From a5b86596329724bdd8ba5c5b0d1ff7e0b6414891 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Sat, 3 Aug 2013 17:07:55 +0200 Subject: [PATCH 01/20] New gradle=[flavour] field --- fdroidserver/build.py | 3 +++ fdroidserver/common.py | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index e51716b2..94835efc 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -415,6 +415,9 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d if 'mvnflags' in thisbuild: mvncmd += thisbuild['mvnflags'] p = subprocess.Popen(mvncmd, cwd=root_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + elif 'gradle' in thisbuild: + flavour = thisbuild['gradle'] + p = subprocess.Popen(gradle, 'assemble'+flavour+'Release', cwd=root_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) else: if install: antcommands = ['debug','install'] diff --git a/fdroidserver/common.py b/fdroidserver/common.py index a363ffb5..8baa502f 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1133,7 +1133,7 @@ def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, sdk_path, # Generate (or update) the ant build file, build.xml... updatemode = build.get('update', '.') if (updatemode != 'no' and - 'maven' not in build): + 'maven' not in build and 'gradle' not in build): parms = [os.path.join(sdk_path, 'tools', 'android'), 'update', 'project', '-p', '.'] parms.append('--subprojects') From 946e42fe71579f25549b4135566bb10ef3ced601 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Sat, 3 Aug 2013 17:19:23 +0200 Subject: [PATCH 02/20] Try to fix subprocess crash --- fdroidserver/build.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 94835efc..42160513 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -417,7 +417,8 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d p = subprocess.Popen(mvncmd, cwd=root_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) elif 'gradle' in thisbuild: flavour = thisbuild['gradle'] - p = subprocess.Popen(gradle, 'assemble'+flavour+'Release', cwd=root_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + arg = 'assemble'+flavour+'Release' + p = subprocess.Popen(gradle, arg, cwd=root_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) else: if install: antcommands = ['debug','install'] From dbe0d1ec2645ba4e8dda444af81e8ef420521486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Sat, 3 Aug 2013 17:32:39 +0200 Subject: [PATCH 03/20] Fix gradle command --- fdroidserver/build.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 42160513..0161c03c 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -417,8 +417,7 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d p = subprocess.Popen(mvncmd, cwd=root_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) elif 'gradle' in thisbuild: flavour = thisbuild['gradle'] - arg = 'assemble'+flavour+'Release' - p = subprocess.Popen(gradle, arg, cwd=root_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + p = subprocess.Popen([gradle, 'assemble'+flavour+'Release'], cwd=root_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) else: if install: antcommands = ['debug','install'] From e0174654f847dd32be8e2f386b3246933101b0de Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Sat, 3 Aug 2013 17:45:11 +0200 Subject: [PATCH 04/20] Try and feed the right gradle apk --- fdroidserver/build.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 0161c03c..7090623b 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -467,6 +467,8 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d raise BuildException('Failed to find output') src = m.group(1) src = os.path.join(bindir, src) + '.apk' + elif 'gradle' in thisbuild: + src = os.path.join('build', 'apk', '-'.join(app['Auto Name'], flavour, 'release', 'unsigned')+'.apk') else: src = re.match(r".*^.*Creating (.+) for release.*$.*", output, re.S|re.M).group(1) From f1c1971c88cd75bd6bec0461e4bd5770a6f8bd09 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Sat, 3 Aug 2013 17:46:55 +0200 Subject: [PATCH 05/20] join needs a list --- fdroidserver/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 7090623b..444ba8c8 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -468,7 +468,7 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d src = m.group(1) src = os.path.join(bindir, src) + '.apk' elif 'gradle' in thisbuild: - src = os.path.join('build', 'apk', '-'.join(app['Auto Name'], flavour, 'release', 'unsigned')+'.apk') + src = os.path.join('build', 'apk', '-'.join([app['Auto Name'], flavour, 'release', 'unsigned')+'.apk']) else: src = re.match(r".*^.*Creating (.+) for release.*$.*", output, re.S|re.M).group(1) From 8866724f05b176ce32bfa0cfa82f09e26efde95d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Sat, 3 Aug 2013 18:08:49 +0200 Subject: [PATCH 06/20] Use new manifest path function in checkupdates --- fdroidserver/checkupdates.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index d38c784d..2bf68539 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -71,7 +71,7 @@ def check_tags(app, sdk_path): vcs.gotorevision(tag) # Only process tags where the manifest exists... - if os.path.exists(os.path.join(build_dir, 'AndroidManifest.xml')): + if os.path.exists(common.manifest_path(build_dir)): version, vercode, package = common.parse_androidmanifest(build_dir) if package and package == app['id'] and version and vercode: if int(vercode) > int(hcode): From 8c8a20bcb1ed9745cca90deef860c532e500a1ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Sat, 3 Aug 2013 18:37:29 +0200 Subject: [PATCH 07/20] Merge master into gradle --- fdroidserver/checkupdates.py | 5 ++++- fdroidserver/common.py | 1 + 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 2bf68539..20f51b80 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -71,8 +71,11 @@ def check_tags(app, sdk_path): vcs.gotorevision(tag) # Only process tags where the manifest exists... - if os.path.exists(common.manifest_path(build_dir)): + path = common.manifest_path(build_dir) + print "Trying manifest at %s" % path + if os.path.exists(path): version, vercode, package = common.parse_androidmanifest(build_dir) + print "Manifest exists. Found version %s" % version if package and package == app['id'] and version and vercode: if int(vercode) > int(hcode): hcode = str(int(vercode)) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 8baa502f..30162da3 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1070,6 +1070,7 @@ def getsrclib(spec, srclib_dir, sdk_path, ndk_path="", mvn3="", basepath=False, + name, out, err) if srclib["Update Project"] == "Yes": + print "Updating srclib %s at path %s" % (name, libdir) if subprocess.call([os.path.join(sdk_path, 'tools', 'android'), 'update', 'project', '-p', libdir]) != 0: raise BuildException( 'Error updating ' + name + ' project') From 89a9447a8c8dae1f400fa8de8420b08762b6b664 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Sat, 3 Aug 2013 18:53:01 +0200 Subject: [PATCH 08/20] Use src/ rather than source/ --- fdroidserver/common.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 30162da3..c14778da 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -876,7 +876,7 @@ def retrieve_string(app_dir, string_id): # Find the AM.xml - try the new gradle method first. def manifest_path(app_dir): - gradlepath = os.path.join(app_dir, 'source', 'main', 'AndroidManifest.xml') + gradlepath = os.path.join(app_dir, 'src', 'main', 'AndroidManifest.xml') if os.path.exists(gradlepath): return gradlepath rootpath = os.path.join(app_dir, 'AndroidManifest.xml') From 7d1f2b68b90e09457d6e4102e9b74abb791a8f18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Mon, 5 Aug 2013 20:01:02 +0200 Subject: [PATCH 09/20] Proper apk path for gradle --- fdroidserver/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 444ba8c8..e0caa615 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -468,7 +468,7 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d src = m.group(1) src = os.path.join(bindir, src) + '.apk' elif 'gradle' in thisbuild: - src = os.path.join('build', 'apk', '-'.join([app['Auto Name'], flavour, 'release', 'unsigned')+'.apk']) + src = os.path.join(build_dir, 'build', 'apk', '-'.join([app['id'], flavour, 'release', 'unsigned'])+'.apk') else: src = re.match(r".*^.*Creating (.+) for release.*$.*", output, re.S|re.M).group(1) From d86a68b85838d6658abebb9d7eecc46900ab15a3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Thu, 8 Aug 2013 12:55:48 +0200 Subject: [PATCH 10/20] Fix gradle checkupdates with tags and RM. new settings. --- config.sample.py | 9 +++++++++ fdroidserver/checkupdates.py | 31 +++++++++++++++++++++---------- fdroidserver/common.py | 34 ++++++++++++++++++++++++---------- 3 files changed, 54 insertions(+), 20 deletions(-) diff --git a/config.sample.py b/config.sample.py index 7d666d1e..02d04807 100644 --- a/config.sample.py +++ b/config.sample.py @@ -5,6 +5,9 @@ sdk_path = "/path/to/android-sdk-linux_86" ndk_path = "/path/to/android-ndk-r8e" +# Build tools version to be used +build_tools = "18.0.1" + # May be necessary for fdroid update; you may still need to make a symlink to # aapt in platform-tools aapt_path = "/path/to/android-sdk-linux_x86/build-tools/17.0.0/aapt" @@ -15,6 +18,12 @@ javacc_path = "/usr/share/java" #Command for running maven 3 (could be mvn, mvn3, or a full path) mvn3 = "mvn3" +# Gradle command +gradle = "gradle" + +# Android gradle plugin version +gradle_plugin = "0.5.+" + repo_url = "https://f-droid.org/repo" repo_name = "F-Droid" repo_icon = "fdroid-icon.png" diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 20f51b80..f74b99c3 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -60,9 +60,12 @@ def check_tags(app, sdk_path): vcs.gotorevision(None) + flavour = None if len(app['builds']) > 0: if 'subdir' in app['builds'][-1]: build_dir = os.path.join(build_dir, app['builds'][-1]['subdir']) + if 'gradle' in app['builds'][-1]: + flavour = app['builds'][-1]['gradle'] hver = None hcode = "0" @@ -71,10 +74,10 @@ def check_tags(app, sdk_path): vcs.gotorevision(tag) # Only process tags where the manifest exists... - path = common.manifest_path(build_dir) - print "Trying manifest at %s" % path - if os.path.exists(path): - version, vercode, package = common.parse_androidmanifest(build_dir) + path = common.manifest_path(build_dir, flavour, gradle, + build_tools, gradle_plugin) + if path is not None and os.path.exists(path): + version, vercode, package = common.parse_androidmanifest(path) print "Manifest exists. Found version %s" % version if package and package == app['id'] and version and vercode: if int(vercode) > int(hcode): @@ -141,11 +144,18 @@ def check_repomanifest(app, sdk_path, branch=None): if len(app['builds']) > 0: if 'subdir' in app['builds'][-1]: build_dir = os.path.join(build_dir, app['builds'][-1]['subdir']) + if 'gradle' in app['builds'][-1]: + flavour = app['builds'][-1]['gradle'] if not os.path.isdir(build_dir): return (None, "Subdir '" + app['builds'][-1]['subdir'] + "'is not a valid directory") - version, vercode, package = common.parse_androidmanifest(build_dir) + path = common.manifest_path(build_dir, flavour, gradle, build_tools, + gradle_plugin) + if path is None: + return (None, "Gradle flavour not found") + + version, vercode, package = common.parse_androidmanifest(path) if not package: return (None, "Couldn't find package ID") if package != app['id']: @@ -213,6 +223,7 @@ def check_market(app): def main(): #Read configuration... + globals()['gradle'] = "gradle" execfile('config.py', globals()) # Parse command line... @@ -300,11 +311,11 @@ def main(): if 'subdir' in app['builds'][-1]: app_dir = os.path.join(app_dir, app['builds'][-1]['subdir']) - new_name = common.fetch_real_name(app_dir) - if new_name != app['Auto Name']: - app['Auto Name'] = new_name - if not writeit: - writeit = True + #new_name = common.fetch_real_name(app_dir) + #if new_name != app['Auto Name']: + #app['Auto Name'] = new_name + #if not writeit: + #writeit = True except Exception: msg = "Auto Name failed for %s due to exception: %s" % (app['id'], traceback.format_exc()) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index c14778da..3ff34614 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -22,6 +22,7 @@ import subprocess import time import operator import cgi +import fileinput def getvcs(vcstype, remote, local, sdk_path): if vcstype == 'git': @@ -875,12 +876,25 @@ def retrieve_string(app_dir, string_id): return '' # Find the AM.xml - try the new gradle method first. -def manifest_path(app_dir): - gradlepath = os.path.join(app_dir, 'src', 'main', 'AndroidManifest.xml') - if os.path.exists(gradlepath): - return gradlepath - rootpath = os.path.join(app_dir, 'AndroidManifest.xml') - return rootpath +def manifest_path(app_dir, flavour, gradle, build_tools, gradle_plugin): + + if flavour is None: + return os.path.join(app_dir, 'AndroidManifest.xml') + + if not os.path.exists(os.path.join(app_dir, 'src', flavour)): + return None + + for line in fileinput.input(os.path.join(app_dir, 'build.gradle'), inplace=True): + if 'buildToolsVersion' in line: + print 'buildToolsVersion "%s"' % build_tools, + elif 'com.android.tools.build:gradle:' in line: + print "classpath 'com.android.tools.build:gradle:%s'" % gradle_plugin, + else: + print line, + + subprocess.Popen([gradle, 'process'+flavour+'ReleaseManifest'], cwd=app_dir).communicate() + + return os.path.join(app_dir, 'build', 'manifests', flavour, 'release', 'AndroidManifest.xml') # Retrieve the package name @@ -907,7 +921,7 @@ def fetch_real_name(app_dir): # Extract some information from the AndroidManifest.xml at the given path. # Returns (version, vercode, package), any or all of which might be None. # All values returned are strings. -def parse_androidmanifest(app_dir): +def parse_androidmanifest(manifest): vcsearch = re.compile(r'.*android:versionCode="([0-9]+?)".*').search vnsearch = re.compile(r'.*android:versionName="([^"]+?)".*').search @@ -916,7 +930,7 @@ def parse_androidmanifest(app_dir): version = None vercode = None package = None - for line in file(manifest_path(app_dir)): + for line in file(manifest): if not package: matches = psearch(line) if matches: @@ -929,8 +943,8 @@ def parse_androidmanifest(app_dir): matches = vcsearch(line) if matches: vercode = matches.group(1) - if version.startswith('@string/'): - version = retrieve_string(app_dir, version[8:]) + #if version.startswith('@string/'): + #version = retrieve_string(app_dir, version[8:]) return (version, vercode, package) class BuildException(Exception): From ece2ece0719e243dd5b7084b51987efabf61c87b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Thu, 8 Aug 2013 13:00:02 +0200 Subject: [PATCH 11/20] Deprecate aapt_path in favour of sdk_path + build_tools --- config.sample.py | 4 ---- fdroidserver/build.py | 8 +------- fdroidserver/common.py | 9 ++------- fdroidserver/update.py | 5 +---- 4 files changed, 4 insertions(+), 22 deletions(-) diff --git a/config.sample.py b/config.sample.py index 02d04807..d1417362 100644 --- a/config.sample.py +++ b/config.sample.py @@ -8,10 +8,6 @@ ndk_path = "/path/to/android-ndk-r8e" # Build tools version to be used build_tools = "18.0.1" -# May be necessary for fdroid update; you may still need to make a symlink to -# aapt in platform-tools -aapt_path = "/path/to/android-sdk-linux_x86/build-tools/17.0.0/aapt" - #You probably don't need to change this... javacc_path = "/usr/share/java" diff --git a/fdroidserver/build.py b/fdroidserver/build.py index e0caa615..5f0056ec 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -483,14 +483,8 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d print "Checking " + src if not os.path.exists(src): raise BuildException("Unsigned apk is not at expected location of " + src) - if ('aapt_path' not in globals()): - # (re-)read configuration - execfile('config.py', globals()) - if not os.path.exists(aapt_path): - print "Missing aapt - check aapt_path in your config" - sys.exit(1) - p = subprocess.Popen([aapt_path, + p = subprocess.Popen([os.path.join(sdk_path, 'build-tools', build_tools, 'aapt'), 'dump', 'badging', src], stdout=subprocess.PIPE) output = p.communicate()[0] diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 3ff34614..6b06871c 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -1589,14 +1589,9 @@ def isApkDebuggable(apkfile): :param apkfile: full path to the apk to check""" - if ('aapt_path' not in globals()): - # (re-)read configuration - execfile('config.py', globals()) - if not os.path.exists(aapt_path): - print "Missing aapt - check aapt_path in your config" - sys.exit(1) + execfile('config.py', globals()) - p = subprocess.Popen([aapt_path, + p = subprocess.Popen([os.path.join(sdk_path, 'build-tools', build_tools, 'aapt'), 'dump', 'xmltree', apkfile, 'AndroidManifest.xml'], stdout=subprocess.PIPE) output = p.communicate()[0] diff --git a/fdroidserver/update.py b/fdroidserver/update.py index c705cb4b..d40773d5 100644 --- a/fdroidserver/update.py +++ b/fdroidserver/update.py @@ -267,10 +267,7 @@ def scan_apks(apps, apkcache, repodir, knownapks): thisinfo['size'] = os.path.getsize(apkfile) thisinfo['permissions'] = [] thisinfo['features'] = [] - if not os.path.exists(aapt_path): - print "Missing aapt - check aapt_path in your config" - sys.exit(1) - p = subprocess.Popen([aapt_path, + p = subprocess.Popen([os.path.join(sdk_path, 'build-tools', build_tools, 'aapt'), 'dump', 'badging', apkfile], stdout=subprocess.PIPE) output = p.communicate()[0] From 1d046790bb5d612914ddd1cf1df4a08c3590d009 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Thu, 8 Aug 2013 13:02:11 +0200 Subject: [PATCH 12/20] Merge changes from the master branch --- .../cookbooks/android-sdk/recipes/default.rb | 33 ++++++++++--------- 1 file changed, 18 insertions(+), 15 deletions(-) diff --git a/buildserver/cookbooks/android-sdk/recipes/default.rb b/buildserver/cookbooks/android-sdk/recipes/default.rb index 2b415f21..34b418ea 100644 --- a/buildserver/cookbooks/android-sdk/recipes/default.rb +++ b/buildserver/cookbooks/android-sdk/recipes/default.rb @@ -23,27 +23,30 @@ execute "add-android-sdk-path" do not_if "grep #{sdk_loc} /home/#{user}/.bashrc" end -script "add_build_tools" do - interpreter "bash" - user user - cwd "/tmp" - code " - if [ -f /vagrant/cache/build-tools/17.0.0.tar.gz ] ; then - echo Installing from cache - tar -C #{sdk_loc}/build-tools -z -x -f /vagrant/cache/build-tools/17.0.0.tar.gz - else - #{sdk_loc}/tools/android update sdk --no-ui -a -t build-tools-17.0.0 < Date: Fri, 9 Aug 2013 17:15:27 +0200 Subject: [PATCH 13/20] Don't run gradle during checkudpates. Use whatever can be found. --- fdroidserver/checkupdates.py | 10 ++++------ fdroidserver/common.py | 32 ++++++++++++++++---------------- 2 files changed, 20 insertions(+), 22 deletions(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index f74b99c3..e1cfaa71 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -74,9 +74,8 @@ def check_tags(app, sdk_path): vcs.gotorevision(tag) # Only process tags where the manifest exists... - path = common.manifest_path(build_dir, flavour, gradle, - build_tools, gradle_plugin) - if path is not None and os.path.exists(path): + path = common.manifest_path(build_dir, flavour) + if path is not None: version, vercode, package = common.parse_androidmanifest(path) print "Manifest exists. Found version %s" % version if package and package == app['id'] and version and vercode: @@ -150,10 +149,9 @@ def check_repomanifest(app, sdk_path, branch=None): if not os.path.isdir(build_dir): return (None, "Subdir '" + app['builds'][-1]['subdir'] + "'is not a valid directory") - path = common.manifest_path(build_dir, flavour, gradle, build_tools, - gradle_plugin) + path = common.manifest_path(build_dir, flavour) if path is None: - return (None, "Gradle flavour not found") + return (None, "No manifest could be found") version, vercode, package = common.parse_androidmanifest(path) if not package: diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 6b06871c..ebaf6d77 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -875,26 +875,26 @@ def retrieve_string(app_dir, string_id): return s.replace("\\'","'") return '' -# Find the AM.xml - try the new gradle method first. -def manifest_path(app_dir, flavour, gradle, build_tools, gradle_plugin): +# Find the AM.xml - try to use new gradle manifest paths +# TODO: Gradle can use multiple manifests. Return a list of the existing ones +# and later iterate through them to find the highest vercode. +def manifest_path(app_dir, flavour): - if flavour is None: - return os.path.join(app_dir, 'AndroidManifest.xml') + root_manifest = os.path.join(app_dir, 'AndroidManifest.xml') + if flavour is not None: + flavour_manifest = os.path.join(app_dir, 'src', flavour, 'AndroidManifest.xml') + if os.path.isfile(flavour_manifest): + return flavour_manifest - if not os.path.exists(os.path.join(app_dir, 'src', flavour)): - return None + main_manifest = os.path.join(app_dir, 'src', 'main', 'AndroidManifest.xml') + print main_manifest + if os.path.isfile(main_manifest): + return main_manifest - for line in fileinput.input(os.path.join(app_dir, 'build.gradle'), inplace=True): - if 'buildToolsVersion' in line: - print 'buildToolsVersion "%s"' % build_tools, - elif 'com.android.tools.build:gradle:' in line: - print "classpath 'com.android.tools.build:gradle:%s'" % gradle_plugin, - else: - print line, + if os.path.isfile(root_manifest): + return root_manifest - subprocess.Popen([gradle, 'process'+flavour+'ReleaseManifest'], cwd=app_dir).communicate() - - return os.path.join(app_dir, 'build', 'manifests', flavour, 'release', 'AndroidManifest.xml') + return None # Retrieve the package name From 578e030ee61a120b80830f83a537b62bf0f4ccdb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Tue, 13 Aug 2013 12:02:48 +0200 Subject: [PATCH 14/20] Try and adapt checkupdates to gradle better --- fdroidserver/checkupdates.py | 21 ++++---- fdroidserver/common.py | 94 +++++++++++++++++++++--------------- 2 files changed, 65 insertions(+), 50 deletions(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index e1cfaa71..93998666 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -74,14 +74,13 @@ def check_tags(app, sdk_path): vcs.gotorevision(tag) # Only process tags where the manifest exists... - path = common.manifest_path(build_dir, flavour) - if path is not None: - version, vercode, package = common.parse_androidmanifest(path) - print "Manifest exists. Found version %s" % version - if package and package == app['id'] and version and vercode: - if int(vercode) > int(hcode): - hcode = str(int(vercode)) - hver = version + paths = common.manifest_paths(build_dir, flavour) + version, vercode, package = common.parse_androidmanifests(paths) + print "Manifest exists. Found version %s" % version + if package and package == app['id'] and version and vercode: + if int(vercode) > int(hcode): + hcode = str(int(vercode)) + hver = version if hver: return (hver, hcode) @@ -149,11 +148,9 @@ def check_repomanifest(app, sdk_path, branch=None): if not os.path.isdir(build_dir): return (None, "Subdir '" + app['builds'][-1]['subdir'] + "'is not a valid directory") - path = common.manifest_path(build_dir, flavour) - if path is None: - return (None, "No manifest could be found") + paths = common.manifest_paths(build_dir, flavour) - version, vercode, package = common.parse_androidmanifest(path) + version, vercode, package = common.parse_androidmanifest(paths) if not package: return (None, "Couldn't find package ID") if package != app['id']: diff --git a/fdroidserver/common.py b/fdroidserver/common.py index ebaf6d77..ac1218b5 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -875,26 +875,19 @@ def retrieve_string(app_dir, string_id): return s.replace("\\'","'") return '' -# Find the AM.xml - try to use new gradle manifest paths -# TODO: Gradle can use multiple manifests. Return a list of the existing ones -# and later iterate through them to find the highest vercode. -def manifest_path(app_dir, flavour): +# Return list of existing AM.xml files that will be used to find the highest +# vercode +def manifest_paths(app_dir, flavour): + + possible_manifests = [ os.path.join(app_dir, 'AndroidManifest.xml'), + os.path.join(app_dir, 'src', 'main', 'AndroidManifest.xml'), + os.path.join(app_dir, 'build.gradle') ] - root_manifest = os.path.join(app_dir, 'AndroidManifest.xml') if flavour is not None: - flavour_manifest = os.path.join(app_dir, 'src', flavour, 'AndroidManifest.xml') - if os.path.isfile(flavour_manifest): - return flavour_manifest + possible_manifests.append( + os.path.join(app_dir, 'src', flavour, 'AndroidManifest.xml')) - main_manifest = os.path.join(app_dir, 'src', 'main', 'AndroidManifest.xml') - print main_manifest - if os.path.isfile(main_manifest): - return main_manifest - - if os.path.isfile(root_manifest): - return root_manifest - - return None + return [path for path in possible_manifests if os.path.isfile(path)] # Retrieve the package name @@ -921,31 +914,56 @@ def fetch_real_name(app_dir): # Extract some information from the AndroidManifest.xml at the given path. # Returns (version, vercode, package), any or all of which might be None. # All values returned are strings. -def parse_androidmanifest(manifest): +def parse_androidmanifests(paths): vcsearch = re.compile(r'.*android:versionCode="([0-9]+?)".*').search vnsearch = re.compile(r'.*android:versionName="([^"]+?)".*').search psearch = re.compile(r'.*package="([^"]+)".*').search - vnsearch_xml = re.compile(r'.*"(app_|)version">([^<]+?)<.*').search - version = None - vercode = None - package = None - for line in file(manifest): - if not package: - matches = psearch(line) - if matches: - package = matches.group(1) - if not version: - matches = vnsearch(line) - if matches: - version = matches.group(1) - if not vercode: - matches = vcsearch(line) - if matches: - vercode = matches.group(1) - #if version.startswith('@string/'): - #version = retrieve_string(app_dir, version[8:]) - return (version, vercode, package) + + vcsearch_g = re.compile(r'.*versionCode[ ]+?([0-9]+?).*').search + vnsearch_g = re.compile(r'.*versionName[ ]+?"([^"]+?)".*').search + psearch_g = re.compile(r'.*packageName[ ]+?"([^"]+)".*').search + + max_version = None + max_vercode = None + max_package = None + + for path in paths: + + gradle = path.endswith("build.gradle") + version = None + vercode = None + package = None + + for line in file(path): + if not package: + if gradle: + matches = psearch_g(line) + else: + matches = psearch(line) + if matches: + package = matches.group(1) + if not version: + if gradle: + matches = vnsearch_g(line) + else: + matches = vnsearch(line) + if matches: + version = matches.group(1) + if not vercode: + if gradle: + matches = vcsearch_g(line) + else: + matches = vcsearch(line) + if matches: + vercode = matches.group(1) + + if max_vercode is None or (vercode is not None and vercode > max_vercode): + max_version = version + max_vercode = vercode + max_package = package + + return (max_version, max_vercode, max_package) class BuildException(Exception): def __init__(self, value, stdout = None, stderr = None): From cf47e151f7bb6b91ceb1536343d6bf07be55d136 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Tue, 13 Aug 2013 14:51:40 +0200 Subject: [PATCH 15/20] Small fixes to checkupdates --- fdroidserver/checkupdates.py | 4 +++- fdroidserver/common.py | 2 +- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index 93998666..ee80bca6 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -139,6 +139,8 @@ def check_repomanifest(app, sdk_path, branch=None): elif vcs.repotype() == 'bzr': vcs.gotorevision(None) + flavour = None + if len(app['builds']) > 0: if 'subdir' in app['builds'][-1]: build_dir = os.path.join(build_dir, app['builds'][-1]['subdir']) @@ -150,7 +152,7 @@ def check_repomanifest(app, sdk_path, branch=None): paths = common.manifest_paths(build_dir, flavour) - version, vercode, package = common.parse_androidmanifest(paths) + version, vercode, package = common.parse_androidmanifests(paths) if not package: return (None, "Couldn't find package ID") if package != app['id']: diff --git a/fdroidserver/common.py b/fdroidserver/common.py index ac1218b5..528a9dbf 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -930,7 +930,7 @@ def parse_androidmanifests(paths): for path in paths: - gradle = path.endswith("build.gradle") + gradle = path.endswith("gradle") version = None vercode = None package = None From bc27ebcb82a236f3df2ad925b5d4b5ec2fe9a1d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Tue, 13 Aug 2013 15:20:11 +0200 Subject: [PATCH 16/20] Implement --install for gradle, add compilesdk= --- docs/fdroid.texi | 8 ++++++++ fdroidserver/build.py | 22 +++++++++++++++++++++- 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/docs/fdroid.texi b/docs/fdroid.texi index 1f0de51a..ff4861c8 100644 --- a/docs/fdroid.texi +++ b/docs/fdroid.texi @@ -772,6 +772,14 @@ already exist, but not a good idea if it's heavily customised. If you get an error about invalid target, first try @code{init=rm -rf bin/}; otherwise this parameter should do the trick. +Please note that gradle builds should be using compilesdk=. + +@item compilesdk= +Practically accomplishes the same that target= does when used in ant and maven +projects. compilesdk= is used rather than target= so as to not cause any more +confusion. It only takes effect on gradle builds in the build.gradle file, +thus using it in any other case is not wise. + @item update=xxx By default, 'android update project' is used to generate or update the build.xml file. Specifying update=no bypasses that. diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 5f0056ec..3d0a0836 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -417,7 +417,27 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d p = subprocess.Popen(mvncmd, cwd=root_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) elif 'gradle' in thisbuild: flavour = thisbuild['gradle'] - p = subprocess.Popen([gradle, 'assemble'+flavour+'Release'], cwd=root_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) + + if 'compilesdk' in thisbuild: + level = thisbuild["compilesdk"].split('-')[1] + subprocess.call(['sed', '-i', + 's@compileSdkVersion[ ]*[0-9]*@compileSdkVersion '+level+'@g', + 'build.gradle'], cwd=root_dir) + + subprocess.call(['sed', '-i', + 's@buildToolsVersion[ ]*["\'][0-9\.]*["\']@buildToolsVersion "'+build_tools+'"@g', + 'build.gradle'], cwd=root_dir) + + subprocess.call(['sed', '-i', + 's@com.android.tools.build:gradle:[0-9\.\+]*@com.android.tools.build:gradle:'+target+'@g', + 'build.gradle'], cwd=root_dir) + + if install: + commands = [gradle, 'assemble'+flavour+'Debug', 'install'+flavour+'Debug'] + else: + commands = [gradle, 'assemble'+flavour+'Release'] + + p = subprocess.Popen(commands, cwd=root_dir, stdout=subprocess.PIPE, stderr=subprocess.PIPE) else: if install: antcommands = ['debug','install'] From 1fcb56b946e912af1329aac046b00f6364791fd4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Tue, 13 Aug 2013 15:25:47 +0200 Subject: [PATCH 17/20] Use last found package name if none found --- fdroidserver/common.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 528a9dbf..6664ce69 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -933,7 +933,8 @@ def parse_androidmanifests(paths): gradle = path.endswith("gradle") version = None vercode = None - package = None + # Remember package name, may be defined separately from version+vercode + package = max_package for line in file(path): if not package: @@ -958,6 +959,10 @@ def parse_androidmanifests(paths): if matches: vercode = matches.group(1) + # Better some package name than nothing + if max_package is None: + max_package = package + if max_vercode is None or (vercode is not None and vercode > max_vercode): max_version = version max_vercode = vercode From 0ad09f6481b481c062f38e2c0e36a16e49b12a32 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Tue, 13 Aug 2013 15:58:43 +0200 Subject: [PATCH 18/20] Improve checkupdates further, Auto Name works with gradle --- fdroidserver/checkupdates.py | 13 ++++++---- fdroidserver/common.py | 50 +++++++++++++++++------------------- 2 files changed, 32 insertions(+), 31 deletions(-) diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index ee80bca6..d030f4a6 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -304,15 +304,18 @@ def main(): vcs = common.getvcs(app["Repo Type"], app["Repo"], app_dir, sdk_path) vcs.gotorevision(None) + flavour = None if len(app['builds']) > 0: if 'subdir' in app['builds'][-1]: app_dir = os.path.join(app_dir, app['builds'][-1]['subdir']) + if 'gradle' in app['builds'][-1]: + flavour = app['builds'][-1]['gradle'] + + new_name = common.fetch_real_name(app_dir, flavour) + if new_name != app['Auto Name']: + app['Auto Name'] = new_name + writeit = True - #new_name = common.fetch_real_name(app_dir) - #if new_name != app['Auto Name']: - #app['Auto Name'] = new_name - #if not writeit: - #writeit = True except Exception: msg = "Auto Name failed for %s due to exception: %s" % (app['id'], traceback.format_exc()) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 6664ce69..4a188c08 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -862,21 +862,19 @@ def description_html(lines,linkres): ps.end() return ps.text_html -def retrieve_string(app_dir, string_id): - string_search = re.compile(r'.*"'+string_id+'".*>([^<]+?)<.*').search - for xmlfile in glob.glob(os.path.join( - app_dir, 'res', 'values', '*.xml')): +def retrieve_string(xml_dir, string): + print string + if not string.startswith('@string/'): + return string.replace("\\'","'") + string_search = re.compile(r'.*"'+string[8:]+'".*>([^<]+?)<.*').search + for xmlfile in glob.glob(os.path.join(xml_dir, '*.xml')): for line in file(xmlfile): matches = string_search(line) if matches: - s = matches.group(1) - if s.startswith('@string/'): - return retrieve_string(app_dir, s[8:]); - return s.replace("\\'","'") + return retrieve_string(xml_dir, matches.group(1)) return '' -# Return list of existing AM.xml files that will be used to find the highest -# vercode +# Return list of existing files that will be used to find the highest vercode def manifest_paths(app_dir, flavour): possible_manifests = [ os.path.join(app_dir, 'AndroidManifest.xml'), @@ -886,30 +884,30 @@ def manifest_paths(app_dir, flavour): if flavour is not None: possible_manifests.append( os.path.join(app_dir, 'src', flavour, 'AndroidManifest.xml')) - + return [path for path in possible_manifests if os.path.isfile(path)] - # Retrieve the package name -def fetch_real_name(app_dir): +def fetch_real_name(app_dir, flavour): app_search = re.compile(r'.* Date: Tue, 13 Aug 2013 16:00:51 +0200 Subject: [PATCH 19/20] Forgot to remove debugging prints --- fdroidserver/common.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 4a188c08..36dc77ee 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -863,7 +863,6 @@ def description_html(lines,linkres): return ps.text_html def retrieve_string(xml_dir, string): - print string if not string.startswith('@string/'): return string.replace("\\'","'") string_search = re.compile(r'.*"'+string[8:]+'".*>([^<]+?)<.*').search @@ -894,7 +893,6 @@ def fetch_real_name(app_dir, flavour): app_found = False name = None for f in manifest_paths(app_dir, flavour): - print f if not f.endswith(".xml"): continue xml_dir = os.path.join(f[:-19], 'res', 'values') From 4cb7e340d15bb83d9dc7a557c0dd49a8d6219cea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Daniel=20Mart=C3=AD?= Date: Tue, 13 Aug 2013 20:04:44 +0200 Subject: [PATCH 20/20] Small fix --- fdroidserver/build.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 3d0a0836..86ca309e 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -429,7 +429,7 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d 'build.gradle'], cwd=root_dir) subprocess.call(['sed', '-i', - 's@com.android.tools.build:gradle:[0-9\.\+]*@com.android.tools.build:gradle:'+target+'@g', + 's@com.android.tools.build:gradle:[0-9\.\+]*@com.android.tools.build:gradle:'+gradle_plugin+'@g', 'build.gradle'], cwd=root_dir) if install: