1645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# Copyright 2015 The Chromium Authors. All rights reserved. 2645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# Use of this source code is governed by a BSD-style license that can be 3645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez# found in the LICENSE file. 4645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 5645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezimport contextlib 6645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezimport json 7645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezimport os 8645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezimport platform 9645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezimport sys 10645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezimport tempfile 11645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezimport threading 12645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 13645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezCATAPULT_ROOT_PATH = os.path.abspath(os.path.join( 14645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez os.path.dirname(__file__), '..', '..')) 15645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezDEPENDENCY_MANAGER_PATH = os.path.join( 16645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez CATAPULT_ROOT_PATH, 'dependency_manager') 17645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector ChavezPYMOCK_PATH = os.path.join( 18645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez CATAPULT_ROOT_PATH, 'third_party', 'mock') 19645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 20645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 21645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez@contextlib.contextmanager 22645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezdef SysPath(path): 23645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez sys.path.append(path) 24645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez yield 25645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if sys.path[-1] != path: 26645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez sys.path.remove(path) 27645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez else: 28645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez sys.path.pop() 29645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 30645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezwith SysPath(DEPENDENCY_MANAGER_PATH): 31645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez import dependency_manager # pylint: disable=import-error 32645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 33645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez_ANDROID_BUILD_TOOLS = {'aapt', 'dexdump', 'split-select'} 34645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 35645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez_DEVIL_DEFAULT_CONFIG = os.path.abspath(os.path.join( 36645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez os.path.dirname(__file__), 'devil_dependencies.json')) 37645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 38645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez_LEGACY_ENVIRONMENT_VARIABLES = { 39645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'ADB_PATH': { 40645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'dependency_name': 'adb', 41645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'platform': 'linux2_x86_64', 42645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez }, 43645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'ANDROID_SDK_ROOT': { 44645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'dependency_name': 'android_sdk', 45645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'platform': 'linux2_x86_64', 46645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez }, 47645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez} 48645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 49645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 50645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezdef _GetEnvironmentVariableConfig(): 51645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez path_config = ( 52645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez (os.environ.get(k), v) 53645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez for k, v in _LEGACY_ENVIRONMENT_VARIABLES.iteritems()) 54645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return { 55645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'config_type': 'BaseConfig', 56645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'dependencies': { 57645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez c['dependency_name']: { 58645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'file_info': { 59645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez c['platform']: { 60645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 'local_paths': [p], 61645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez }, 62645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez }, 63645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } for p, c in path_config if p 64645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez }, 65645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez } 66645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 67645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 68645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezclass _Environment(object): 69645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 70645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def __init__(self): 71645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self._dm_init_lock = threading.Lock() 72645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self._dm = None 73645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 74645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def Initialize(self, configs=None, config_files=None): 75645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """Initialize devil's environment from configuration files. 76645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 77645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez This uses all configurations provided via |configs| and |config_files| 78645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez to determine the locations of devil's dependencies. Configurations should 79645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez all take the form described by catapult_base.dependency_manager.BaseConfig. 80645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez If no configurations are provided, a default one will be used if available. 81645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 82645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez Args: 83645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez configs: An optional list of dict configurations. 84645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez config_files: An optional list of files to load 85645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez """ 86645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 87645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez # Make sure we only initialize self._dm once. 88645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with self._dm_init_lock: 89645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if self._dm is None: 90645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if configs is None: 91645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez configs = [] 92645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 93645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez env_config = _GetEnvironmentVariableConfig() 94645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if env_config: 95645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez configs.insert(0, env_config) 96645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self._InitializeRecursive( 97645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez configs=configs, 98645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez config_files=config_files) 99645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez assert self._dm is not None, 'Failed to create dependency manager.' 100645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 101645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def _InitializeRecursive(self, configs=None, config_files=None): 102645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez # This recurses through configs to create temporary files for each and 103645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez # take advantage of context managers to appropriately close those files. 104645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez # TODO(jbudorick): Remove this recursion if/when dependency_manager 105645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez # supports loading configurations directly from a dict. 106645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if configs: 107645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez with tempfile.NamedTemporaryFile(delete=False) as next_config_file: 108645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez try: 109645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez next_config_file.write(json.dumps(configs[0])) 110645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez next_config_file.close() 111645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self._InitializeRecursive( 112645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez configs=configs[1:], 113645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez config_files=[next_config_file.name] + (config_files or [])) 114645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez finally: 115645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if os.path.exists(next_config_file.name): 116645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez os.remove(next_config_file.name) 117645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez else: 118645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez config_files = config_files or [] 119645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if 'DEVIL_ENV_CONFIG' in os.environ: 120645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez config_files.append(os.environ.get('DEVIL_ENV_CONFIG')) 121645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez config_files.append(_DEVIL_DEFAULT_CONFIG) 122645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 123645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self._dm = dependency_manager.DependencyManager( 124645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez [dependency_manager.BaseConfig(c) for c in config_files]) 125645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 126645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def FetchPath(self, dependency, arch=None, device=None): 127645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if self._dm is None: 128645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.Initialize() 129645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if dependency in _ANDROID_BUILD_TOOLS: 130645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.FetchPath('android_build_tools_libc++', arch=arch, device=device) 131645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return self._dm.FetchPath(dependency, GetPlatform(arch, device)) 132645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 133645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez def LocalPath(self, dependency, arch=None, device=None): 134645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if self._dm is None: 135645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez self.Initialize() 136645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return self._dm.LocalPath(dependency, GetPlatform(arch, device)) 137645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 138645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 139645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezdef GetPlatform(arch=None, device=None): 140645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez if device: 141645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return 'android_%s' % (arch or device.product_cpu_abi) 142645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez return '%s_%s' % (sys.platform, platform.machine()) 143645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 144645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 145645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavezconfig = _Environment() 146645501c2ab19a559ce82a1d5a29ced159a4c30fbLuis Hector Chavez 147