From: Daniel Martí Date: Wed, 11 Dec 2013 16:29:38 +0000 (+0100) Subject: Start rewrite: Remove --package and --install from 'build' X-Git-Tag: 0.1~109 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;h=a4780c2107f1dc4632f04e0ad8e3bb616f4bf556;p=fdroidserver.git Start rewrite: Remove --package and --install from 'build' --- diff --git a/completion/bash-completion b/completion/bash-completion index 41ba5d74..b05ee2a2 100644 --- a/completion/bash-completion +++ b/completion/bash-completion @@ -23,14 +23,6 @@ # # This way, one can simply do 'fbld com.some.app' or 'fcheckup com.some.app' -__fdroid_cwd() { - if [[ "${PWD##*/}" == metadata ]]; then - subdir=. - else - [ -d metadata ] && subdir=metadata || return 1 - fi -} - __fdroid_init() { COMPREPLY=() cur="${COMP_WORDS[COMP_CWORD]}" @@ -40,29 +32,24 @@ __fdroid_init() { } __package() { - [ -n "$subdir" ] || __fdroid_cwd - files=( ${subdir}/*.txt ) - files=( ${files[@]#${subdir}/} ) + files=( metadata/*.txt ) + files=( ${files[@]#metadata/} ) files=${files[@]%.txt} COMPREPLY=( $( compgen -W "$files" -- $cur ) ) } +__signed_package() { + files=( repo/*.apk ) + files=( ${files[@]#repo/} ) + files=${files[@]%_*} + COMPREPLY=( $( compgen -W "$files" -- $cur ) ) +} + __vercode() { - local s p_found p - s=${#COMP_WORDS[*]} - p_found=false - - $aliased && p=${COMP_WORDS[1]} || { - for (( i=1; i <= s; i++ )); do - $p_found && { p=${COMP_WORDS[$i]}; break;} - [[ ${COMP_WORDS[$i]} == -p ]] || [[ ${COMP_WORDS[$i]} == --package ]] &&\ - p_found=true - done - $p_found || return 0 - } - [ -n "$subdir" ] || __fdroid_cwd + local p + p=${cur:0:-1} - COMPREPLY=( $( compgen -W "$( while read line; do + COMPREPLY=( $( compgen -P "${p}:" -W "$( while read line; do if [[ "$line" == "Build Version:"* ]] then line="${line#*,}" @@ -72,7 +59,7 @@ __vercode() { line="${line#*,}" printf "${line%%,*} " fi - done < "${subdir}/${p}.txt" )" -- $cur ) ) + done < "metadata/${p}.txt" )" -- $cur ) ) } __complete_options() { @@ -88,15 +75,15 @@ __complete_options() { __complete_build() { opts="-h -v -p -c -l -s -t -f" - lopts="--help --verbose --package --vercode --latest --server --resetserver - --on-server --force --install --all" - case "${prev}" in - -p|--package) - __package - return 0;; - -c|--vercode) + lopts="--help --verbose --latest --server --resetserver --on-server + --force --all" + case "${cur}" in + *:) __vercode return 0;; + *) + __package + return 0;; esac __complete_options } @@ -203,7 +190,6 @@ _fdroid() { cmd=${COMP_WORDS[1]} cmds=" build init update publish checkupdates import rewritemeta scanner verify stats server " aliased=false - __fdroid_cwd || return 0 for c in $cmds; do eval "_fdroid_${c} () { local cur prev cmds opts lopts @@ -234,7 +220,6 @@ _fdroid_checkupdates_project() { } _fd-commit() { - __fdroid_cwd || return 0 __package } diff --git a/fdroidserver/build.py b/fdroidserver/build.py index 2dada68c..a5d9dba8 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -379,7 +379,7 @@ def adapt_gradle(path): 's@com.android.tools.build:gradle:[0-9\.\+]*@com.android.tools.build:gradle:'+ config['gradle_plugin'] +'@g', path]) -def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_dir, tmp_dir, install, force, onserver): +def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_dir, tmp_dir, force, onserver): """Do a build locally.""" # Prepare the source code... @@ -506,11 +506,8 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d else: maven_dir = root_dir - mvncmd = [config['mvn3'], '-Dandroid.sdk.path=' + config['sdk_path']] - if install: - mvncmd += ['-Dandroid.sign.debug=true', 'package', 'android:deploy'] - else: - mvncmd += ['-Dandroid.sign.debug=false', '-Dandroid.release=true', 'package'] + mvncmd = [config['mvn3'], '-Dandroid.sdk.path=' + config['sdk_path'], + '-Dandroid.sign.debug=false', '-Dandroid.release=true', 'package'] if 'target' in thisbuild: target = thisbuild["target"].split('-')[1] subprocess.call(['sed', '-i', @@ -622,19 +619,14 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d if 'preassemble' in thisbuild: for task in thisbuild['preassemble'].split(): commands.append(task) - if install: - commands += ['assemble'+flavour+'Debug', 'install'+flavour+'Debug'] - else: - commands += ['assemble'+flavour+'Release'] + commands += ['assemble'+flavour+'Release'] p = FDroidPopen(commands, cwd=gradle_dir) else: print "Building Ant project..." cmd = ['ant'] - if install: - cmd += ['debug','install'] - elif 'antcommand' in thisbuild: + if 'antcommand' in thisbuild: cmd += [thisbuild['antcommand']] else: cmd += ['release'] @@ -646,9 +638,6 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d raise BuildException("Build failed for %s:%s" % (app['id'], thisbuild['version']), p.stdout, p.stderr) print "Successfully built version " + thisbuild['version'] + ' of ' + app['id'] - if install: - return - # Find the apk name in the output... if 'bindir' in thisbuild: bindir = os.path.join(build_dir, thisbuild['bindir']) @@ -752,7 +741,7 @@ def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_d def trybuild(app, thisbuild, build_dir, output_dir, also_check_dir, srclib_dir, extlib_dir, - tmp_dir, repo_dir, vcs, test, server, install, force, onserver): + tmp_dir, repo_dir, vcs, test, server, force, onserver): """ Build a particular version of an application, if it needs building. @@ -796,22 +785,18 @@ def trybuild(app, thisbuild, build_dir, output_dir, also_check_dir, srclib_dir, build_server(app, thisbuild, vcs, build_dir, output_dir, force) else: - build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_dir, tmp_dir, install, force, onserver) + build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_dir, tmp_dir, force, onserver) return True def parse_commandline(): """Parse the command line. Returns options, args.""" - parser = OptionParser() + parser = OptionParser(usage="Usage: %prog [options] [APPID[:VERCODE] [APPID[:VERCODE] ...]]") parser.add_option("-v", "--verbose", action="store_true", default=False, help="Spew out even more information than normal") - parser.add_option("-p", "--package", default=None, - help="Build only the specified package") - parser.add_option("-c", "--vercode", default=None, - help="Build only the specified version code") parser.add_option("-l", "--latest", action="store_true", default=False, - help="Build only the latest version code available") + help="Build only the latest version of each package") parser.add_option("-s", "--stop", action="store_true", default=False, help="Make the build stop on exceptions") parser.add_option("-t", "--test", action="store_true", default=False, @@ -824,13 +809,8 @@ def parse_commandline(): help="Specify that we're running on the build server") parser.add_option("-f", "--force", action="store_true", default=False, help="Force build of disabled apps, and carries on regardless of scan problems. Only allowed in test mode.") - parser.add_option("--install", action="store_true", default=False, - help="Use 'ant debug install' to build and install a " + - "debug version on your device or emulator. " + - "Implies --force and --test") - parser.add_option("--all", action="store_true", default=False, - help="Use with --install, when not using --package" - " to confirm you really want to build and install everything.") + parser.add_option("-a", "--all", action="store_true", default=False, + help="Build all applications available") parser.add_option("-w", "--wiki", default=False, action="store_true", help="Update the wiki") options, args = parser.parse_args() @@ -839,19 +819,6 @@ def parse_commandline(): if options.onserver: options.stop = True - # The --install option implies --test and --force... - if options.install: - if options.server: - print "Can't install when building on a build server." - sys.exit(1) - if not options.package and not options.all: - print "This would build and install everything in the repo to the device." - print "You probably want to use --package and maybe also --vercode." - print "If you really want to install everything, use --all." - sys.exit(1) - options.force = True - options.test = True - if options.force and not options.test: print "Force is only allowed in test mode" sys.exit(1) @@ -874,9 +841,6 @@ def main(): print "Using --resetserver without --server makes no sense" sys.exit(1) - # Get all apps... - apps = metadata.read_metadata(xref=not options.onserver) - log_dir = 'logs' if not os.path.isdir(log_dir): print "Creating log directory" @@ -909,25 +873,10 @@ def main(): srclib_dir = os.path.join(build_dir, 'srclib') extlib_dir = os.path.join(build_dir, 'extlib') - # Filter apps and build versions according to command-line options, etc... - if options.package: - apps = [app for app in apps if app['id'] == options.package] - if len(apps) == 0: - print "No such package" - sys.exit(1) - apps = [app for app in apps if (options.force or not app['Disabled']) and - app['builds'] and len(app['Repo Type']) > 0 and len(app['builds']) > 0] - if len(apps) == 0: - print "Nothing to do - all apps are disabled or have no builds defined." - sys.exit(1) - if options.vercode: - for app in apps: - app['builds'] = [b for b in app['builds'] - if str(b['vercode']) == options.vercode] - elif options.latest: - for app in apps: - m = max([i['vercode'] for i in app['builds']], key=int) - app['builds'] = [b for b in app['builds'] if b['vercode'] == m] + # Get all apps... + allapps = metadata.read_metadata(xref=not options.onserver) + + apps = common.read_app_args(args, options, allapps) if options.wiki: import mwclient @@ -967,7 +916,7 @@ def main(): print "Checking " + thisbuild['version'] if trybuild(app, thisbuild, build_dir, output_dir, also_check_dir, srclib_dir, extlib_dir, tmp_dir, repo_dir, vcs, options.test, - options.server, options.install, options.force, options.onserver): + options.server, options.force, options.onserver): build_succeeded.append(app) wikilog = "Build succeeded" except BuildException as be: diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 5b3d7c62..fc230749 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -110,6 +110,53 @@ def read_config(opts, config_file='config.py'): return config +def read_app_args(args, options, allapps): + if args: + vercodes = {} + for p in args: + if ':' in p: + package, vercode = p.split(':') + else: + package, vercode = p, None + if package not in vercodes: + vercodes[package] = [vercode] if vercode else [] + continue + elif vercode not in vercodes[package]: + vercodes[package] += [vercode] if vercode else [] + packages = vercodes.keys() + apps = [app for app in allapps if app['id'] in packages] + if len(apps) != len(packages): + allids = [app["id"] for app in allapps] + for p in packages: + if p not in allids: + print "No such package: %s" % p + raise Exception("Found invalid app ids in arguments") + + apps = [app for app in apps if (options.force or not app['Disabled']) and + app['builds'] and len(app['Repo Type']) > 0 and len(app['builds']) > 0] + if len(apps) == 0: + raise Exception("No apps to process.") + + error = False + for app in apps: + vc = vercodes[app['id']] + if vc: + app['builds'] = [b for b in app['builds'] if b['vercode'] in vc] + if len(app['builds']) != len(vercodes[app['id']]): + error = True + allvcs = [b['vercode'] for b in app['builds']] + for v in vercodes[app['id']]: + if v not in allvcs: + print "No such vercode %s for app %s" % (v, app['id']) + elif options.latest: + app['builds'] = app['builds'][-1:] + + if error: + raise Exception("Found invalid vercodes for some apps") + + return apps + + def getapkname(app, build): return "%s_%s.apk" % (app['id'], build['vercode']) @@ -117,14 +164,14 @@ def getsrcname(app, build): return "%s_%s_src.tar.gz" % (app['id'], build['vercode']) def getappname(app): - if app['Name']: - return '%s (%s)' % (app['Name'], app['id']) - if app['Auto Name']: - return '%s (%s)' % (app['Auto Name'], app['id']) - return app['id'] + if app['Name']: + return '%s (%s)' % (app['Name'], app['id']) + if app['Auto Name']: + return '%s (%s)' % (app['Auto Name'], app['id']) + return app['id'] def getcvname(app): - return '%s (%s)' % (app['Current Version'], app['Current Version Code']) + return '%s (%s)' % (app['Current Version'], app['Current Version Code']) def getvcs(vcstype, remote, local): if vcstype == 'git': diff --git a/fdroidserver/metadata.py b/fdroidserver/metadata.py index 889fae0d..f52fc878 100644 --- a/fdroidserver/metadata.py +++ b/fdroidserver/metadata.py @@ -38,25 +38,26 @@ class MetaDataException(Exception): class FieldType(): def __init__(self, name, matching, sep, fields, attrs): self.name = name + self.matching = matching if type(matching) is str: - self.matching = re.compile(matching) - elif type(matching) is list: - self.matching = matching + self.compiled = re.compile(matching) self.sep = sep self.fields = fields self.attrs = attrs def _assert_regex(self, values, appid): for v in values: - if not self.matching.match(v): - raise MetaDataException("'%s' is not a valid %s in %s" - % (v, self.name, appid)) + if not self.compiled.match(v): + raise MetaDataException("'%s' is not a valid %s in %s. " + % (v, self.name, appid) + + "Regex pattern: %s" % (self.matching)) def _assert_list(self, values, appid): for v in values: if v not in self.matching: - raise MetaDataException("'%s' is not a valid %s in %s" - % (v, self.name, appid)) + raise MetaDataException("'%s' is not a valid %s in %s. " + % (v, self.name, appid) + + "Possible values: %s" % (", ".join(self.matching))) def check(self, value, appid): if type(value) is not str or not value: