ftp.mkdir('extlib')
ftp.mkdir('srclib')
# Copy any extlibs that are required...
- if 'extlibs' in thisbuild:
+ if thisbuild['extlibs']:
ftp.chdir(homedir + '/build/extlib')
for lib in thisbuild['extlibs']:
lib = lib.strip()
ftp.chdir('..')
# Copy any srclibs that are required...
srclibpaths = []
- if 'srclibs' in thisbuild:
+ if thisbuild['srclibs']:
for lib in thisbuild['srclibs']:
srclibpaths.append(
common.getsrclib(lib, 'build/srclib', srclibpaths,
def build_local(app, thisbuild, vcs, build_dir, output_dir, srclib_dir, extlib_dir, tmp_dir, force, onserver):
"""Do a build locally."""
- if thisbuild.get('buildjni') not in (None, ['no']):
+ if thisbuild['buildjni'] and thisbuild['buildjni'] != ['no']:
if not config['ndk_path']:
logging.critical("$ANDROID_NDK is not set!")
sys.exit(3)
f.write(manifestcontent)
# Run a build command if one is required...
- if 'build' in thisbuild:
+ if thisbuild['build']:
+ logging.info("Running 'build' commands in %s" % root_dir)
cmd = common.replace_config_vars(thisbuild['build'])
+
# Substitute source library paths into commands...
for name, number, libpath in srclibpaths:
libpath = os.path.relpath(libpath, root_dir)
cmd = cmd.replace('$$' + name + '$$', libpath)
- logging.info("Running 'build' commands in %s" % root_dir)
p = FDroidPopen(['bash', '-x', '-c', cmd], cwd=root_dir)
(app['id'], thisbuild['version']), p.stdout)
# Build native stuff if required...
- if thisbuild.get('buildjni') not in (None, ['no']):
- logging.info("Building native libraries...")
- jni_components = thisbuild.get('buildjni')
+ if thisbuild['buildjni'] and thisbuild['buildjni'] != ['no']:
+ logging.info("Building the native code")
+ jni_components = thisbuild['buildjni']
+
if jni_components == ['yes']:
jni_components = ['']
cmd = [os.path.join(config['ndk_path'], "ndk-build"), "-j1"]
'-Dmaven.jar.sign.skip=true', '-Dmaven.test.skip=true',
'-Dandroid.sign.debug=false', '-Dandroid.release=true',
'package']
- if 'target' in thisbuild:
+ if thisbuild['target']:
target = thisbuild["target"].split('-')[1]
FDroidPopen(['sed', '-i',
's@<platform>[0-9]*</platform>@<platform>'
'pom.xml'],
cwd=maven_dir)
- if 'mvnflags' in thisbuild:
+ if thisbuild['mvnflags']:
mvncmd += thisbuild['mvnflags']
p = FDroidPopen(mvncmd, cwd=maven_dir)
flavours[0] = ''
commands = [config['gradle']]
- if 'preassemble' in thisbuild:
+ if thisbuild['preassemble']:
commands += thisbuild['preassemble'].split()
flavours_cmd = ''.join(flavours)
elif thisbuild['type'] == 'ant':
logging.info("Building Ant project...")
cmd = ['ant']
- if 'antcommand' in thisbuild:
+ if thisbuild['antcommand']:
cmd += [thisbuild['antcommand']]
else:
cmd += ['release']
elif thisbuild['type'] == 'gradle':
basename = app['id']
dd = build_dir
- if 'subdir' in thisbuild:
+ if thisbuild['subdir']:
dd = os.path.join(dd, thisbuild['subdir'])
basename = os.path.basename(thisbuild['subdir'])
if '@' in thisbuild['gradle']:
elif line.startswith("native-code:"):
nativecode = line[12:]
- if thisbuild.get('buildjni') is not None:
+ if thisbuild['buildjni']:
if nativecode is None or "'" not in nativecode:
raise BuildException("Native code should have been built but none was packaged")
if thisbuild['novcheck']:
if os.path.exists(dest_also):
return False
- if 'disable' in thisbuild:
+ if thisbuild['disable']:
return False
logging.info("Building version " + thisbuild['version'] + ' of ' + app['id'])
if options.latest:
for app in apps:
for build in reversed(app['builds']):
- if 'disable' in build:
+ if build['disable']:
continue
app['builds'] = [build]
break
flavour = None
if len(app['builds']) > 0:
- if 'subdir' in app['builds'][-1]:
+ if app['builds'][-1]['subdir']:
build_dir = os.path.join(build_dir, app['builds'][-1]['subdir'])
- if 'gradle' in app['builds'][-1]:
+ if app['builds'][-1]['gradle']:
flavour = app['builds'][-1]['gradle']
if flavour == 'yes':
flavour = None
flavour = None
if len(app['builds']) > 0:
- if 'subdir' in app['builds'][-1]:
+ if app['builds'][-1]['subdir']:
build_dir = os.path.join(build_dir, app['builds'][-1]['subdir'])
- if 'gradle' in app['builds'][-1]:
+ if app['builds'][-1]['gradle']:
flavour = app['builds'][-1]['gradle']
if flavour == 'yes':
flavour = None
flavour = None
if len(app['builds']) > 0:
- if 'subdir' in app['builds'][-1]:
+ if app['builds'][-1]['subdir']:
app_dir = os.path.join(app_dir, app['builds'][-1]['subdir'])
- if 'gradle' in app['builds'][-1]:
+ if app['builds'][-1]['gradle']:
flavour = app['builds'][-1]['gradle']
if flavour == 'yes':
flavour = None
if not gotcur:
newbuild = latest.copy()
- for k in ('origlines', 'disable'):
- if k in newbuild:
- del newbuild[k]
+ del newbuild['origlines']
+ newbuild['disable'] = False
newbuild['vercode'] = app['Current Version Code']
newbuild['version'] = app['Current Version'] + suffix
logging.info("...auto-generating build for " + newbuild['version'])
def prepare_source(vcs, app, build, build_dir, srclib_dir, extlib_dir, onserver=False):
# Optionally, the actual app source can be in a subdirectory
- if 'subdir' in build:
+ if build['subdir']:
root_dir = os.path.join(build_dir, build['subdir'])
else:
root_dir = build_dir
raise BuildException('Missing subdir ' + root_dir)
# Run an init command if one is required
- if 'init' in build:
+ if build['init']:
cmd = replace_config_vars(build['init'])
logging.info("Running 'init' commands in %s" % root_dir)
(app['id'], build['version']), p.stdout)
# Apply patches if any
- if 'patch' in build:
+ if build['patch']:
+ logging.info("Applying patches")
for patch in build['patch']:
patch = patch.strip()
logging.info("Applying " + patch)
# Get required source libraries
srclibpaths = []
- if 'srclibs' in build:
+ if build['srclibs']:
logging.info("Collecting source libraries")
for lib in build['srclibs']:
srclibpaths.append(getsrclib(lib, srclib_dir, srclibpaths,
# Update the local.properties file
localprops = [os.path.join(build_dir, 'local.properties')]
- if 'subdir' in build:
+ if build['subdir']:
localprops += [os.path.join(root_dir, 'local.properties')]
for path in localprops:
if not os.path.isfile(path):
props += "ndk.dir=%s\n" % config['ndk_path']
props += "ndk-location=%s\n" % config['ndk_path']
# Add java.encoding if necessary
- if 'encoding' in build:
+ if build['encoding']:
props += "java.encoding=%s\n" % build['encoding']
f = open(path, 'w')
f.write(props)
if flavour in ['main', 'yes', '']:
flavour = None
- if 'target' in build:
+ if build['target']:
n = build["target"].split('-')[1]
FDroidPopen(['sed', '-i',
's@compileSdkVersion *[0-9]*@compileSdkVersion ' + n + '@g',
raise BuildException("Failed to amend build.gradle")
# Delete unwanted files
- if 'rm' in build:
+ if build['rm']:
+ logging.info("Removing specified files")
for part in getpaths(build_dir, build, 'rm'):
dest = os.path.join(build_dir, part)
logging.info("Removing {0}".format(part))
remove_signing_keys(build_dir)
# Add required external libraries
- if 'extlibs' in build:
+ if build['extlibs']:
logging.info("Collecting prebuilt libraries")
libsdir = os.path.join(root_dir, 'libs')
if not os.path.exists(libsdir):
shutil.copyfile(libsrc, os.path.join(libsdir, libf))
# Run a pre-build command if one is required
- if 'prebuild' in build:
+ if build['prebuild']:
+ logging.info("Running 'prebuild' commands in %s" % root_dir)
+
cmd = replace_config_vars(build['prebuild'])
# Substitute source library paths into prebuild commands
libpath = os.path.relpath(libpath, root_dir)
cmd = cmd.replace('$$' + name + '$$', libpath)
- logging.info("Running 'prebuild' commands in %s" % root_dir)
-
p = FDroidPopen(['bash', '-x', '-c', cmd], cwd=root_dir)
if p.returncode != 0:
raise BuildException("Error running prebuild command for %s:%s" %
(app['id'], build['version']), p.stdout)
- updatemode = build.get('update', ['auto'])
# Generate (or update) the ant build file, build.xml...
- if updatemode != ['no'] and build['type'] == 'ant':
+ if build['update'] and build['update'] != ['no'] and build['type'] == 'ant':
parms = [os.path.join(config['sdk_path'], 'tools', 'android'), 'update']
lparms = parms + ['lib-project']
parms = parms + ['project']
- if 'target' in build and build['target']:
+ if build['target']:
parms += ['-t', build['target']]
lparms += ['-t', build['target']]
- if updatemode == ['auto']:
+ if build['update'] == ['auto']:
update_dirs = ant_subprojects(root_dir) + ['.']
else:
- update_dirs = updatemode
+ update_dirs = build['update']
for d in update_dirs:
subdir = os.path.join(root_dir, d)
# Split and extend via globbing the paths from a field
def getpaths(build_dir, build, field):
paths = []
- if field not in build:
- return paths
for p in build[field]:
p = p.strip()
full_path = os.path.join(build_dir, p)
# indicate a problem (if it's not a problem, explicitly use
# buildjni=no to bypass this check)
if (os.path.exists(os.path.join(root_dir, 'jni')) and
- thisbuild.get('buildjni') is None):
+ not thisbuild['buildjni']):
logging.warn('Found jni directory, but buildjni is not enabled')
count += 1
continue
for build in app['builds']:
- if 'commit' in build and 'disable' not in build:
+ if build['commit'] and not build['disable']:
lastcommit = build['commit']
# Potentially incorrect UCM
# Build warnings
for build in app['builds']:
for n in ['master', 'origin/', 'default', 'trunk']:
- if 'commit' in build:
- if build['commit'].startswith(n):
- warn("Branch '%s' used as commit in build '%s'" % (
- n, build['version']))
- if 'srclibs' in build:
- for srclib in build['srclibs']:
- ref = srclib.split('@')[1].split('/')[0]
- if ref.startswith(n):
- warn("Branch '%s' used as commit in srclib '%s'" % (
- n, srclib))
+ if build['commit'] and build['commit'].startswith(n):
+ warn("Branch '%s' used as commit in build '%s'" % (
+ n, build['version']))
+ for srclib in build['srclibs']:
+ ref = srclib.split('@')[1].split('/')[0]
+ if ref.startswith(n):
+ warn("Branch '%s' used as commit in srclib '%s'" % (
+ n, srclib))
if not appid:
print
import cgi
import logging
+from collections import OrderedDict
+
srclibs = {}
def __str__(self):
return self.value
-app_defaults = {
- 'Disabled': None,
- 'AntiFeatures': None,
- 'Provides': None,
- 'Categories': ['None'],
- 'License': 'Unknown',
- 'Web Site': '',
- 'Source Code': '',
- 'Issue Tracker': '',
- 'Donate': None,
- 'FlattrID': None,
- 'Bitcoin': None,
- 'Litecoin': None,
- 'Dogecoin': None,
- 'Name': None,
- 'Auto Name': '',
- 'Summary': '',
- 'Description': [],
- 'Requires Root': False,
- 'Repo Type': '',
- 'Repo': '',
- 'Maintainer Notes': [],
- 'Archive Policy': None,
- 'Auto Update Mode': 'None',
- 'Update Check Mode': 'None',
- 'Update Check Ignore': None,
- 'Vercode Operation': None,
- 'Update Check Name': None,
- 'Update Check Data': None,
- 'Current Version': '',
- 'Current Version Code': '0',
- 'No Source Since': ''
- }
-
-
-# This defines the preferred order for the build items - as in the
-# manual, they're roughly in order of application.
-ordered_flags = [
- 'disable', 'commit', 'subdir', 'submodules', 'init',
- 'gradle', 'maven', 'kivy', 'output', 'oldsdkloc', 'target',
- 'update', 'encoding', 'forceversion', 'forcevercode', 'rm',
- 'extlibs', 'srclibs', 'patch', 'prebuild', 'scanignore',
- 'scandelete', 'build', 'buildjni', 'preassemble', 'bindir',
- 'antcommand', 'novcheck'
- ]
+# In the order in which they are laid out on files
+app_defaults = OrderedDict([
+ ('Disabled', None),
+ ('AntiFeatures', None),
+ ('Provides', None),
+ ('Categories', ['None']),
+ ('License', 'Unknown'),
+ ('Web Site', ''),
+ ('Source Code', ''),
+ ('Issue Tracker', ''),
+ ('Donate', None),
+ ('FlattrID', None),
+ ('Bitcoin', None),
+ ('Litecoin', None),
+ ('Dogecoin', None),
+ ('Name', None),
+ ('Auto Name', ''),
+ ('Summary', ''),
+ ('Description', []),
+ ('Requires Root', False),
+ ('Repo Type', ''),
+ ('Repo', ''),
+ ('Maintainer Notes', []),
+ ('Archive Policy', None),
+ ('Auto Update Mode', 'None'),
+ ('Update Check Mode', 'None'),
+ ('Update Check Ignore', None),
+ ('Vercode Operation', None),
+ ('Update Check Name', None),
+ ('Update Check Data', None),
+ ('Current Version', ''),
+ ('Current Version Code', '0'),
+ ('No Source Since', ''),
+ ])
+
+
+# In the order in which they are laid out on files
+# Sorted by their action and their place in the build timeline
+flag_defaults = OrderedDict([
+ ('disable', False),
+ ('commit', None),
+ ('subdir', None),
+ ('submodules', False),
+ ('init', None),
+ ('patch', []),
+ ('gradle', False),
+ ('maven', False),
+ ('kivy', False),
+ ('output', None),
+ ('srclibs', []),
+ ('oldsdkloc', False),
+ ('encoding', None),
+ ('forceversion', False),
+ ('forcevercode', False),
+ ('rm', []),
+ ('extlibs', []),
+ ('prebuild', []),
+ ('update', ['auto']),
+ ('target', None),
+ ('scanignore', []),
+ ('scandelete', []),
+ ('build', []),
+ ('buildjni', []),
+ ('preassemble', []),
+ ('antcommand', None),
+ ('novcheck', False),
+ ])
# Designates a metadata field type and checks that it matches
v.check(info[field], info['id'])
for build in info['builds']:
for attr in v.attrs:
- if attr in build:
+ if build[attr]:
v.check(build[attr], info['id'])
if name in ['init', 'prebuild', 'build']:
return 'script'
if name in ['submodules', 'oldsdkloc', 'forceversion', 'forcevercode',
- 'novcheck']:
+ 'novcheck']:
return 'bool'
return 'string'
.format(pk, thisbuild['version'], linedesc))
pk = pk.lstrip()
- if pk not in ordered_flags:
+ if pk not in flag_defaults:
raise MetaDataException("Unrecognised build flag at {0} in {1}"
.format(p, linedesc))
t = flagtype(pk)
def get_build_type(build):
for t in ['maven', 'gradle', 'kivy']:
- if build.get(t, 'no') != 'no':
+ if build[t]:
return t
- if 'output' in build:
+ if build['output']:
return 'raw'
return 'ant'
curcomments = []
curbuild = None
- def fill_bool_defaults(build):
- # TODO: quick fix to make bool flags default to False
- # Should provide defaults for all flags instead of using
- # build.get(flagname, default) each time
- for f in ordered_flags:
- if f in build:
- continue
- if flagtype(f) == 'bool':
- build[f] = False
-
c = 0
for line in metafile:
c += 1
raise MetaDataException("No commit specified for {0} in {1}"
.format(curbuild['version'], linedesc))
- fill_bool_defaults(curbuild)
thisinfo['builds'].append(curbuild)
add_comments('build:' + curbuild['version'])
mode = 0
mode = 2
buildlines = [value[:-1]]
else:
- thisinfo['builds'].append(parse_buildline([value]))
+ curbuild = parse_buildline([value])
add_comments('build:' + thisinfo['builds'][-1]['version'])
elif fieldtype == 'buildv2':
curbuild = {}
else:
buildlines.append(line)
curbuild = parse_buildline(buildlines)
- fill_bool_defaults(curbuild)
thisinfo['builds'].append(curbuild)
add_comments('build:' + thisinfo['builds'][-1]['version'])
mode = 0
thisinfo['Description'].append('No description available')
for build in thisinfo['builds']:
+ for flag, value in flag_defaults.iteritems():
+ if flag in build:
+ continue
+ build[flag] = value
build['type'] = get_build_type(build)
return thisinfo
if key in ['version', 'vercode', 'origlines', 'type']:
return
- t = flagtype(key)
- if t == 'bool' and value == False:
+ if value == flag_defaults[key]:
return
+ t = flagtype(key)
+
logging.debug("...writing {0} : {1}".format(key, value))
outline = ' %s=' % key
outline += '\n'
mf.write(outline)
- for key in ordered_flags:
- if key in build:
- write_builditem(key, build[key])
+ for flag in flag_defaults:
+ value = build[flag]
+ if value:
+ write_builditem(flag, value)
mf.write('\n')
if app['Maintainer Notes']:
for thisbuild in app['builds']:
- if 'disable' in thisbuild:
+ if thisbuild['disable']:
logging.info("...skipping version %s - %s" % (
thisbuild['version'], thisbuild.get('disable', thisbuild['commit'][1:])))
else:
apklist.append(apk)
# Include ones we can't build, as a special case...
for thisbuild in app['builds']:
- if 'disable' in thisbuild:
+ if thisbuild['disable']:
if thisbuild['vercode'] == app['Current Version Code']:
cantupdate = True
# TODO: Nasty: vercode is a string in the build, and an int elsewhere
"""
for app in apps:
for build in app['builds']:
- if 'disable' in build:
+ if build['disable']:
apkfilename = app['id'] + '_' + str(build['vercode']) + '.apk'
for repodir in repodirs:
apkpath = os.path.join(repodir, apkfilename)