import argparse
import os
import tarfile
import xml.etree.ElementTree as etree
FLAT_DIRS_REPO_TEMPLATE = 'flatDir {{ dirs {dirs} }}\n'
MAVEN_REPO_TEMPLATE = 'maven {{ url "{repo}" }}\n'
KEYSTORE_TEMLATE = 'signingConfigs {{ debug {{ storeFile file("{keystore}") }} }}\n'
TEST_APK_TEMPLATE = """\
ext.jniLibsDirs = [
{jni_libs_dirs}
]
ext.resDirs = [
{res_dirs}
]
ext.javaDirs = [
{java_dirs}
]
ext.bundles = [
{bundles}
]
buildscript {{
// repositories {{
// jcenter()
// }}
repositories {{
{maven_repos}
}}
dependencies {{
classpath 'com.android.tools.build:gradle:3.5.3'
}}
}}
apply plugin: 'com.android.application'
repositories {{
// maven {{
// url "http://maven.google.com/"
// }}
// maven {{
// url "http://artifactory.yandex.net/artifactory/public/"
// }}
// flatDir {{
// dirs System.env.PKG_ROOT + '/bundle'
// }}
{flat_dirs_repo}
{maven_repos}
}}
dependencies {{
for (bundle in bundles) {{
compile("$bundle")
}}
}}
android {{
{keystore}
compileSdkVersion 33
buildToolsVersion "33.0.0"
compileOptions {{
sourceCompatibility 1.8
targetCompatibility 1.8
}}
defaultConfig {{
minSdkVersion 26
targetSdkVersion 33
applicationId "{app_id}"
}}
sourceSets {{
main {{
manifest.srcFile 'Manifest.xml'
jniLibs.srcDirs = jniLibsDirs
res.srcDirs = resDirs
java.srcDirs = javaDirs
}}
}}
applicationVariants.all {{ variant ->
variant.outputs.each {{ output ->
def fileName = "$projectDir/output/{app_id}.apk"
output.outputFileName = new File(output.outputFile.parent, fileName).getName()
}}
}}
dependencies {{
implementation 'com.google.android.gms:play-services-location:21.0.1'
implementation 'com.google.android.gms:play-services-gcm:17.0.0'
implementation 'com.evernote:android-job:1.2.6'
implementation 'androidx.annotation:annotation:1.1.0'
implementation 'androidx.core:core:1.1.0'
}}
}}
"""
def create_native_properties(output_dir, library_name):
native_properties_file = os.path.join(output_dir, 'native_library_name.xml')
resources = etree.Element('resources')
name = etree.SubElement(resources, 'item', dict(name='native_library_name', type='string'))
name.text = library_name
etree.ElementTree(resources).write(native_properties_file, xml_declaration=True, encoding='utf-8')
def gen_build_script(args):
def wrap(items):
return ',\n '.join('"{}"'.format(x) for x in items)
bundles = []
bundles_dirs = set(args.flat_repos)
for bundle in args.bundles:
dir_name, base_name = os.path.split(bundle)
assert len(dir_name) > 0 and len(base_name) > 0
name, ext = os.path.splitext(base_name)
assert len(name) > 0 and ext == '.aar'
bundles_dirs.add(dir_name)
bundles.append('com.yandex:{}@aar'.format(name))
if len(bundles_dirs) > 0:
flat_dirs_repo = FLAT_DIRS_REPO_TEMPLATE.format(dirs=wrap(bundles_dirs))
else:
flat_dirs_repo = ''
maven_repos = ''.join(MAVEN_REPO_TEMPLATE.format(repo=repo) for repo in args.maven_repos)
if args.keystore:
keystore = KEYSTORE_TEMLATE.format(keystore=args.keystore)
else:
keystore = ''
return TEST_APK_TEMPLATE.format(
app_id=args.app_id,
jni_libs_dirs=wrap(args.jni_libs_dirs),
res_dirs=wrap(args.res_dirs),
java_dirs=wrap(args.java_dirs),
maven_repos=maven_repos,
bundles=wrap(bundles),
flat_dirs_repo=flat_dirs_repo,
keystore=keystore,
)
if __name__ == '__main__':
parser = argparse.ArgumentParser()
parser.add_argument('--aars', nargs='*', default=[])
parser.add_argument('--app-id', required=True)
parser.add_argument('--assets-dirs', nargs='*', default=[])
parser.add_argument('--bundles', nargs='*', default=[])
parser.add_argument('--bundle-name', nargs='?', default=None)
parser.add_argument('--java-dirs', nargs='*', default=[])
parser.add_argument('--jni-libs-dirs', nargs='*', default=[])
parser.add_argument('--library-name', required=True)
parser.add_argument('--manifest', required=True)
parser.add_argument('--flat-repos', nargs='*', default=[])
parser.add_argument('--maven-repos', nargs='*', default=[])
parser.add_argument('--output-dir', required=True)
parser.add_argument('--peers', nargs='*', default=[])
parser.add_argument('--keystore', default=None)
parser.add_argument('--res-dirs', nargs='*', default=[])
args = parser.parse_args()
for index, jsrc in enumerate(filter(lambda x: x.endswith('.jsrc'), args.peers)):
jsrc_dir = os.path.join(args.output_dir, 'jsrc_{}'.format(str(index)))
os.makedirs(jsrc_dir)
with tarfile.open(jsrc, 'r') as tar:
tar.extractall(path=jsrc_dir)
args.java_dirs.append(jsrc_dir)
args.build_gradle = os.path.join(args.output_dir, 'build.gradle')
args.settings_gradle = os.path.join(args.output_dir, 'settings.gradle')
args.gradle_properties = os.path.join(args.output_dir, 'gradle.properties')
content = gen_build_script(args)
with open(args.build_gradle, 'w') as f:
f.write(content)
with open(args.gradle_properties, 'w') as f:
f.write(
'''android.enableJetifier=true
android.useAndroidX=true
org.gradle.jvmargs=-Xmx8192m -XX:MaxPermSize=512m'''
)
if args.bundle_name:
with open(args.settings_gradle, 'w') as f:
f.write('rootProject.name = "{}"'.format(args.bundle_name))
values_dir = os.path.join(args.output_dir, 'res', 'values')
os.makedirs(values_dir)
create_native_properties(values_dir, args.library_name)