chiark / gitweb /
Switch all headers to python3
[fdroidserver.git] / fdroidserver / build.py
index d792132d570d42dbcbd2e87a36ad2c839c32b0ca..cf12c34ed32856ec90c0cedbc64720f8ebcfb09a 100644 (file)
@@ -1,5 +1,4 @@
-#!/usr/bin/env python2
-# -*- coding: utf-8 -*-
+#!/usr/bin/env python3
 #
 # build.py - part of the FDroid server tools
 # Copyright (C) 2010-2014, Ciaran Gultnieks, ciaran@ciarang.com
@@ -30,7 +29,6 @@ import time
 import json
 from ConfigParser import ConfigParser
 from argparse import ArgumentParser
-from distutils.version import LooseVersion
 import logging
 
 import common
@@ -179,16 +177,15 @@ def get_clean_vm(reset=False):
 
         p = subprocess.Popen(['vagrant', '--version'],
                              stdout=subprocess.PIPE)
-        vver = p.communicate()[0]
+        vver = p.communicate()[0].strip().split(' ')[1]
+        if vver.split('.')[0] != '1' or int(vver.split('.')[1]) < 4:
+            raise BuildException("Unsupported vagrant version {0}".format(vver))
+
         with open(os.path.join('builder', 'Vagrantfile'), 'w') as vf:
-            if vver.startswith('Vagrant version 1.2'):
-                vf.write('Vagrant.configure("2") do |config|\n')
-                vf.write('config.vm.box = "buildserver"\n')
-                vf.write('end\n')
-            else:
-                vf.write('Vagrant::Config.run do |config|\n')
-                vf.write('config.vm.box = "buildserver"\n')
-                vf.write('end\n')
+            vf.write('Vagrant.configure("2") do |config|\n')
+            vf.write('config.vm.box = "buildserver"\n')
+            vf.write('config.vm.synced_folder ".", "/vagrant", disabled: true\n')
+            vf.write('end\n')
 
         logging.info("Starting new build server")
         retcode, _ = vagrant(['up'], cwd='builder')
@@ -491,8 +488,8 @@ def build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir,
     # different from the default ones
     p = None
     gradletasks = []
-    method = build.method()
-    if method == 'maven':
+    bmethod = build.build_method()
+    if bmethod == 'maven':
         logging.info("Cleaning Maven project...")
         cmd = [config['mvn3'], 'clean', '-Dandroid.sdk.path=' + config['sdk_path']]
 
@@ -504,7 +501,7 @@ def build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir,
 
         p = FDroidPopen(cmd, cwd=maven_dir)
 
-    elif method == 'gradle':
+    elif bmethod == 'gradle':
 
         logging.info("Cleaning Gradle project...")
 
@@ -525,21 +522,16 @@ def build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir,
 
         cmd = [config['gradle']]
         if build.gradleprops:
-            cmd += ['-P'+kv for kv in build.gradleprops]
-
-        for task in gradletasks:
-            parts = task.split(':')
-            parts[-1] = 'clean' + capitalize_intact(parts[-1])
-            cmd += [':'.join(parts)]
+            cmd += ['-P' + kv for kv in build.gradleprops]
 
         cmd += ['clean']
 
         p = FDroidPopen(cmd, cwd=root_dir)
 
-    elif method == 'kivy':
+    elif bmethod == 'kivy':
         pass
 
-    elif method == 'ant':
+    elif bmethod == 'ant':
         logging.info("Cleaning Ant project...")
         p = FDroidPopen(['ant', 'clean'], cwd=root_dir)
 
@@ -564,7 +556,7 @@ def build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir,
             # .gradle/ as binary files. To avoid overcomplicating the scanner,
             # manually delete them, just like `gradle clean` should have removed
             # the build/ dirs.
-            del_dirs(['build', '.gradle', 'gradle'])
+            del_dirs(['build', '.gradle'])
             del_files(['gradlew', 'gradlew.bat'])
 
         if 'pom.xml' in files:
@@ -646,7 +638,7 @@ def build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir,
 
     p = None
     # Build the release...
-    if method == 'maven':
+    if bmethod == 'maven':
         logging.info("Building Maven project...")
 
         if '@' in build.maven:
@@ -672,7 +664,7 @@ def build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir,
 
         bindir = os.path.join(root_dir, 'target')
 
-    elif method == 'kivy':
+    elif bmethod == 'kivy':
         logging.info("Building Kivy project...")
 
         spec = os.path.join(root_dir, 'buildozer.spec')
@@ -733,18 +725,18 @@ def build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir,
         cmd.append('release')
         p = FDroidPopen(cmd, cwd=distdir)
 
-    elif method == 'gradle':
+    elif bmethod == 'gradle':
         logging.info("Building Gradle project...")
 
         cmd = [config['gradle']]
         if build.gradleprops:
-            cmd += ['-P'+kv for kv in build.gradleprops]
+            cmd += ['-P' + kv for kv in build.gradleprops]
 
         cmd += gradletasks
 
         p = FDroidPopen(cmd, cwd=root_dir)
 
-    elif method == 'ant':
+    elif bmethod == 'ant':
         logging.info("Building Ant project...")
         cmd = ['ant']
         if build.antcommands:
@@ -759,7 +751,8 @@ def build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir,
         raise BuildException("Build failed for %s:%s" % (app.id, build.version), p.output)
     logging.info("Successfully built version " + build.version + ' of ' + app.id)
 
-    if method == 'maven':
+    omethod = build.output_method()
+    if omethod == 'maven':
         stdout_apk = '\n'.join([
             line for line in p.output.splitlines() if any(
                 a in line for a in ('.apk', '.ap_', '.jar'))])
@@ -779,34 +772,46 @@ def build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir,
             raise BuildException('Failed to find output')
         src = m.group(1)
         src = os.path.join(bindir, src) + '.apk'
-    elif method == 'kivy':
+    elif omethod == 'kivy':
         src = os.path.join('python-for-android', 'dist', 'default', 'bin',
                            '{0}-{1}-release.apk'.format(
                                bconfig.get('app', 'title'),
                                bconfig.get('app', 'version')))
-    elif method == 'gradle':
+    elif omethod == 'gradle':
+        src = None
+        for apks_dir in [
+                os.path.join(root_dir, 'build', 'outputs', 'apk'),
+                os.path.join(root_dir, 'build', 'apk'),
+                ]:
+            for apkglob in ['*-release-unsigned.apk', '*-unsigned.apk', '*.apk']:
+                apks = glob.glob(os.path.join(apks_dir, apkglob))
+
+                if len(apks) > 1:
+                    raise BuildException('More than one resulting apks found in %s' % apks_dir,
+                                         '\n'.join(apks))
+                if len(apks) == 1:
+                    src = apks[0]
+                    break
+            if src is not None:
+                break
 
-        if build.gradlepluginver >= LooseVersion('0.11'):
-            apks_dir = os.path.join(root_dir, 'build', 'outputs', 'apk')
-        else:
-            apks_dir = os.path.join(root_dir, 'build', 'apk')
+        if src is None:
+            raise BuildException('Failed to find any output apks')
 
-        apks = glob.glob(os.path.join(apks_dir, '*-release-unsigned.apk'))
-        if len(apks) > 1:
-            raise BuildException('More than one resulting apks found in %s' % apks_dir,
-                                 '\n'.join(apks))
-        if len(apks) < 1:
-            raise BuildException('Failed to find gradle output in %s' % apks_dir)
-        src = apks[0]
-    elif method == 'ant':
+    elif omethod == 'ant':
         stdout_apk = '\n'.join([
             line for line in p.output.splitlines() if '.apk' in line])
         src = re.match(r".*^.*Creating (.+) for release.*$.*", stdout_apk,
                        re.S | re.M).group(1)
         src = os.path.join(bindir, src)
-    elif method == 'raw':
-        src = os.path.join(root_dir, build.output)
-        src = os.path.normpath(src)
+    elif omethod == 'raw':
+        globpath = os.path.join(root_dir, build.output)
+        apks = glob.glob(globpath)
+        if len(apks) > 1:
+            raise BuildException('Multiple apks match %s' % globpath, '\n'.join(apks))
+        if len(apks) < 1:
+            raise BuildException('No apks match %s' % globpath)
+        src = os.path.normpath(apks[0])
 
     # Make sure it's not debuggable...
     if common.isApkDebuggable(src, config):
@@ -1001,6 +1006,16 @@ def main():
     global options, config
 
     options, parser = parse_commandline()
+
+    metadata_files = glob.glob('.fdroid.*[a-z]')  # ignore files ending in ~
+    if os.path.isdir('metadata'):
+        pass
+    elif len(metadata_files) == 0:
+        raise FDroidException("No app metadata found, nothing to process!")
+    elif len(metadata_files) > 1:
+        raise FDroidException("Only one local metadata file allowed! Found: "
+                              + " ".join(metadata_files))
+
     if not options.appid and not options.all:
         parser.error("option %s: If you really want to build all the apps, use --all" % "all")