chiark / gitweb /
add force_build_tools config option
[fdroidserver.git] / fdroidserver / build.py
index 10f40dc478da8dc214373adc271ac01ab4b67b9a..bad025a6d9a37258aedad1bada262e1a82301f6e 100644 (file)
@@ -176,6 +176,7 @@ def get_clean_vm(reset=False):
         os.mkdir('builder')
 
         p = subprocess.Popen(['vagrant', '--version'],
+                             universal_newlines=True,
                              stdout=subprocess.PIPE)
         vver = p.communicate()[0].strip().split(' ')[1]
         if vver.split('.')[0] != '1' or int(vver.split('.')[1]) < 4:
@@ -387,8 +388,9 @@ def build_server(app, build, vcs, build_dir, output_dir, force):
         if options.verbose:
             cmdline += ' --verbose'
         cmdline += " %s:%s" % (app.id, build.vercode)
-        chan.exec_command('bash -c ". ~/.bsenv && ' + cmdline + '"')
-        output = ''
+        cmdline = '. /etc/profile && ' + cmdline
+        chan.exec_command('bash -c "' + cmdline + '"')
+        output = bytes()
         while not chan.exit_status_ready():
             while chan.recv_ready():
                 output += chan.recv(1024)
@@ -403,7 +405,7 @@ def build_server(app, build, vcs, build_dir, output_dir, force):
         if returncode != 0:
             raise BuildException(
                 "Build.py failed on server for {0}:{1}".format(
-                    app.id, build.version), output)
+                    app.id, build.version), str(output, 'utf-8'))
 
         # Retrieve the built files...
         logging.info("Retrieving build output...")
@@ -429,8 +431,7 @@ def build_server(app, build, vcs, build_dir, output_dir, force):
         release_vm()
 
 
-def adapt_gradle(build_dir):
-    filename = 'build.gradle'
+def force_gradle_build_tools(build_dir, build_tools):
     for root, dirs, files in os.walk(build_dir):
         for filename in files:
             if not filename.endswith('.gradle'):
@@ -438,9 +439,9 @@ def adapt_gradle(build_dir):
             path = os.path.join(root, filename)
             if not os.path.isfile(path):
                 continue
-            logging.debug("Adapting %s at %s" % (filename, path))
+            logging.debug("Forcing build-tools %s in %s" % (build_tools, path))
             common.regsub_file(r"""(\s*)buildToolsVersion([\s=]+).*""",
-                               r"""\1buildToolsVersion\2'%s'""" % config['build_tools'],
+                               r"""\1buildToolsVersion\2'%s'""" % build_tools,
                                path)
 
 
@@ -471,13 +472,7 @@ def build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir,
             logging.critical("Android NDK '%s' is not a directory!" % ndk_path)
             sys.exit(3)
 
-    # Set up environment vars that depend on each build
-    for n in ['ANDROID_NDK', 'NDK', 'ANDROID_NDK_HOME']:
-        common.env[n] = ndk_path
-
-    common.reset_env_path()
-    # Set up the current NDK to the PATH
-    common.add_to_env_path(ndk_path)
+    common.set_FDroidPopen_env(build)
 
     # Prepare the source code...
     root_dir, srclibpaths = common.prepare_source(vcs, app, build,
@@ -516,9 +511,10 @@ def build_local(app, build, vcs, build_dir, output_dir, srclib_dir, extlib_dir,
 
         gradletasks += ['assemble' + flavours_cmd + 'Release']
 
-        adapt_gradle(build_dir)
-        for name, number, libpath in srclibpaths:
-            adapt_gradle(libpath)
+        if config['force_build_tools']:
+            force_gradle_build_tools(build_dir, config['build_tools'])
+            for name, number, libpath in srclibpaths:
+                force_gradle_build_tools(libpath, config['build_tools'])
 
         cmd = [config['gradle']]
         if build.gradleprops:
@@ -1007,17 +1003,25 @@ def main():
 
     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:
+    # The defaults for .fdroid.* metadata that is included in a git repo are
+    # different than for the standard metadata/ layout because expectations
+    # are different.  In this case, the most common user will be the app
+    # developer working on the latest update of the app on their own machine.
+    local_metadata_files = common.get_local_metadata_files()
+    if len(local_metadata_files) == 1:  # there is local metadata in an app's source
+        config = dict(common.default_config)
+        # `fdroid build` should build only the latest version by default since
+        # most of the time the user will be building the most recent update
+        if not options.all:
+            options.latest = True
+    elif len(local_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")
+                              + " ".join(local_metadata_files))
+    else:
+        if not os.path.isdir('metadata') and len(local_metadata_files) == 0:
+            raise FDroidException("No app metadata found, nothing to process!")
+        if not options.appid and not options.all:
+            parser.error("option %s: If you really want to build all the apps, use --all" % "all")
 
     config = common.read_config(options)
 
@@ -1062,7 +1066,7 @@ def main():
     allapps = metadata.read_metadata(xref=not options.onserver)
 
     apps = common.read_app_args(options.appid, allapps, True)
-    for appid, app in apps.items():
+    for appid, app in list(apps.items()):
         if (app.Disabled and not options.force) or not app.RepoType or not app.builds:
             del apps[appid]