From 3768d7a4d68f09005ccfe5dcd610752fee995a30 Mon Sep 17 00:00:00 2001 From: Hans-Christoph Steiner Date: Wed, 5 Aug 2015 14:39:58 +0200 Subject: [PATCH] refactor env handling for FDroidPopen to support .fdroid.* metadata The start up sequence of processes that are based on the .fdroid.* metadata is a bit different, so this ensures that the environment variables get properly initialized in all cases. This also creates a single function where the environment is set. Before it was being set in multiple places across multiple files. --- fdroidserver/build.py | 8 +------ fdroidserver/common.py | 50 +++++++++++++++++++++++++++++++----------- tests/common.TestCase | 2 +- tests/import.TestCase | 5 +++-- tests/install.TestCase | 2 +- tests/update.TestCase | 4 ++++ 6 files changed, 47 insertions(+), 24 deletions(-) diff --git a/fdroidserver/build.py b/fdroidserver/build.py index b059124d..b64cc920 100644 --- a/fdroidserver/build.py +++ b/fdroidserver/build.py @@ -472,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, diff --git a/fdroidserver/common.py b/fdroidserver/common.py index 725c7961..8b676cc5 100644 --- a/fdroidserver/common.py +++ b/fdroidserver/common.py @@ -197,7 +197,7 @@ def read_config(opts, config_file='config.py'): The config is read from config_file, which is in the current directory when any of the repo management commands are used. """ - global config, options, env, orig_path + global config, options, orig_path if config is not None: return config @@ -268,6 +268,21 @@ def read_config(opts, config_file='config.py'): return config +def get_ndk_path(version): + if config is None or 'ndk_paths' not in config: + ndk_path = os.getenv('ANDROID_NDK_HOME') + if ndk_path is None: + logging.error('No NDK found! Either set ANDROID_NDK_HOME or add ndk_path to your config.py') + else: + return ndk_path + if version is None: + version = 'r10e' # falls back to latest + paths = config['ndk_paths'] + if version not in paths: + return '' + return paths[version] or '' + + def find_sdk_tools_cmd(cmd): '''find a working path to a tool from the Android SDK''' @@ -1639,6 +1654,8 @@ def FDroidPopenBytes(commands, cwd=None, output=True, stderr_to_stdout=True): """ global env + if env is None: + set_FDroidPopen_env() if cwd: cwd = os.path.normpath(cwd) @@ -1780,25 +1797,32 @@ def remove_signing_keys(build_dir): logging.info("Cleaned %s of keysigning configs at %s" % (propfile, path)) -def reset_env_path(): +def set_FDroidPopen_env(build=None): + # There is only a weak standard, the variables used by gradle, so also set + # up the most commonly used environment variables for SDK and NDK global env, orig_path - env['PATH'] = orig_path + if env is None: + env = os.environ + orig_path = env['PATH'] + for n in ['ANDROID_HOME', 'ANDROID_SDK']: + env[n] = config['sdk_path'] + # Set up environment vars that depend on each build + if build is not None: + path = build.ndk_path() + paths = orig_path.split(os.pathsep) + if path in paths: + return + paths.append(path) + env['PATH'] = os.pathsep.join(paths) -def add_to_env_path(path): - global env - paths = env['PATH'].split(os.pathsep) - if path in paths: - return - paths.append(path) - env['PATH'] = os.pathsep.join(paths) + for n in ['ANDROID_NDK', 'NDK', 'ANDROID_NDK_HOME']: + env[n] = build.ndk_path() def replace_config_vars(cmd, build): - global env cmd = cmd.replace('$$SDK$$', config['sdk_path']) - # env['ANDROID_NDK'] is set in build_local right before prepare_source - cmd = cmd.replace('$$NDK$$', env['ANDROID_NDK']) + cmd = cmd.replace('$$NDK$$', get_ndk_path(build['ndk'])) cmd = cmd.replace('$$MVN3$$', config['mvn3']) if build is not None: cmd = cmd.replace('$$COMMIT$$', build.commit) diff --git a/tests/common.TestCase b/tests/common.TestCase index 48e1d29d..d7dca14e 100755 --- a/tests/common.TestCase +++ b/tests/common.TestCase @@ -64,7 +64,7 @@ class CommonTest(unittest.TestCase): def testIsApkDebuggable(self): config = dict() - config['sdk_path'] = os.getenv('ANDROID_HOME') + fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config self._set_build_tools() config['aapt'] = fdroidserver.common.find_sdk_tools_cmd('aapt') diff --git a/tests/import.TestCase b/tests/import.TestCase index cce85d68..c53b53d4 100755 --- a/tests/import.TestCase +++ b/tests/import.TestCase @@ -25,8 +25,9 @@ class ImportTest(unittest.TestCase): def test_import_gitlab(self): # FDroidPopen needs some config to work - fdroidserver.common.config = dict() - fdroidserver.common.config['sdk_path'] = '/fake/path/to/android-sdk' + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config url = 'https://gitlab.com/fdroid/fdroidclient' app = fdroidserver.metadata.get_default_app_info() diff --git a/tests/install.TestCase b/tests/install.TestCase index d1ed93ff..ce516117 100755 --- a/tests/install.TestCase +++ b/tests/install.TestCase @@ -23,7 +23,7 @@ class InstallTest(unittest.TestCase): def test_devices(self): config = dict() - config['sdk_path'] = os.getenv('ANDROID_HOME') + fdroidserver.common.fill_config_defaults(config) fdroidserver.common.config = config config['adb'] = fdroidserver.common.find_sdk_tools_cmd('adb') self.assertTrue(os.path.exists(config['adb'])) diff --git a/tests/update.TestCase b/tests/update.TestCase index 83349f5e..0cc93e5c 100755 --- a/tests/update.TestCase +++ b/tests/update.TestCase @@ -29,6 +29,10 @@ class UpdateTest(unittest.TestCase): if not os.path.exists(getsig_dir + "/getsig.class"): logging.critical("getsig.class not found. To fix: cd '%s' && ./make.sh" % getsig_dir) sys.exit(1) + # FDroidPopen needs some config to work + config = dict() + fdroidserver.common.fill_config_defaults(config) + fdroidserver.common.config = config p = FDroidPopen(['java', '-cp', os.path.join(os.path.dirname(__file__), 'getsig'), 'getsig', os.path.join(os.getcwd(), apkfile)]) sig = None