-#!/usr/bin/env python2
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
#
# publish.py - part of the FDroid server tools
# Copyright (C) 2010-13, Ciaran Gultnieks, ciaran@ciarang.com
import shutil
import md5
import glob
-from optparse import OptionParser
+from argparse import ArgumentParser
import logging
import common
global config, options
# Parse command line...
- 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("-q", "--quiet", action="store_true", default=False,
- help="Restrict output to warnings and errors")
- (options, args) = parser.parse_args()
+ parser = ArgumentParser(usage="%(prog)s [options] "
+ "[APPID[:VERCODE] [APPID[:VERCODE] ...]]")
+ common.setup_global_opts(parser)
+ parser.add_argument("appid", nargs='*', help="app-id with optional versioncode in the form APPID[:VERCODE]")
+ options = parser.parse_args()
config = common.read_config(options)
+ if not ('jarsigner' in config and 'keytool' in config):
+ logging.critical('Java JDK not found! Install in standard location or set java_paths!')
+ sys.exit(1)
+
log_dir = 'logs'
if not os.path.isdir(log_dir):
logging.info("Creating log directory")
# Nonetheless, to be sure, before publishing we check that there are no
# collisions, and refuse to do any publishing if that's the case...
allapps = metadata.read_metadata()
- vercodes = common.read_pkg_args(args, True)
+ vercodes = common.read_pkg_args(options.appid, True)
allaliases = []
for appid in allapps:
m = md5.new()
sys.exit(1)
app = allapps[appid]
- if app.get('Binaries', None):
+ if app.Binaries is not None:
# It's an app where we build from source, and verify the apk
# contents against a developer's binary, and then publish their
# version if everything checks out.
-
- # Need the version name for the version code...
- versionname = None
- for build in app['builds']:
- if build['vercode'] == vercode:
- versionname = build['version']
- break
- if not versionname:
- logging.error("...no defined build for version code {0}"
- .format(vercode))
- continue
-
- # Figure out where the developer's binary is supposed to come from...
- url = app['Binaries']
- url = url.replace('%v', versionname)
- url = url.replace('%c', str(vercode))
-
- # Grab the binary from where the developer publishes it...
- logging.info("...retrieving " + url)
- srcapk = os.path.join(tmp_dir, url.split('/')[-1])
- p = FDroidPopen(['wget', '-nv', '--continue', url], cwd=tmp_dir)
- if p.returncode != 0 or not os.path.exists(srcapk):
- logging.error("...failed to retrieve " + url +
- " - publish skipped")
- continue
+ # The binary should already have been retrieved during the build
+ # process.
+ srcapk = apkfile + ".binary"
# Compare our unsigned one with the downloaded one...
- compare_result = common.compare_apks(srcapk, apkfile, tmp_dir)
+ compare_result = common.verify_apks(srcapk, apkfile, tmp_dir)
if compare_result:
logging.error("...verification failed - publish skipped : "
+ compare_result)
continue
- # Success! So move the downloaded file to the repo...
+ # Success! So move the downloaded file to the repo, and remove
+ # our built version.
shutil.move(srcapk, os.path.join(output_dir, apkfilename))
+ os.remove(apkfile)
else:
# See if we already have a key for this application, and
# if not generate one...
- p = FDroidPopen(['keytool', '-list',
+ p = FDroidPopen([config['keytool'], '-list',
'-alias', keyalias, '-keystore', config['keystore'],
'-storepass:file', config['keystorepassfile']])
if p.returncode != 0:
logging.info("Key does not exist - generating...")
- p = FDroidPopen(['keytool', '-genkey',
+ p = FDroidPopen([config['keytool'], '-genkey',
'-keystore', config['keystore'],
'-alias', keyalias,
'-keyalg', 'RSA', '-keysize', '2048',
raise BuildException("Failed to generate key")
# Sign the application...
- p = FDroidPopen(['jarsigner', '-keystore', config['keystore'],
+ p = FDroidPopen([config['jarsigner'], '-keystore', config['keystore'],
'-storepass:file', config['keystorepassfile'],
'-keypass:file', config['keypassfile'], '-sigalg',
- 'MD5withRSA', '-digestalg', 'SHA1',
+ 'SHA1withRSA', '-digestalg', 'SHA1',
apkfile, keyalias])
# TODO keypass should be sent via stdin
if p.returncode != 0: