Chromium Code Reviews| OLD | NEW |
|---|---|
| (Empty) | |
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | |
| 2 # Use of this source code is governed by a BSD-style license that can be | |
| 3 # found in the LICENSE file. | |
| 4 | |
| 5 import json | |
| 6 import logging | |
| 7 import os | |
| 8 import sys | |
| 9 import tempfile | |
| 10 import threading | |
| 11 | |
| 12 # TODO(jbudorick): Update this once dependency_manager moves to catapult. | |
| 13 _TELEMETRY_PATH = os.path.abspath(os.path.join( | |
| 14 os.path.dirname(__file__), os.pardir, os.pardir, os.pardir, | |
| 15 'tools', 'telemetry')) | |
| 16 sys.path.append(_TELEMETRY_PATH) | |
| 17 from catapult_base import dependency_manager # pylint: disable=import-error | |
| 18 | |
| 19 | |
| 20 _DEFAULT_CONFIG_FILES = [ | |
| 21 os.path.abspath(os.path.join( | |
| 22 os.path.dirname(__file__), os.pardir, 'devil_config.json')), | |
| 23 ] | |
| 24 | |
| 25 | |
| 26 class _Environment(object): | |
| 27 | |
| 28 def __init__(self): | |
| 29 self._config = None | |
| 30 self._config_init_lock = threading.Lock() | |
| 31 | |
| 32 def Initialize(self, configs=None, config_files=None): | |
| 33 """Initialize devil's environment. | |
| 34 | |
| 35 This uses all configurations provided via |configs| and |config_files| | |
| 36 to determine the locations of devil's dependencies. Configurations should | |
| 37 all take the form described by catapult_base.dependency_manager.BaseConfig. | |
| 38 If no configurations are provided, a default one will be used if available. | |
| 39 | |
| 40 Args: | |
| 41 configs: An optional list of dict configurations. | |
| 42 config_files: An optional list of files to load | |
| 43 """ | |
| 44 | |
| 45 # Make sure we only initialize self._config once. | |
| 46 with self._config_init_lock: | |
| 47 if self._config is not None: | |
| 48 return | |
| 49 self._config = {} | |
| 50 | |
| 51 self._InitializeRecursive(configs=configs, config_files=config_files) | |
| 52 | |
| 53 def _InitializeRecursive(self, configs=None, config_files=None): | |
| 54 if configs: | |
| 55 with tempfile.NamedTemporaryFile() as next_config_file: | |
| 56 next_config_file.write(json.dumps(configs[0])) | |
| 57 next_config_file.flush() | |
| 58 self._InitializeRecursive( | |
| 59 configs=configs[1:], | |
| 60 config_files=[next_config_file.name] + (config_files or [])) | |
|
perezju
2015/09/14 16:15:06
ugh, this is a somewhat ugly use of recursion... a
jbudorick
2015/09/14 17:45:39
Correct.
aiolos (Not reviewing)
2015/09/16 03:37:54
I designed the dependency_manager to allow subclas
jbudorick
2015/09/18 15:08:20
Landing as-is. I'll send you a follow-up CL.
| |
| 61 else: | |
| 62 self._InitializeImpl(config_files) | |
| 63 | |
| 64 def _InitializeImpl(self, config_files): | |
| 65 if not config_files: | |
| 66 config_files = _DEFAULT_CONFIG_FILES | |
| 67 | |
| 68 dm = dependency_manager.DependencyManager( | |
| 69 [dependency_manager.BaseConfig(c) for c in config_files]) | |
| 70 platform = 'linux_android' | |
| 71 | |
| 72 self._config['android_sdk_path'] = dm.FetchPath('android_sdk', platform) | |
| 73 self._config['adb_path'] = ( | |
| 74 dm.FetchPath('adb_path', platform) | |
| 75 or os.path.join(self.android_sdk_path, 'platform-tools', 'adb')) | |
| 76 | |
| 77 build_tools_contents = os.listdir( | |
| 78 os.path.join(self.android_sdk_path, 'build-tools')) | |
| 79 if not build_tools_contents: | |
| 80 self._config['android_sdk_build_tools_path'] = None | |
| 81 else: | |
| 82 if len(build_tools_contents) > 1: | |
| 83 build_tools_contents.sort() | |
| 84 logging.warning( | |
| 85 'More than one set of build-tools provided by the Android SDK: %s', | |
| 86 ','.join(build_tools_contents)) | |
| 87 logging.warning('Defaulting to %s', build_tools_contents[-1]) | |
| 88 self._config['android_sdk_build_tools_path'] = os.path.join( | |
| 89 self.android_sdk_path, 'build-tools', build_tools_contents[-1]) | |
| 90 | |
| 91 self._config['forwarder_host_path'] = dm.FetchPath( | |
| 92 'forwarder_host', platform) | |
| 93 self._config['forwarder_device_path'] = dm.FetchPath( | |
| 94 'forwarder_device', platform) | |
| 95 | |
| 96 self._config['md5sum_host_path'] = dm.FetchPath('md5sum_host', platform) | |
| 97 self._config['md5sum_device_path'] = dm.FetchPath('md5sum_device', platform) | |
| 98 | |
| 99 self._config['pymock_path'] = dm.FetchPath('pymock', platform) | |
| 100 | |
| 101 def __getattr__(self, name): | |
| 102 if self._config is None: | |
| 103 self.Initialize() | |
| 104 | |
| 105 if name not in self._config: | |
| 106 raise AttributeError('devil environment has no %r attribute', name) | |
|
perezju
2015/09/14 16:15:06
This is not logging. I think here you really need:
jbudorick
2015/09/14 17:45:39
O_O
fixed.
| |
| 107 | |
| 108 return self._config[name] | |
| 109 | |
| 110 | |
| 111 config = _Environment() | |
| 112 | |
| 113 | |
| 114 def GenerateDynamicConfig(deps): | |
| 115 """Generate a configuration dict from the provided deps dict. | |
| 116 | |
| 117 Args: | |
| 118 deps: A dict mapping dependency names to lists of local files. | |
| 119 Returns: | |
| 120 A BaseConfig-compatible dict. | |
| 121 """ | |
| 122 return { | |
| 123 'config_type': 'BaseConfig', | |
| 124 'dependencies': { | |
| 125 k: { | |
| 126 'file_info': { | |
| 127 'linux_android': { | |
| 128 'local_paths': v | |
| 129 } | |
| 130 } | |
| 131 } for k, v in deps.iteritems() | |
| 132 } | |
| 133 } | |
| 134 | |
| OLD | NEW |