from portage.localization import _
from portage.util import ensure_dirs, grabfile, \
normalize_path, shlex_split, writemsg
+from portage.repository.config import parse_layout_conf
+_PORTAGE1_DIRECTORIES = frozenset([
+ 'package.mask', 'package.provided',
+ 'package.use', 'package.use.mask', 'package.use.force',
+ 'use.mask', 'use.force'])
+
class LocationsManager(object):
def __init__(self, config_root=None, eprefix=None, config_profile_path=None, local_config=True, \
self._check_var_directory("PORTAGE_CONFIGROOT", self.config_root)
self.abs_user_config = os.path.join(self.config_root, USER_CONFIG_PATH)
+ self.config_profile_path = config_profile_path
+
+ def load_profiles(self, known_repository_paths):
+ known_repos = [os.path.abspath(x) for x in set(known_repository_paths)]
+ # force a trailing '/' for ease of doing startswith checks
+ known_repos = [(x + '/', parse_layout_conf(x)[0]) for x in known_repos]
- if config_profile_path is None:
- config_profile_path = \
+ if self.config_profile_path is None:
+ self.config_profile_path = \
os.path.join(self.config_root, PROFILE_PATH)
- if os.path.isdir(config_profile_path):
- self.profile_path = config_profile_path
+ if os.path.isdir(self.config_profile_path):
+ self.profile_path = self.config_profile_path
else:
- config_profile_path = \
+ self.config_profile_path = \
os.path.join(self.abs_user_config, 'make.profile')
- if os.path.isdir(config_profile_path):
- self.profile_path = config_profile_path
+ if os.path.isdir(self.config_profile_path):
+ self.profile_path = self.config_profile_path
else:
self.profile_path = None
else:
# here, in order to create an empty profile
# for checking dependencies of packages with
# empty KEYWORDS.
- self.profile_path = config_profile_path
+ self.profile_path = self.config_profile_path
# The symlink might not exist or might not be a symlink.
self.profiles = []
+ self.profiles_complex = []
if self.profile_path:
try:
- self._addProfile(os.path.realpath(self.profile_path))
+ self._addProfile(os.path.realpath(self.profile_path),
+ known_repos)
except ParseError as e:
writemsg(_("!!! Unable to parse profile: '%s'\n") % \
self.profile_path, noiselevel=-1)
if os.path.exists(custom_prof):
self.user_profile_dir = custom_prof
self.profiles.append(custom_prof)
+ self.profiles_complex.append((custom_prof, True))
del custom_prof
self.profiles = tuple(self.profiles)
+ self.profiles_complex = tuple(self.profiles_complex)
def _check_var_directory(self, varname, var):
if not os.path.isdir(var):
noiselevel=-1)
raise DirectoryNotFound(var)
- def _addProfile(self, currentPath):
+ def _addProfile(self, currentPath, known_repos):
+ current_abs_path = os.path.abspath(currentPath)
+ allow_directories = True
+ compat_mode = False
+ intersecting_repos = [x for x in known_repos if current_abs_path.startswith(x[0])]
+ if intersecting_repos:
+ # protect against nested repositories. Insane configuration, but the longest
+ # path will be the correct one.
+ repo_loc, layout_data = max(intersecting_repos, key=lambda x:len(x[0]))
+ allow_directories = any(x.startswith("portage-1")
+ for x in layout_data['profile-formats'])
+ compat_mode = layout_data['profile-formats'] == ('portage-1-compat',)
+
+ if compat_mode:
+ offenders = _PORTAGE1_DIRECTORIES.intersection(os.listdir(currentPath))
+ offenders = sorted(x for x in offenders
+ if os.path.isdir(os.path.join(currentPath, x)))
+ if offenders:
+ writemsg((_("Profile '%(profile_path)s' in repository "
+ "'%(repo_name)s' is using 'portage-1' profile format, but "
+ "the repository is not configured for it. This will break "
+ "in the future. Please either convert the following paths "
+ "to files, or add\nprofile-format = portage-1\nto the "
+ "repositories layout.conf. Files: '%(files)s'\n")
+ % dict(profile_path=currentPath, repo_name=repo_loc,
+ files=', '.join(offenders))),
+ noiselevel=-1)
+
parentsFile = os.path.join(currentPath, "parent")
eapi_file = os.path.join(currentPath, "eapi")
f = None
parentPath = normalize_path(os.path.join(
currentPath, parentPath))
if os.path.exists(parentPath):
- self._addProfile(parentPath)
+ self._addProfile(parentPath, known_repos)
else:
raise ParseError(
_("Parent '%s' not found: '%s'") % \
(parentPath, parentsFile))
+
self.profiles.append(currentPath)
+ self.profiles_complex.append((currentPath, allow_directories))
def set_root_override(self, root_overwrite=None):
# Allow ROOT setting to come from make.conf if it's not overridden