diff options
Diffstat (limited to 'lib/brick_lib.py')
-rw-r--r-- | lib/brick_lib.py | 273 |
1 files changed, 0 insertions, 273 deletions
diff --git a/lib/brick_lib.py b/lib/brick_lib.py deleted file mode 100644 index 092568816..000000000 --- a/lib/brick_lib.py +++ /dev/null @@ -1,273 +0,0 @@ -# Copyright 2015 The Chromium OS Authors. All rights reserved. -# Use of this source code is governed by a BSD-style license that can be -# found in the LICENSE file. - -"""Common brick related utilities.""" - -from __future__ import print_function - -import os - -from chromite.lib import osutils -from chromite.lib import workspace_lib - -_DEFAULT_LAYOUT_CONF = {'profile_eapi_when_unspecified': '5-progress', - 'profile-formats': 'portage-2 profile-default-eapi', - 'thin-manifests': 'true', - 'use-manifests': 'true'} - -_CONFIG_FILE = 'config.json' - -_IGNORED_OVERLAYS = ('portage-stable', 'chromiumos', 'eclass-overlay') - - -class BrickCreationFailed(Exception): - """The brick creation failed.""" - - -class BrickNotFound(Exception): - """The brick does not exist.""" - - -class BrickFeatureNotSupported(Exception): - """Attempted feature not supported for this brick.""" - - -class Brick(object): - """Encapsulates the interaction with a brick.""" - - def __init__(self, brick_loc, initial_config=None, allow_legacy=True): - """Instantiates a brick object. - - Args: - brick_loc: brick locator. This can be a relative path to CWD, an absolute - path, a public board name prefix with 'board:' or a relative path to the - root of the workspace, prefixed with '//'). - initial_config: The initial configuration as a python dictionary. - If not None, creates a brick with this configuration. - allow_legacy: Allow board overlays, simulating a basic read-only config. - Ignored if |initial_config| is not None. - - Raises: - ValueError: If |brick_loc| is invalid. - LocatorNotResolved: |brick_loc| is valid but could not be resolved. - BrickNotFound: If |brick_loc| does not point to a brick and no initial - config was provided. - BrickCreationFailed: when the brick could not be created successfully. - """ - if workspace_lib.IsLocator(brick_loc): - self.brick_dir = workspace_lib.LocatorToPath(brick_loc) - self.brick_locator = brick_loc - else: - self.brick_dir = brick_loc - self.brick_locator = workspace_lib.PathToLocator(brick_loc) - - self.config = None - self.legacy = False - config_json = os.path.join(self.brick_dir, _CONFIG_FILE) - - if not os.path.exists(config_json): - if initial_config: - if os.path.exists(self.brick_dir): - raise BrickCreationFailed('directory %s already exists.' - % self.brick_dir) - success = False - try: - self.UpdateConfig(initial_config) - osutils.SafeMakedirs(self.OverlayDir()) - osutils.SafeMakedirs(self.SourceDir()) - success = True - except BrickNotFound as e: - # If BrickNotFound was raised, the dependencies contain a missing - # brick. - raise BrickCreationFailed('dependency not found %s' % e) - finally: - if not success: - # If the brick creation failed for any reason, cleanup the partially - # created brick. - osutils.RmDir(self.brick_dir, ignore_missing=True) - - elif allow_legacy: - self.legacy = True - try: - masters = self._ReadLayoutConf().get('masters') - masters_list = masters.split() if masters else [] - - # Keep general Chromium OS overlays out of this list as they are - # handled separately by the build system. - deps = ['board:' + d for d in masters_list - if d not in _IGNORED_OVERLAYS] - self.config = {'name': self._ReadLayoutConf()['repo-name'], - 'dependencies': deps} - except (IOError, KeyError): - pass - - if self.config is None: - raise BrickNotFound('Brick not found at %s' % self.brick_dir) - elif initial_config is None: - self.config = workspace_lib.ReadConfigFile(config_json) - else: - raise BrickCreationFailed('brick %s already exists.' % self.brick_dir) - - self.friendly_name = None - if not self.legacy: - self.friendly_name = workspace_lib.LocatorToFriendlyName( - self.brick_locator) - - def _LayoutConfPath(self): - """Returns the path to the layout.conf file.""" - return os.path.join(self.OverlayDir(), 'metadata', 'layout.conf') - - def _WriteLayoutConf(self, content): - """Writes layout.conf. - - Sets unset fields to a sensible default and write |content| in layout.conf - in the right format. - - Args: - content: dictionary containing the set fields in layout.conf. - """ - for k, v in _DEFAULT_LAYOUT_CONF.iteritems(): - content.setdefault(k, v) - - content_str = ''.join(['%s = %s\n' % (k, v) - for k, v in content.iteritems()]) - osutils.WriteFile(self._LayoutConfPath(), content_str, makedirs=True) - - def _ReadLayoutConf(self): - """Returns the content of layout.conf as a Python dictionary.""" - def ParseConfLine(line): - k, _, v = line.partition('=') - return k.strip(), v.strip() or None - - content_str = osutils.ReadFile(self._LayoutConfPath()) - return dict(ParseConfLine(line) for line in content_str.splitlines()) - - def UpdateConfig(self, config, regenerate=True): - """Updates the brick's configuration. - - Writes |config| to the configuration file. - If |regenerate| is true, regenerate the portage configuration files in - this brick to match the new configuration. - - Args: - config: brick configuration as a python dict. - regenerate: if True, regenerate autogenerated brick files. - """ - if self.legacy: - raise BrickFeatureNotSupported( - 'Cannot update configuration of legacy brick %s' % self.brick_dir) - - self.config = config - # All objects must be unambiguously referenced. Normalize all the - # dependencies according to the workspace. - self.config['dependencies'] = [d if workspace_lib.IsLocator(d) - else workspace_lib.PathToLocator(d) - for d in self.config.get('dependencies', [])] - - workspace_lib.WriteConfigFile(os.path.join(self.brick_dir, _CONFIG_FILE), - config) - - if regenerate: - self.GeneratePortageConfig() - - def GeneratePortageConfig(self): - """Generates all autogenerated brick files.""" - # We don't generate anything in legacy brick so everything is up-to-date. - if self.legacy: - return - - deps = [b.config['name'] for b in self.Dependencies()] - - self._WriteLayoutConf( - {'masters': ' '.join( - ['eclass-overlay', 'portage-stable', 'chromiumos'] + deps), - 'repo-name': self.config['name']}) - - def Dependencies(self): - """Returns the dependent bricks.""" - return [Brick(d) for d in self.config.get('dependencies', [])] - - def Inherits(self, brick_name): - """Checks whether this brick contains |brick_name|. - - Args: - brick_name: The name of the brick to check containment. - - Returns: - Whether |brick_name| is contained in this brick. - """ - return brick_name in [b.config['name'] for b in self.BrickStack()] - - def MainPackages(self): - """Returns the brick's main package(s). - - This finds the 'main_package' property. It nevertheless returns a (single - element) list as it is easier to work with. - - Returns: - A list of main packages; empty if no main package configured. - """ - main_package = self.config.get('main_package') - return [main_package] if main_package else [] - - def OverlayDir(self): - """Returns the brick's overlay directory.""" - if self.legacy: - return self.brick_dir - - return os.path.join(self.brick_dir, 'packages') - - def SourceDir(self): - """Returns the project's source directory.""" - return os.path.join(self.brick_dir, 'src') - - def FriendlyName(self): - """Return the friendly name for this brick. - - This name is used as the board name for legacy commands (--board). - """ - if self.friendly_name is None: - raise BrickFeatureNotSupported() - return self.friendly_name - - def BrickStack(self): - """Returns the brick stack for this brick. - - Returns: - A list of bricks, respecting the partial ordering of bricks as defined by - dependencies, ordered from the lowest priority to the highest priority. - """ - seen = set() - def _stack(brick): - seen.add(brick.brick_dir) - l = [] - for dep in brick.Dependencies(): - if dep.brick_dir not in seen: - l.extend(_stack(dep)) - l.append(brick) - return l - - return _stack(self) - - -def FindBrickInPath(path=None): - """Returns the root directory of the brick containing a path. - - Return the first parent directory of |path| that is the root of a brick. - This method is used for brick auto-detection and does not consider legacy. - - Args: - path: path to a directory. If |path| is None, |path| will be set to CWD. - - Returns: - The path to the first parent that is a brick directory if one exist. - Otherwise return None. - """ - for p in osutils.IteratePathParents(path or os.getcwd()): - try: - return Brick(p, allow_legacy=False) - except BrickNotFound: - pass - - return None |