summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Luther <SebastianLuther@gmx.de>2010-09-25 16:20:48 +0200
committerZac Medico <zmedico@gentoo.org>2010-09-26 23:50:15 -0700
commit03e4da855927aa69687acad97246be50096b6b00 (patch)
treec719ef4cba20b94ae5127b388324453c116bcbba
parent59ac8965f0a914123c7f4f570721070c59ce39d8 (diff)
downloadportage-03e4da855927aa69687acad97246be50096b6b00.tar.gz
portage-03e4da855927aa69687acad97246be50096b6b00.tar.bz2
portage-03e4da855927aa69687acad97246be50096b6b00.zip
Improved profiles/p.mask handling
It's now possible for an repo to revert masks from the master for its own packages.
-rw-r--r--pym/portage/package/ebuild/_config/LocationsManager.py5
-rw-r--r--pym/portage/package/ebuild/_config/MaskManager.py53
-rw-r--r--pym/portage/package/ebuild/config.py2
-rw-r--r--pym/portage/repository/config.py17
-rw-r--r--pym/portage/util/__init__.py35
5 files changed, 80 insertions, 32 deletions
diff --git a/pym/portage/package/ebuild/_config/LocationsManager.py b/pym/portage/package/ebuild/_config/LocationsManager.py
index 83d61050f..b857f3262 100644
--- a/pym/portage/package/ebuild/_config/LocationsManager.py
+++ b/pym/portage/package/ebuild/_config/LocationsManager.py
@@ -176,8 +176,3 @@ class LocationsManager(object):
self.profile_locations = tuple(self.profile_locations)
self.profile_and_user_locations = tuple(self.profile_and_user_locations)
-
- self.pmask_locations = (
- tuple([os.path.join(portdir, "profiles")] + self.overlay_profiles),
- tuple(self.profiles),
- )
diff --git a/pym/portage/package/ebuild/_config/MaskManager.py b/pym/portage/package/ebuild/_config/MaskManager.py
index c06e34663..f41636b48 100644
--- a/pym/portage/package/ebuild/_config/MaskManager.py
+++ b/pym/portage/package/ebuild/_config/MaskManager.py
@@ -5,38 +5,49 @@ __all__ = (
'MaskManager',
)
-from itertools import chain
from portage import os
from portage.dep import ExtendedAtomDict, match_from_list, _repo_separator, _slot_separator
-from portage.util import grabfile_package, stack_lists
+from portage.util import append_repo, grabfile_package, stack_lists
from portage.versions import cpv_getkey
class MaskManager(object):
- def __init__(self, pmask_locations, abs_user_config,
+ def __init__(self, repositories, profiles, abs_user_config,
user_config=True, strict_umatched_removal=False):
self._punmaskdict = ExtendedAtomDict(list)
self._pmaskdict = ExtendedAtomDict(list)
- repo_profiles, profiles = pmask_locations
+ #Read profile/package.mask form every repo.
+ #Repositories inherit masks from their parent profiles and
+ #are able to remove mask from them with -atoms.
+ #Such a removal affects only the current repo, but not the parent.
+ #Add ::repo specs to every atom to make sure atoms only affect
+ #packages from the current repo.
- #Read profile/package.mask form every repo. Stack them immediately
- #to make sure that -atoms don't effect other repos.
repo_pkgmasklines = []
- repo_pkgunmasklines = []
- for x in repo_profiles:
- repo_pkgmasklines.append(stack_lists([grabfile_package(
- os.path.join(x, "package.mask"), recursive=1, remember_source_file=True, verify_eapi=True)], \
- incremental=1, remember_source_file=True,
- warn_for_unmatched_removal=True,
+ for repo in repositories.repos_with_profiles():
+ lines = []
+ repo_lines = grabfile_package(os.path.join(repo.location, "profiles", "package.mask"), \
+ recursive=1, remember_source_file=True, verify_eapi=True)
+ masters = repo.masters
+ if masters is None:
+ masters = [repositories.mainRepo()]
+ for master in masters:
+ master_lines = grabfile_package(os.path.join(master.location, "profiles", "package.mask"), \
+ recursive=1, remember_source_file=True, verify_eapi=True)
+ lines.append(stack_lists([master_lines, repo_lines], incremental=1,
+ remember_source_file=True, warn_for_unmatched_removal=True,
strict_warn_for_unmatched_removal=strict_umatched_removal))
- repo_pkgunmasklines.append(stack_lists([grabfile_package(
- os.path.join(x, "package.unmask"), recursive=1, remember_source_file=True, verify_eapi=True)], \
- incremental=1, remember_source_file=True,
- warn_for_unmatched_removal=True,
- strict_warn_for_unmatched_removal=strict_umatched_removal))
- repo_pkgmasklines = list(chain.from_iterable(repo_pkgmasklines))
- repo_pkgunmasklines = list(chain.from_iterable(repo_pkgunmasklines))
+ repo_pkgmasklines.extend(append_repo(stack_lists(lines), repo.name, remember_source_file=True))
+
+ repo_pkgunmasklines = []
+ for repo in repositories.repos_with_profiles():
+ repo_lines = grabfile_package(os.path.join(repo.location, "profiles", "package.unmask"), \
+ recursive=1, remember_source_file=True, verify_eapi=True)
+ lines = stack_lists([repo_lines], incremental=1, \
+ remember_source_file=True, warn_for_unmatched_removal=True,
+ strict_warn_for_unmatched_removal=strict_umatched_removal)
+ repo_pkgmasklines.extend(append_repo(lines, repo.name))
#Read package.mask form the user's profile. Stack them in the end
#to allow profiles to override masks from their parent profiles.
@@ -69,9 +80,9 @@ class MaskManager(object):
#Stack everything together. At this point, only user_pkgmasklines may contain -atoms.
#Don't warn for unmatched -atoms here, since we don't do it for any other user config file.
pkgmasklines = stack_lists([repo_pkgmasklines, profile_pkgmasklines, user_pkgmasklines], \
- incremental=1, remember_source_file=True, warn_for_unmatched_removal=False)
+ incremental=1, remember_source_file=True, warn_for_unmatched_removal=False, ignore_repo=True)
pkgunmasklines = stack_lists([repo_pkgunmasklines, profile_pkgunmasklines, user_pkgunmasklines], \
- incremental=1, remember_source_file=True, warn_for_unmatched_removal=False)
+ incremental=1, remember_source_file=True, warn_for_unmatched_removal=False, ignore_repo=True)
for x, source_file in pkgmasklines:
self._pmaskdict.setdefault(x.cp, []).append(x)
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py
index e6e5d01c7..477444b3c 100644
--- a/pym/portage/package/ebuild/config.py
+++ b/pym/portage/package/ebuild/config.py
@@ -558,7 +558,7 @@ class config(object):
self.configdict["conf"].get("ACCEPT_LICENSE", ""))
#Read package.mask and package.unmask from profiles and optionally from user config
- self._mask_manager = MaskManager(locations_manager.pmask_locations,
+ self._mask_manager = MaskManager(self.repositories, self.profiles,
abs_user_config, user_config=local_config,
strict_umatched_removal=_unmatched_removal)
diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py
index 7f0d392a5..0d4412082 100644
--- a/pym/portage/repository/config.py
+++ b/pym/portage/repository/config.py
@@ -17,7 +17,7 @@ import codecs
class RepoConfig(object):
"""Stores config of one repository"""
__slots__ = ['aliases', 'eclass_overrides', 'location', 'masters', 'main_repo',
- 'missing_repo_name', 'name', 'priority', 'sync']
+ 'missing_repo_name', 'name', 'priority', 'sync', 'format']
def __init__(self, name, repo_opts):
"""Build a RepoConfig with options in repo_opts
Try to read repo_name in repository location, but if
@@ -52,6 +52,11 @@ class RepoConfig(object):
sync = sync.strip()
self.sync = sync
+ format = repo_opts.get('format')
+ if format is not None:
+ format = format.strip()
+ self.format = format
+
self.missing_repo_name = False
location = repo_opts.get('location')
@@ -236,6 +241,10 @@ class RepoConfigLoader(object):
else:
return ''
+ def mainRepo(self):
+ """Returns the main repo"""
+ return self.prepos[self.prepos['DEFAULT'].main_repo]
+
def _check_locations(self):
"""Check if repositories location are correct and show a warning message if not"""
for (name, r) in self.prepos.items():
@@ -248,6 +257,12 @@ class RepoConfigLoader(object):
writemsg(_("!!! Invalid Repository Location"
" (not a dir): '%s'\n") % r.location, noiselevel=-1)
+ def repos_with_profiles(self):
+ for repo_name in self.prepos_order:
+ repo = self.prepos[repo_name]
+ if repo.format != "unavailable":
+ yield repo
+
def load_repository_config(settings):
#~ repoconfigpaths = [os.path.join(settings.global_config_path, "repos.conf")]
#~ repoconfigpaths.append(os.path.join(settings["PORTAGE_CONFIGROOT"],
diff --git a/pym/portage/util/__init__.py b/pym/portage/util/__init__.py
index 0b0e0435e..0c2dc3382 100644
--- a/pym/portage/util/__init__.py
+++ b/pym/portage/util/__init__.py
@@ -231,8 +231,19 @@ def stack_dicts(dicts, incremental=0, incrementals=[], ignore_none=0):
final_dict[k] = v
return final_dict
+def append_repo(atom_list, repo_name, remember_source_file=False):
+ """
+ Takes a list of valid atoms without repo spec and appends ::repo_name.
+ """
+ if remember_source_file:
+ return [(Atom(atom + "::" + repo_name, allow_wildcard=True, allow_repo=True), source) \
+ for atom, source in atom_list]
+ else:
+ return [Atom(atom + "::" + repo_name, allow_wildcard=True, allow_repo=True) \
+ for atom in atom_list]
+
def stack_lists(lists, incremental=1, remember_source_file=False,
- warn_for_unmatched_removal=False, strict_warn_for_unmatched_removal=False):
+ warn_for_unmatched_removal=False, strict_warn_for_unmatched_removal=False, ignore_repo=False):
"""Stacks an array of list-types into one array. Optionally removing
distinct values using '-value' notation. Higher index is preferenced.
@@ -255,9 +266,25 @@ def stack_lists(lists, incremental=1, remember_source_file=False,
if token == "-*":
new_list.clear()
elif token[:1] == '-':
- try:
- new_list.pop(token[1:])
- except KeyError:
+ matched = False
+ if ignore_repo and not "::" in token:
+ #Let -cat/pkg remove cat/pkg::repo.
+ to_be_removed = []
+ for atom in new_list:
+ if atom == token[1:] or atom.split("::")[0] == token[1:]:
+ to_be_removed.append(atom)
+ if to_be_removed:
+ matched = True
+ for atom in to_be_removed:
+ new_list.pop(atom)
+ else:
+ try:
+ new_list.pop(token[1:])
+ matched = True
+ except KeyError:
+ pass
+
+ if not matched:
if source_file and \
(strict_warn_for_unmatched_removal or \
token_key not in matched_removals):