Skip to content

Instantly share code, notes, and snippets.

@glombard
Last active March 7, 2018 04:57
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save glombard/2fdb883de1d50fb51d1a to your computer and use it in GitHub Desktop.
Save glombard/2fdb883de1d50fb51d1a to your computer and use it in GitHub Desktop.
Generate a pom.xml file to download the jars needed to use the Robolectric Test Runner in offline mode
#!/usr/bin/env python
"""
This is a quick and dirty script to parse SdkConfig.java from the
Robolectric sources on GitHub to determine the list of dependencies we need
to use the Robolectric Test Runner in offline mode. It then generates a Maven
pom.xml file that can be used to download all the necessary depedenency jars
from maven central.
Author: @codeblast
"""
from __future__ import print_function
import re
from jinja2 import Template
import requests
__author__ = 'glombard'
SDK_CONFIG_URL = (
'https://raw.githubusercontent.com/robolectric/robolectric/master'
'/robolectric/src/main/java/org/robolectric/internal/SdkConfig.java')
LATEST_VERSION_URL = 'https://api.bintray.com/packages/bintray/jcenter/org' \
'.robolectric%3Arobolectric'
# Determine the latest version from the JCenter API (e.g. '3.0-rc2'):
robolectric_version = requests.get(LATEST_VERSION_URL).json()['latest_version']
# Determine the latest supported SDK version (e.g. '5.0.0_r2-robolectric-1'):
sdk_config_src = requests.get(SDK_CONFIG_URL).text
matches = re.findall('SdkVersion\("(.+)",\s*"(.+)"\)', sdk_config_src)
latest_version = sorted(matches, key=lambda tup: tup[0], reverse=True)[0]
sdk_version = '{}-robolectric-{}'.format(latest_version[0],
latest_version[1])
# Extract the list of dependencies form SdkConfig.java:
matches = re.findall('^\s*createDependency\("(.+?)",\s*"(.+?)",\s*(.+?),',
sdk_config_src, re.MULTILINE)
dependencies = list()
for tup in matches:
if tup[2] == 'artifactVersionString':
ver = sdk_version
elif tup[2] == 'ROBOLECTRIC_VERSION':
ver = robolectric_version
else:
ver = tup[2].replace('"', '')
classifier = ''
if tup[1] == 'shadows-core':
classifier = '21' # hack - force to download shadows-core for API 21.
dependencies.append(
{'groupId': tup[0], 'artifactId': tup[1], 'version': ver, 'classifier': classifier})
pom_template_text = """
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<!--
Robolectric version: {{ robolectric_version }}
SDK version: {{ sdk_version }}
Save this output to pom.xml and download jars with:
mvn dependency:copy-dependencies
-DremoteRepositories=http://repo1.maven.org/maven2/
-DoutputDirectory=/tmp/robolectric-files
-->
<modelVersion>4.0.0</modelVersion>
<groupId>org.robolectric</groupId>
<artifactId>robolectric-files</artifactId>
<version>{{ robolectric_version }}</version>
<packaging>pom</packaging>
<description>Robolectric Test Runner files.</description>
<url>http://robolectric.org/</url>
<dependencies>
{% for d in dependencies -%}
<dependency>
<groupId>{{ d.groupId }} </groupId>
<artifactId>{{ d.artifactId }}</artifactId>
<version>{{ d.version }}</version>
<classifier>{{ d.classifier }}</classifier>
</dependency>
{%- endfor %}
</dependencies>
</project>
"""
context = {
'robolectric_version': robolectric_version,
'sdk_version': sdk_version,
'dependencies': dependencies
}
template = Template(pom_template_text)
print(template.render(context))
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<!--
Robolectric version: 3.0-rc2
SDK version: 5.0.0_r2-robolectric-1
Save this output to pom.xml and download jars with:
mvn dependency:copy-dependencies
-DremoteRepositories=http://repo1.maven.org/maven2/
-DoutputDirectory=/tmp/robolectric-files
-->
<modelVersion>4.0.0</modelVersion>
<groupId>org.robolectric</groupId>
<artifactId>robolectric-files</artifactId>
<version>3.0-rc2</version>
<packaging>pom</packaging>
<description>Robolectric Test Runner files.</description>
<url>http://robolectric.org/</url>
<dependencies>
<dependency>
<groupId>org.robolectric </groupId>
<artifactId>android-all</artifactId>
<version>5.0.0_r2-robolectric-1</version>
<classifier></classifier>
</dependency><dependency>
<groupId>org.robolectric </groupId>
<artifactId>shadows-core</artifactId>
<version>3.0-rc2</version>
<classifier>21</classifier>
</dependency><dependency>
<groupId>org.json </groupId>
<artifactId>json</artifactId>
<version>20080701</version>
<classifier></classifier>
</dependency><dependency>
<groupId>org.ccil.cowan.tagsoup </groupId>
<artifactId>tagsoup</artifactId>
<version>1.2</version>
<classifier></classifier>
</dependency>
</dependencies>
</project>
@benoberkfell
Copy link

Hey, just a heads-up, I found this on your blog - thanks for this!

It looks like in a more recent Robolectric change they've changed the way the SDKs are specified - I forked and fixed the regex to make this work for me.

https://gist.github.com/benoberkfell/8b34b14d26f0075848d0

@glombard
Copy link
Author

Oh cool, thanks @benoberkfell!

@markcerqueira
Copy link

@benoberkfell Mind sharing your updated gist? The one you linked 404s. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment