diff --git a/completion/bash-completion b/completion/bash-completion index f5d914c2..a6a79518 100644 --- a/completion/bash-completion +++ b/completion/bash-completion @@ -12,16 +12,6 @@ # # alias fbuild='fdroid build' # complete -F _fdroid_build fbuild -# -# There are also completion function for '-p com.some.app' aliases: -# -# alias fbld='fdroid build -v -l -p' -# complete -F _fdroid_build_project fbld -# -# alias fcheckup='fdroid checkupdates -v -p' -# complete -F _fdroid_checkupdates_project fcheckup -# -# This way, one can simply do 'fbld com.some.app' or 'fcheckup com.some.app' __fdroid_init() { COMPREPLY=() @@ -38,21 +28,22 @@ __package() { COMPREPLY=( $( compgen -W "$files" -- $cur ) ) } -__signed_package() { - files=( repo/*.apk ) - if [ "${files[0]}" == "repo/*.apk" ]; then - return - fi - files=( ${files[@]#repo/} ) +__apk_package() { + files=( ${1}/*.apk ) + [ -f "${files[0]}" ] || return + + files=( ${files[@]#*/} ) files=${files[@]%_*} COMPREPLY=( $( compgen -W "$files" -- $cur ) ) } -__signed_vercode() { +__apk_vercode() { local p p=${cur:0:-1} - files=( repo/${p}_*.apk ) + files=( ${1}/${p}_*.apk ) + [ -f "${files[0]}" ] || return + files=( ${files[@]#*_} ) files=${files[@]%.apk} COMPREPLY=( $( compgen -P "${p}:" -W "$files" -- $cur ) ) @@ -109,10 +100,10 @@ __complete_install() { __complete_options return 0;; *:) - __signed_vercode + __apk_vercode repo return 0;; *) - __signed_package + __apk_package repo return 0;; esac } @@ -130,14 +121,19 @@ __complete_update() { } __complete_publish() { - opts="-h -v -p" - lopts="--help --verbose --package" - case "${prev}" in - -p|--package) - __package + opts="-h -v" + lopts="--help --verbose" + case "${cur}" in + -*) + __complete_options + return 0;; + *:) + __apk_vercode unsigned + return 0;; + *) + __apk_package unsigned return 0;; esac - __complete_options } __complete_checkupdates() { diff --git a/fdroidserver/build.py b/fdroidserver/build.py index c9d3d2f8..e7fe5591 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -876,7 +876,7 @@ def main(): # Get all apps... allapps = metadata.read_metadata(xref=not options.onserver) - apps = common.read_app_args(args, options, allapps, True) + apps = common.read_app_args(args, allapps, True) apps = [app for app in apps if (options.force or not app['Disabled']) and len(app['Repo Type']) > 0 and len(app['builds']) > 0] diff --git a/fdroidserver/checkupdates.py b/fdroidserver/checkupdates.py index f2aaec79..17a6c963 100644 --- a/fdroidserver/checkupdates.py +++ b/fdroidserver/checkupdates.py @@ -295,7 +295,7 @@ def main(): # Get all apps... allapps = metadata.read_metadata(options.verbose) - apps = common.read_app_args(args, options, allapps, False) + apps = common.read_app_args(args, allapps, False) if options.gplay: for app in apps: diff --git a/fdroidserver/publish.py b/fdroidserver/publish.py index 8e824d26..d04c3a7d 100644 --- a/fdroidserver/publish.py +++ b/fdroidserver/publish.py @@ -38,10 +38,9 @@ def main(): # Parse command line... 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="Publish only the specified package") (options, args) = parser.parse_args() config = common.read_config(options) @@ -74,9 +73,10 @@ def main(): # and b) a sane-looking ID that would make its way into the repo. # Nonetheless, to be sure, before publishing we check that there are no # collisions, and refuse to do any publishing if that's the case... - apps = metadata.read_metadata() + allapps = metadata.read_metadata() + vercodes = common.read_pkg_args(args, True) allaliases = [] - for app in apps: + for app in allapps: m = md5.new() m.update(app['id']) keyalias = m.hexdigest()[:8] @@ -85,87 +85,87 @@ def main(): sys.exit(1) allaliases.append(keyalias) if options.verbose: - print "{0} apps, {0} key aliases".format(len(apps), len(allaliases)) + print "{0} apps, {0} key aliases".format(len(allapps), len(allaliases)) # Process any apks that are waiting to be signed... for apkfile in sorted(glob.glob(os.path.join(unsigned_dir, '*.apk'))): + appid, vercode = common.apknameinfo(apkfile) apkfilename = os.path.basename(apkfile) - i = apkfilename.rfind('_') - if i == -1: - raise BuildException("Invalid apk name") - appid = apkfilename[:i] - print "Processing " + appid + if vercodes and appid not in vercodes: + continue + if appid in vercodes and vercodes[appid]: + if vercode not in vercodes[appid]: + continue + print "Processing " + apkfile - if not options.package or options.package == appid: - - # Figure out the key alias name we'll use. Only the first 8 - # characters are significant, so we'll use the first 8 from - # the MD5 of the app's ID and hope there are no collisions. - # If a collision does occur later, we're going to have to - # come up with a new alogrithm, AND rename all existing keys - # in the keystore! - if appid in config['keyaliases']: - # For this particular app, the key alias is overridden... - keyalias = config['keyaliases'][appid] - if keyalias.startswith('@'): - m = md5.new() - m.update(keyalias[1:]) - keyalias = m.hexdigest()[:8] - else: + # Figure out the key alias name we'll use. Only the first 8 + # characters are significant, so we'll use the first 8 from + # the MD5 of the app's ID and hope there are no collisions. + # If a collision does occur later, we're going to have to + # come up with a new alogrithm, AND rename all existing keys + # in the keystore! + if appid in config['keyaliases']: + # For this particular app, the key alias is overridden... + keyalias = config['keyaliases'][appid] + if keyalias.startswith('@'): m = md5.new() - m.update(appid) + m.update(keyalias[1:]) keyalias = m.hexdigest()[:8] - print "Key alias: " + keyalias + else: + m = md5.new() + m.update(appid) + keyalias = m.hexdigest()[:8] + print "Key alias: " + keyalias - # See if we already have a key for this application, and - # if not generate one... - p = subprocess.Popen(['keytool', '-list', - '-alias', keyalias, '-keystore', config['keystore'], - '-storepass', config['keystorepass']], stdout=subprocess.PIPE) - output = p.communicate()[0] - if p.returncode !=0: - print "Key does not exist - generating..." - p = subprocess.Popen(['keytool', '-genkey', - '-keystore', config['keystore'], '-alias', keyalias, - '-keyalg', 'RSA', '-keysize', '2048', - '-validity', '10000', - '-storepass', config['keystorepass'], - '-keypass', config['keypass'], - '-dname', config['keydname']], stdout=subprocess.PIPE) - output = p.communicate()[0] - print output - if p.returncode != 0: - raise BuildException("Failed to generate key") - - # Sign the application... - p = subprocess.Popen(['jarsigner', '-keystore', config['keystore'], + # See if we already have a key for this application, and + # if not generate one... + p = subprocess.Popen(['keytool', '-list', + '-alias', keyalias, '-keystore', config['keystore'], + '-storepass', config['keystorepass']], stdout=subprocess.PIPE) + output = p.communicate()[0] + if p.returncode !=0: + print "Key does not exist - generating..." + p = subprocess.Popen(['keytool', '-genkey', + '-keystore', config['keystore'], '-alias', keyalias, + '-keyalg', 'RSA', '-keysize', '2048', + '-validity', '10000', '-storepass', config['keystorepass'], - '-keypass', config['keypass'], '-sigalg', - 'MD5withRSA', '-digestalg', 'SHA1', - apkfile, keyalias], stdout=subprocess.PIPE) + '-keypass', config['keypass'], + '-dname', config['keydname']], stdout=subprocess.PIPE) output = p.communicate()[0] print output if p.returncode != 0: - raise BuildException("Failed to sign application") + raise BuildException("Failed to generate key") - # Zipalign it... - p = subprocess.Popen([os.path.join(config['sdk_path'],'tools','zipalign'), - '-v', '4', apkfile, - os.path.join(output_dir, apkfilename)], - stdout=subprocess.PIPE) - output = p.communicate()[0] - print output - if p.returncode != 0: - raise BuildException("Failed to align application") - os.remove(apkfile) + # Sign the application... + p = subprocess.Popen(['jarsigner', '-keystore', config['keystore'], + '-storepass', config['keystorepass'], + '-keypass', config['keypass'], '-sigalg', + 'MD5withRSA', '-digestalg', 'SHA1', + apkfile, keyalias], stdout=subprocess.PIPE) + output = p.communicate()[0] + print output + if p.returncode != 0: + raise BuildException("Failed to sign application") - # Move the source tarball into the output directory... - tarfilename = apkfilename[:-4] + '_src.tar.gz' - shutil.move(os.path.join(unsigned_dir, tarfilename), - os.path.join(output_dir, tarfilename)) + # Zipalign it... + p = subprocess.Popen([os.path.join(config['sdk_path'],'tools','zipalign'), + '-v', '4', apkfile, + os.path.join(output_dir, apkfilename)], + stdout=subprocess.PIPE) + output = p.communicate()[0] + print output + if p.returncode != 0: + raise BuildException("Failed to align application") + os.remove(apkfile) - print 'Published ' + apkfilename + # Move the source tarball into the output directory... + tarfilename = apkfilename[:-4] + '_src.tar.gz' + shutil.move(os.path.join(unsigned_dir, tarfilename), + os.path.join(output_dir, tarfilename)) + + print 'Published ' + apkfilename if __name__ == "__main__":