From 0bc4ffacd98068a9be01066ab0c129bad9e5d0a6 Mon Sep 17 00:00:00 2001 From: Zac Medico Date: Tue, 15 May 2012 21:29:38 -0700 Subject: [PATCH 2/2] Profile parent repo: references for bug #414961. If "profile-formats = portage-2" is specified in metadata/layout.conf, then paths such as 'gentoo:targets/desktop' or ':targets/desktop' in profile parent files can be used to express paths relative to the root 'profiles' directory of a repository. When the repo name is omitted before the colon, it refers to the current repository that the parent file is inside of. --- .../package/ebuild/_config/LocationsManager.py | 48 ++++++++++++++++++-- pym/portage/repository/config.py | 2 +- 2 files changed, 45 insertions(+), 5 deletions(-) diff --git a/pym/portage/package/ebuild/_config/LocationsManager.py b/pym/portage/package/ebuild/_config/LocationsManager.py index 337edc4..9be3401 100644 --- a/pym/portage/package/ebuild/_config/LocationsManager.py +++ b/pym/portage/package/ebuild/_config/LocationsManager.py @@ -29,7 +29,10 @@ _profile_node = collections.namedtuple('_profile_node', 'location portage1_directories') _allow_directories = frozenset( - ["portage-1-compat", "portage-1"]) + ["portage-1-compat", "portage-1", "portage-2"]) + +_allow_parent_colon = frozenset( + ["portage-2"]) class LocationsManager(object): @@ -96,7 +99,7 @@ class LocationsManager(object): if self.profile_path: try: self._addProfile(os.path.realpath(self.profile_path), - known_repos) + repositories, known_repos) except ParseError as e: writemsg(_("!!! Unable to parse profile: '%s'\n") % \ self.profile_path, noiselevel=-1) @@ -123,9 +126,10 @@ class LocationsManager(object): noiselevel=-1) raise DirectoryNotFound(var) - def _addProfile(self, currentPath, known_repos): + def _addProfile(self, currentPath, repositories, known_repos): current_abs_path = os.path.abspath(currentPath) allow_directories = True + allow_parent_colon = True repo_loc = None compat_mode = False intersecting_repos = [x for x in known_repos if current_abs_path.startswith(x[0])] @@ -136,6 +140,8 @@ class LocationsManager(object): allow_directories = any(x in _allow_directories for x in layout_data['profile-formats']) compat_mode = layout_data['profile-formats'] == ('portage-1-compat',) + allow_parent_colon = any(x in _allow_parent_colon + for x in layout_data['profile-formats']) if compat_mode: offenders = _PORTAGE1_DIRECTORIES.intersection(os.listdir(currentPath)) @@ -177,6 +183,12 @@ class LocationsManager(object): _("Empty parent file: '%s'") % parentsFile) for parentPath in parents: abs_parent = parentPath[:1] == os.sep + if not abs_parent and allow_parent_colon: + parentPath = self._expand_parent_colon(parentsFile, + parentPath, repo_loc, repositories) + + # NOTE: This os.path.join() call is intended to ignore + # currentPath if parentPath is already absolute. parentPath = normalize_path(os.path.join( currentPath, parentPath)) @@ -187,7 +199,7 @@ class LocationsManager(object): parentPath = os.path.realpath(parentPath) if os.path.exists(parentPath): - self._addProfile(parentPath, known_repos) + self._addProfile(parentPath, repositories, known_repos) else: raise ParseError( _("Parent '%s' not found: '%s'") % \ @@ -197,6 +209,34 @@ class LocationsManager(object): self.profiles_complex.append( _profile_node(currentPath, allow_directories)) + def _expand_parent_colon(self, parentsFile, parentPath, + repo_loc, repositories): + colon = parentPath.find(":") + if colon == -1: + return parentPath + + if colon == 0: + if repo_loc is None: + raise ParseError( + _("Parent '%s' not found: '%s'") % \ + (parentPath, parentsFile)) + else: + parentPath = normalize_path(os.path.join( + repo_loc, 'profiles', parentPath[colon+1:])) + else: + p_repo_name = parentPath[:colon] + try: + p_repo_loc = repositories.get_location_for_name(p_repo_name) + except KeyError: + raise ParseError( + _("Parent '%s' not found: '%s'") % \ + (parentPath, parentsFile)) + else: + parentPath = normalize_path(os.path.join( + p_repo_loc, 'profiles', parentPath[colon+1:])) + + return parentPath + def set_root_override(self, root_overwrite=None): # Allow ROOT setting to come from make.conf if it's not overridden # by the constructor argument (from the calling environment). diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py index 872c189..6f62019 100644 --- a/pym/portage/repository/config.py +++ b/pym/portage/repository/config.py @@ -28,7 +28,7 @@ from portage import _encodings from portage import manifest _valid_profile_formats = frozenset( - ['pms', 'portage-1']) + ['pms', 'portage-1', 'portage-2']) _repo_name_sub_re = re.compile(r'[^\w-]') -- 1.7.9.7