diff options
authorZac Medico <zmedico@gentoo.org>2014-12-11 10:42:43 -0800
committerZac Medico <zmedico@gentoo.org>2014-12-30 20:41:27 -0800
commit605846a0b98869c9d1cbf19660969fb24e5c680b (patch)
treeeec7c23e887b6cc4fa589bc199311c1fde3f79e9 /pym/portage/repository/config.py
parentFix "TabError: inconsistent use of tabs and spaces in indentation" with Pytho... (diff)
Support override of default profile EAPI (532670)
Add support for a profile-default-eapi flag in the metadata/layout.conf profile-formats field. When this flag is enabled, it enables support for a profile_eapi_when_unspecified attribute which can be used to specify the default EAPI to use for profile directories that do not contain an eapi file. For example, the following settings will cause all profiles that do not contain an eapi file to default to EAPI 5 instead of EAPI 0: profile-formats = profile-default-eapi profile_eapi_when_unspecified = 5 This is convenient for organizations that maintain their own profiles in separate repositories from Gentoo, since they typically want to use EAPI 5 for all of their profiles, and this allows them to avoid having separate eapi files in each directory of their profiles. The name of the profile_eapi_when_unspecified attribute is inherited from Paludis, which has supported this attribute in exheres repositories for many years. The implementation may seem a bit messy because it needs to account for 3 different types of profile nodes: * Regular profile nodes * User profile override directory in /etc/portage/profile * The root "profiles" directory, which is not really a profile node, but is used for repository-level configurations (package.mask being the most common example used by Gentoo) The default EAPI setting is stored in the RepoConfig.eapi attribute, which is used as the "default" parameter for all read_corresponding_eapi_file calls. Each profile node in LocationsManager.profiles_complex now has an eapi attribute which serves to cache the computed EAPI for that node, allowing redundant read_corresponding_eapi_file calls to be eliminated. As a result, functions such as grabfile_package now have eapi and eapi_default parameters, where eapi is used to pass in a cached EAPI, and eapi_default is used to pass in a default for read_corresponding_eapi_file to use when a cached EAPI is not available. For /etc/portage/profile, the EAPI is considered to have a default value of None, which means that atoms from any supported EAPI are allowed. X-Gentoo-Bug: 532670 X-Gentoo-Bug-URL: https://bugs.gentoo.org/show_bug.cgi?id=532670 Acked-by: Alexander Berntsen <bernalex@gentoo.org>
Diffstat (limited to 'pym/portage/repository/config.py')
1 files changed, 37 insertions, 4 deletions
diff --git a/pym/portage/repository/config.py b/pym/portage/repository/config.py
index 9096d7373..7e17e02dd 100644
--- a/pym/portage/repository/config.py
+++ b/pym/portage/repository/config.py
@@ -41,7 +41,8 @@ if sys.hexversion >= 0x3000000:
_invalid_path_char_re = re.compile(r'[^a-zA-Z0-9._\-+:/]')
_valid_profile_formats = frozenset(
- ['pms', 'portage-1', 'portage-2', 'profile-bashrcs', 'profile-set'])
+ ['pms', 'portage-1', 'portage-2', 'profile-bashrcs', 'profile-set',
+ 'profile-default-eapi'])
_portage1_profiles_allow_directories = frozenset(
["portage-1-compat", "portage-1", 'portage-2'])
@@ -190,11 +191,9 @@ class RepoConfig(object):
location = None
self.location = location
- eapi = None
missing = True
self.name = name
if self.location is not None:
- eapi = read_corresponding_eapi_file(os.path.join(self.location, REPO_NAME_LOC))
self.name, missing = self._read_valid_repo_name(self.location)
if missing:
# The name from repos.conf has to be used here for
@@ -208,7 +207,7 @@ class RepoConfig(object):
elif name == "DEFAULT":
missing = False
- self.eapi = eapi
+ self.eapi = None
self.missing_repo_name = missing
# sign_commit is disabled by default, since it requires Git >=1.7.9,
# and key_id configured by `git config user.signingkey key_id`
@@ -258,6 +257,16 @@ class RepoConfig(object):
'sign-commit', 'sign-manifest', 'thin-manifest', 'update-changelog'):
setattr(self, value.lower().replace("-", "_"), layout_data[value])
+ # If profile-formats specifies a default EAPI, then set
+ # self.eapi to that, otherwise set it to "0" as specified
+ # by PMS.
+ self.eapi = layout_data.get(
+ 'profile_eapi_when_unspecified', '0')
+ eapi = read_corresponding_eapi_file(
+ os.path.join(self.location, REPO_NAME_LOC),
+ default=self.eapi)
self.portage1_profiles = eapi_allows_directories_on_profile_level_and_repository_level(eapi) or \
any(x in _portage1_profiles_allow_directories for x in layout_data['profile-formats'])
self.portage1_profiles_compat = not eapi_allows_directories_on_profile_level_and_repository_level(eapi) and \
@@ -1085,4 +1094,28 @@ def parse_layout_conf(repo_location, repo_name=None):
raw_formats = tuple(raw_formats.intersection(_valid_profile_formats))
data['profile-formats'] = raw_formats
+ try:
+ eapi = layout_data['profile_eapi_when_unspecified']
+ except KeyError:
+ pass
+ else:
+ if 'profile-default-eapi' not in raw_formats:
+ warnings.warn((_("Repository named '%(repo_name)s' has "
+ "profile_eapi_when_unspecified setting in "
+ "'%(layout_filename)s', but 'profile-default-eapi' is "
+ "not listed in the profile-formats field. Please "
+ "report this issue to the repository maintainer.") %
+ dict(repo_name=repo_name or 'unspecified',
+ layout_filename=layout_filename)),
+ SyntaxWarning)
+ elif not portage.eapi_is_supported(eapi):
+ warnings.warn((_("Repository named '%(repo_name)s' has "
+ "unsupported EAPI '%(eapi)s' setting in "
+ "'%(layout_filename)s'; please upgrade portage.") %
+ dict(repo_name=repo_name or 'unspecified',
+ eapi=eapi, layout_filename=layout_filename)),
+ SyntaxWarning)
+ else:
+ data['profile_eapi_when_unspecified'] = eapi
return data, layout_errors