def _check_var_directory(self, varname, var): if not isdir_raise_eaccess(var): writemsg( _("!!! Error: %s='%s' is not a directory. " "Please correct this.\n") % (varname, var), noiselevel=-1, ) raise DirectoryNotFound(var)
def _check_locations(self): """Check if repositories location are correct and show a warning message if not""" for (name, r) in self.prepos.items(): if name != 'DEFAULT': if r.location is None: writemsg(_("!!! Location not set for repository %s\n") % name, noiselevel=-1) else: if not isdir_raise_eaccess(r.location) and not portage._sync_mode: self.prepos_order.remove(name) writemsg(_("!!! Invalid Repository Location" " (not a dir): '%s'\n") % r.location, noiselevel=-1)
def set_port_dirs(self, portdir, portdir_overlay): self.portdir = portdir self.portdir_overlay = portdir_overlay if self.portdir_overlay is None: self.portdir_overlay = "" self.overlay_profiles = [] for ov in shlex_split(self.portdir_overlay): ov = normalize_path(ov) profiles_dir = os.path.join(ov, "profiles") if isdir_raise_eaccess(profiles_dir): self.overlay_profiles.append(profiles_dir) self.profile_locations = [os.path.join(portdir, "profiles")] + self.overlay_profiles self.profile_and_user_locations = self.profile_locations[:] if self._user_config: self.profile_and_user_locations.append(self.abs_user_config) self.profile_locations = tuple(self.profile_locations) self.profile_and_user_locations = tuple(self.profile_and_user_locations)
def __init__(self, paths, settings): """Load config from files in paths""" prepos = {} location_map = {} treemap = {} ignored_map = {} default_opts = { "EPREFIX" : settings["EPREFIX"], "EROOT" : settings["EROOT"], "PORTAGE_CONFIGROOT" : settings["PORTAGE_CONFIGROOT"], "ROOT" : settings["ROOT"], } if "PORTAGE_REPOSITORIES" in settings: portdir = "" portdir_overlay = "" # deprecated portdir_sync portdir_sync = "" else: portdir = settings.get("PORTDIR", "") portdir_overlay = settings.get("PORTDIR_OVERLAY", "") # deprecated portdir_sync portdir_sync = settings.get("SYNC", "") default_opts['sync-rsync-extra-opts'] = \ settings.get("PORTAGE_RSYNC_EXTRA_OPTS", "") try: self._parse(paths, prepos, settings.local_config, default_opts) except ConfigParserError as e: writemsg( _("!!! Error while reading repo config file: %s\n") % e, noiselevel=-1) # The configparser state is unreliable (prone to quirky # exceptions) after it has thrown an error, so use empty # config and try to fall back to PORTDIR{,_OVERLAY}. prepos.clear() prepos['DEFAULT'] = RepoConfig('DEFAULT', {}, local_config=settings.local_config) location_map.clear() treemap.clear() default_portdir = os.path.join(os.sep, settings['EPREFIX'].lstrip(os.sep), 'usr', 'portage') # If PORTDIR_OVERLAY contains a repo with the same repo_name as # PORTDIR, then PORTDIR is overridden. portdir = self._add_repositories(portdir, portdir_overlay, prepos, ignored_map, settings.local_config, default_portdir) if portdir and portdir.strip(): portdir = os.path.realpath(portdir) ignored_repos = tuple((repo_name, tuple(paths)) \ for repo_name, paths in ignored_map.items()) self.missing_repo_names = frozenset(repo.location for repo in prepos.values() if repo.location is not None and repo.missing_repo_name) # Do this before expanding aliases, so that location_map and # treemap consistently map unaliased names whenever available. for repo_name, repo in list(prepos.items()): if repo.location is None: if repo_name != 'DEFAULT': # Skip this warning for repoman (bug #474578). if settings.local_config and paths: writemsg_level("!!! %s\n" % _("Section '%s' in repos.conf is missing location attribute") % repo.name, level=logging.ERROR, noiselevel=-1) del prepos[repo_name] continue else: if not portage._sync_mode: if not isdir_raise_eaccess(repo.location): writemsg_level("!!! %s\n" % _("Section '%s' in repos.conf has location attribute set " "to nonexistent directory: '%s'") % (repo_name, repo.location), level=logging.ERROR, noiselevel=-1) # Ignore missing directory for 'gentoo' so that # first sync with emerge-webrsync is possible. if repo.name != 'gentoo': del prepos[repo_name] continue # After removing support for PORTDIR_OVERLAY, the following check can be: # if repo.missing_repo_name: if repo.missing_repo_name and repo.name != repo_name: writemsg_level("!!! %s\n" % _("Section '%s' in repos.conf refers to repository " "without repository name set in '%s'") % (repo_name, os.path.join(repo.location, REPO_NAME_LOC)), level=logging.ERROR, noiselevel=-1) del prepos[repo_name] continue if repo.name != repo_name: writemsg_level("!!! %s\n" % _("Section '%s' in repos.conf has name different " "from repository name '%s' set inside repository") % (repo_name, repo.name), level=logging.ERROR, noiselevel=-1) del prepos[repo_name] continue location_map[repo.location] = repo_name treemap[repo_name] = repo.location # Add alias mappings, but never replace unaliased mappings. for repo_name, repo in list(prepos.items()): names = set() names.add(repo_name) if repo.aliases: aliases = stack_lists([repo.aliases], incremental=True) names.update(aliases) for name in names: if name in prepos and prepos[name].location is not None: if name == repo_name: # unaliased names already handled earlier continue writemsg_level(_("!!! Repository name or alias '%s', " + \ "defined for repository '%s', overrides " + \ "existing alias or repository.\n") % (name, repo_name), level=logging.WARNING, noiselevel=-1) # Never replace an unaliased mapping with # an aliased mapping. continue prepos[name] = repo if repo.location is not None: if repo.location not in location_map: # Never replace an unaliased mapping with # an aliased mapping. location_map[repo.location] = name treemap[name] = repo.location main_repo = prepos['DEFAULT'].main_repo if main_repo is None or main_repo not in prepos: #setting main_repo if it was not set in repos.conf main_repo = location_map.get(portdir) if main_repo is not None: prepos['DEFAULT'].main_repo = main_repo else: prepos['DEFAULT'].main_repo = None if portdir and not portage._sync_mode: writemsg(_("!!! main-repo not set in DEFAULT and PORTDIR is empty.\n"), noiselevel=-1) if main_repo is not None and prepos[main_repo].priority is None: # This happens if main-repo has been set in repos.conf. prepos[main_repo].priority = -1000 # DEPRECATED Backward compatible SYNC support for old mirrorselect. # Feb. 2, 2015. Version 2.2.16 if portdir_sync and main_repo is not None: writemsg(_("!!! SYNC setting found in make.conf.\n " "This setting is Deprecated and no longer used. " "Please ensure your 'sync-type' and 'sync-uri' are set correctly" " in /etc/portage/repos.conf/gentoo.conf\n"), noiselevel=-1) # Include repo.name in sort key, for predictable sorting # even when priorities are equal. prepos_order = sorted(prepos.items(), key=lambda r:(r[1].priority or 0, r[1].name)) # filter duplicates from aliases, by only including # items where repo.name == key prepos_order = [repo.name for (key, repo) in prepos_order if repo.name == key and key != 'DEFAULT' and repo.location is not None] self.prepos = prepos self.prepos_order = prepos_order self.ignored_repos = ignored_repos self.location_map = location_map self.treemap = treemap self._prepos_changed = True self._repo_location_list = [] #The 'masters' key currently contains repo names. Replace them with the matching RepoConfig. for repo_name, repo in prepos.items(): if repo_name == "DEFAULT": continue if repo.masters is None: if self.mainRepo() and repo_name != self.mainRepo().name: repo.masters = self.mainRepo(), else: repo.masters = () else: if repo.masters and isinstance(repo.masters[0], RepoConfig): # This one has already been processed # because it has an alias. continue master_repos = [] for master_name in repo.masters: if master_name not in prepos: layout_filename = os.path.join(repo.location, "metadata", "layout.conf") writemsg_level(_("Unavailable repository '%s' " \ "referenced by masters entry in '%s'\n") % \ (master_name, layout_filename), level=logging.ERROR, noiselevel=-1) else: master_repos.append(prepos[master_name]) repo.masters = tuple(master_repos) #The 'eclass_overrides' key currently contains repo names. Replace them with the matching repo paths. for repo_name, repo in prepos.items(): if repo_name == "DEFAULT": continue eclass_locations = [] eclass_locations.extend(master_repo.location for master_repo in repo.masters) # Only append the current repo to eclass_locations if it's not # there already. This allows masters to have more control over # eclass override order, which may be useful for scenarios in # which there is a plan to migrate eclasses to a master repo. if repo.location not in eclass_locations: eclass_locations.append(repo.location) if repo.eclass_overrides: for other_repo_name in repo.eclass_overrides: if other_repo_name in self.treemap: eclass_locations.append(self.get_location_for_name(other_repo_name)) else: writemsg_level(_("Unavailable repository '%s' " \ "referenced by eclass-overrides entry for " \ "'%s'\n") % (other_repo_name, repo_name), \ level=logging.ERROR, noiselevel=-1) repo.eclass_locations = tuple(eclass_locations) eclass_dbs = {} for repo_name, repo in prepos.items(): if repo_name == "DEFAULT": continue eclass_db = None for eclass_location in repo.eclass_locations: tree_db = eclass_dbs.get(eclass_location) if tree_db is None: tree_db = eclass_cache.cache(eclass_location) eclass_dbs[eclass_location] = tree_db if eclass_db is None: eclass_db = tree_db.copy() else: eclass_db.append(tree_db) repo.eclass_db = eclass_db for repo_name, repo in prepos.items(): if repo_name == "DEFAULT": continue if repo._masters_orig is None and self.mainRepo() and \ repo.name != self.mainRepo().name and not portage._sync_mode: # TODO: Delete masters code in pym/portage/tests/resolver/ResolverPlayground.py when deleting this warning. writemsg_level("!!! %s\n" % _("Repository '%s' is missing masters attribute in '%s'") % (repo.name, os.path.join(repo.location, "metadata", "layout.conf")) + "!!! %s\n" % _("Set 'masters = %s' in this file for future compatibility") % self.mainRepo().name, level=logging.WARNING, noiselevel=-1) self._prepos_changed = True self._repo_location_list = [] self._check_locations()
def _add_repositories(portdir, portdir_overlay, prepos, ignored_map, local_config, default_portdir): """Add overlays in PORTDIR_OVERLAY as repositories""" overlays = [] portdir_orig = None if portdir: portdir = normalize_path(portdir) portdir_orig = portdir overlays.append(portdir) try: port_ov = [normalize_path(i) for i in shlex_split(portdir_overlay)] except ValueError as e: #File "/usr/lib/python3.2/shlex.py", line 168, in read_token # raise ValueError("No closing quotation") writemsg(_("!!! Invalid PORTDIR_OVERLAY:" " %s: %s\n") % (e, portdir_overlay), noiselevel=-1) port_ov = [] overlays.extend(port_ov) default_repo_opts = {} if prepos['DEFAULT'].aliases is not None: default_repo_opts['aliases'] = \ ' '.join(prepos['DEFAULT'].aliases) if prepos['DEFAULT'].eclass_overrides is not None: default_repo_opts['eclass-overrides'] = \ ' '.join(prepos['DEFAULT'].eclass_overrides) if prepos['DEFAULT'].masters is not None: default_repo_opts['masters'] = \ ' '.join(prepos['DEFAULT'].masters) if overlays: # We need a copy of the original repos.conf data, since we're # going to modify the prepos dict and some of the RepoConfig # objects that we put in prepos may have to be discarded if # they get overridden by a repository with the same name but # a different location. This is common with repoman, for example, # when temporarily overriding an rsync repo with another copy # of the same repo from CVS. repos_conf = prepos.copy() #overlay priority is negative because we want them to be looked before any other repo base_priority = 0 for ov in overlays: # Ignore missing directory for 'gentoo' so that # first sync with emerge-webrsync is possible. if isdir_raise_eaccess(ov) or \ (base_priority == 0 and ov is portdir): repo_opts = default_repo_opts.copy() repo_opts['location'] = ov repo = RepoConfig(None, repo_opts, local_config=local_config) # repos_conf_opts contains options from repos.conf repos_conf_opts = repos_conf.get(repo.name) if repos_conf_opts is not None: # Selectively copy only the attributes which # repos.conf is allowed to override. for k in ('aliases', 'auto_sync', 'clone_depth', 'eclass_overrides', 'force', 'masters', 'priority', 'strict_misc_digests', 'sync_depth', 'sync_hooks_only_on_change', 'sync_openpgp_key_path', 'sync_openpgp_key_refresh_retry_count', 'sync_openpgp_key_refresh_retry_delay_max', 'sync_openpgp_key_refresh_retry_delay_exp_base', 'sync_openpgp_key_refresh_retry_delay_mult', 'sync_openpgp_key_refresh_retry_overall_timeout', 'sync_type', 'sync_umask', 'sync_uri', 'sync_user', 'module_specific_options'): v = getattr(repos_conf_opts, k, None) if v is not None: setattr(repo, k, v) if repo.name in prepos: # Silently ignore when PORTDIR overrides the location # setting from the default repos.conf (bug #478544). old_location = prepos[repo.name].location if old_location is not None and \ old_location != repo.location and \ not (base_priority == 0 and old_location == default_portdir): ignored_map.setdefault(repo.name, []).append(old_location) if old_location == portdir: portdir = repo.location if repo.priority is None: if base_priority == 0 and ov == portdir_orig: # If it's the original PORTDIR setting and it's not # in PORTDIR_OVERLAY, then it will be assigned a # special priority setting later. pass else: repo.priority = base_priority base_priority += 1 prepos[repo.name] = repo else: if not portage._sync_mode: writemsg(_("!!! Invalid PORTDIR_OVERLAY (not a dir): '%s'\n") % ov, noiselevel=-1) return portdir
def load_profiles(self, repositories, known_repository_paths): known_repository_paths = set( os.path.realpath(x) for x in known_repository_paths) known_repos = [] for x in known_repository_paths: try: repo = repositories.get_repo_for_location(x) except KeyError: layout_data = parse_layout_conf(x)[0] else: layout_data = { "profile-formats": repo.profile_formats, "profile_eapi_when_unspecified": repo.eapi } # force a trailing '/' for ease of doing startswith checks known_repos.append((x + '/', layout_data)) known_repos = tuple(known_repos) if self.config_profile_path is None: deprecated_profile_path = os.path.join(self.config_root, 'etc', 'make.profile') self.config_profile_path = \ os.path.join(self.config_root, PROFILE_PATH) if isdir_raise_eaccess(self.config_profile_path): self.profile_path = self.config_profile_path if isdir_raise_eaccess(deprecated_profile_path) and not \ os.path.samefile(self.profile_path, deprecated_profile_path): # Don't warn if they refer to the same path, since # that can be used for backward compatibility with # old software. writemsg("!!! %s\n" % _("Found 2 make.profile dirs: " "using '%s', ignoring '%s'") % (self.profile_path, deprecated_profile_path), noiselevel=-1) else: self.config_profile_path = deprecated_profile_path if isdir_raise_eaccess(self.config_profile_path): self.profile_path = self.config_profile_path else: self.profile_path = None else: # NOTE: repoman may pass in an empty string # here, in order to create an empty profile # for checking dependencies of packages with # empty KEYWORDS. 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), repositories, known_repos) except ParseError as e: if not portage._sync_mode: writemsg(_("!!! Unable to parse profile: '%s'\n") % self.profile_path, noiselevel=-1) writemsg("!!! ParseError: %s\n" % str(e), noiselevel=-1) self.profiles = [] self.profiles_complex = [] if self._user_config and self.profiles: custom_prof = os.path.join(self.config_root, CUSTOM_PROFILE_PATH) if os.path.exists(custom_prof): # For read_corresponding_eapi_file, specify default=None # in order to allow things like wildcard atoms when # is no explicit EAPI setting. self.user_profile_dir = custom_prof self.profiles.append(custom_prof) self.profiles_complex.append( _profile_node( custom_prof, True, True, ('profile-bashrcs', 'profile-set'), read_corresponding_eapi_file(custom_prof + os.sep, default=None), True)) del custom_prof self.profiles = tuple(self.profiles) self.profiles_complex = tuple(self.profiles_complex)
def load_profiles(self, repositories, known_repository_paths): known_repository_paths = set(os.path.realpath(x) for x in known_repository_paths) known_repos = [] for x in known_repository_paths: try: layout_data = {"profile-formats": repositories.get_repo_for_location(x).profile_formats} except KeyError: layout_data = parse_layout_conf(x)[0] # force a trailing '/' for ease of doing startswith checks known_repos.append((x + '/', layout_data)) known_repos = tuple(known_repos) if self.config_profile_path is None: deprecated_profile_path = os.path.join( self.config_root, 'etc', 'make.profile') self.config_profile_path = \ os.path.join(self.config_root, PROFILE_PATH) if isdir_raise_eaccess(self.config_profile_path): self.profile_path = self.config_profile_path if isdir_raise_eaccess(deprecated_profile_path) and not \ os.path.samefile(self.profile_path, deprecated_profile_path): # Don't warn if they refer to the same path, since # that can be used for backward compatibility with # old software. writemsg("!!! %s\n" % _("Found 2 make.profile dirs: " "using '%s', ignoring '%s'") % (self.profile_path, deprecated_profile_path), noiselevel=-1) else: self.config_profile_path = deprecated_profile_path if isdir_raise_eaccess(self.config_profile_path): self.profile_path = self.config_profile_path else: self.profile_path = None else: # NOTE: repoman may pass in an empty string # here, in order to create an empty profile # for checking dependencies of packages with # empty KEYWORDS. 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), repositories, known_repos) except ParseError as e: if not portage._sync_disabled_warnings: writemsg(_("!!! Unable to parse profile: '%s'\n") % self.profile_path, noiselevel=-1) writemsg("!!! ParseError: %s\n" % str(e), noiselevel=-1) self.profiles = [] self.profiles_complex = [] if self._user_config and self.profiles: custom_prof = os.path.join( self.config_root, CUSTOM_PROFILE_PATH) if os.path.exists(custom_prof): self.user_profile_dir = custom_prof self.profiles.append(custom_prof) self.profiles_complex.append( _profile_node(custom_prof, True, 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 isdir_raise_eaccess(var): writemsg(_("!!! Error: %s='%s' is not a directory. " "Please correct this.\n") % (varname, var), noiselevel=-1) raise DirectoryNotFound(var)
def __init__(self, paths, settings): """Load config from files in paths""" prepos = {} location_map = {} treemap = {} ignored_map = {} default_opts = { "EPREFIX": settings["EPREFIX"], "EROOT": settings["EROOT"], "PORTAGE_CONFIGROOT": settings["PORTAGE_CONFIGROOT"], "ROOT": settings["ROOT"], } if "PORTAGE_REPOSITORIES" in settings: portdir = "" portdir_overlay = "" # deprecated portdir_sync portdir_sync = "" else: portdir = settings.get("PORTDIR", "") portdir_overlay = settings.get("PORTDIR_OVERLAY", "") # deprecated portdir_sync portdir_sync = settings.get("SYNC", "") default_opts['sync-rsync-extra-opts'] = \ settings.get("PORTAGE_RSYNC_EXTRA_OPTS", None) try: self._parse(paths, prepos, settings.local_config, default_opts) except ConfigParserError as e: writemsg(_("!!! Error while reading repo config file: %s\n") % e, noiselevel=-1) # The configparser state is unreliable (prone to quirky # exceptions) after it has thrown an error, so use empty # config and try to fall back to PORTDIR{,_OVERLAY}. prepos.clear() prepos['DEFAULT'] = RepoConfig('DEFAULT', {}, local_config=settings.local_config) location_map.clear() treemap.clear() default_portdir = os.path.join(os.sep, settings['EPREFIX'].lstrip(os.sep), 'usr', 'portage') # If PORTDIR_OVERLAY contains a repo with the same repo_name as # PORTDIR, then PORTDIR is overridden. portdir = self._add_repositories(portdir, portdir_overlay, prepos, ignored_map, settings.local_config, default_portdir) if portdir and portdir.strip(): portdir = os.path.realpath(portdir) ignored_repos = tuple((repo_name, tuple(paths)) \ for repo_name, paths in ignored_map.items()) self.missing_repo_names = frozenset( repo.location for repo in prepos.values() if repo.location is not None and repo.missing_repo_name) # Do this before expanding aliases, so that location_map and # treemap consistently map unaliased names whenever available. for repo_name, repo in list(prepos.items()): if repo.location is None: if repo_name != 'DEFAULT': # Skip this warning for repoman (bug #474578). if settings.local_config and paths: writemsg_level("!!! %s\n" % _( "Section '%s' in repos.conf is missing location attribute" ) % repo.name, level=logging.ERROR, noiselevel=-1) del prepos[repo_name] continue else: if not portage._sync_mode: if not isdir_raise_eaccess(repo.location): writemsg_level("!!! %s\n" % _( "Section '%s' in repos.conf has location attribute set " "to nonexistent directory: '%s'") % (repo_name, repo.location), level=logging.ERROR, noiselevel=-1) # Ignore missing directory for 'gentoo' so that # first sync with emerge-webrsync is possible. if repo.name != 'gentoo': del prepos[repo_name] continue # After removing support for PORTDIR_OVERLAY, the following check can be: # if repo.missing_repo_name: if repo.missing_repo_name and repo.name != repo_name: writemsg_level("!!! %s\n" % _( "Section '%s' in repos.conf refers to repository " "without repository name set in '%s'") % (repo_name, os.path.join(repo.location, REPO_NAME_LOC)), level=logging.ERROR, noiselevel=-1) del prepos[repo_name] continue if repo.name != repo_name: writemsg_level("!!! %s\n" % _( "Section '%s' in repos.conf has name different " "from repository name '%s' set inside repository") % (repo_name, repo.name), level=logging.ERROR, noiselevel=-1) del prepos[repo_name] continue location_map[repo.location] = repo_name treemap[repo_name] = repo.location # Add alias mappings, but never replace unaliased mappings. for repo_name, repo in list(prepos.items()): names = set() names.add(repo_name) if repo.aliases: aliases = stack_lists([repo.aliases], incremental=True) names.update(aliases) for name in names: if name in prepos and prepos[name].location is not None: if name == repo_name: # unaliased names already handled earlier continue writemsg_level(_("!!! Repository name or alias '%s', " + \ "defined for repository '%s', overrides " + \ "existing alias or repository.\n") % (name, repo_name), level=logging.WARNING, noiselevel=-1) # Never replace an unaliased mapping with # an aliased mapping. continue prepos[name] = repo if repo.location is not None: if repo.location not in location_map: # Never replace an unaliased mapping with # an aliased mapping. location_map[repo.location] = name treemap[name] = repo.location main_repo = prepos['DEFAULT'].main_repo if main_repo is None or main_repo not in prepos: #setting main_repo if it was not set in repos.conf main_repo = location_map.get(portdir) if main_repo is not None: prepos['DEFAULT'].main_repo = main_repo else: prepos['DEFAULT'].main_repo = None if portdir and not portage._sync_mode: writemsg(_( "!!! main-repo not set in DEFAULT and PORTDIR is empty.\n" ), noiselevel=-1) if main_repo is not None and prepos[main_repo].priority is None: # This happens if main-repo has been set in repos.conf. prepos[main_repo].priority = -1000 # DEPRECATED Backward compatible SYNC support for old mirrorselect. # Feb. 2, 2015. Version 2.2.16 if portdir_sync and main_repo is not None: writemsg(_( "!!! SYNC setting found in make.conf.\n " "This setting is Deprecated and no longer used. " "Please ensure your 'sync-type' and 'sync-uri' are set correctly" " in /etc/portage/repos.conf/gentoo.conf\n"), noiselevel=-1) # Include repo.name in sort key, for predictable sorting # even when priorities are equal. prepos_order = sorted(prepos.items(), key=lambda r: (r[1].priority or 0, r[1].name)) # filter duplicates from aliases, by only including # items where repo.name == key prepos_order = [ repo.name for (key, repo) in prepos_order if repo.name == key and key != 'DEFAULT' and repo.location is not None ] self.prepos = prepos self.prepos_order = prepos_order self.ignored_repos = ignored_repos self.location_map = location_map self.treemap = treemap self._prepos_changed = True self._repo_location_list = [] #The 'masters' key currently contains repo names. Replace them with the matching RepoConfig. for repo_name, repo in prepos.items(): if repo_name == "DEFAULT": continue if repo.masters is None: if self.mainRepo() and repo_name != self.mainRepo().name: repo.masters = self.mainRepo(), else: repo.masters = () else: if repo.masters and isinstance(repo.masters[0], RepoConfig): # This one has already been processed # because it has an alias. continue master_repos = [] for master_name in repo.masters: if master_name not in prepos: layout_filename = os.path.join(repo.location, "metadata", "layout.conf") writemsg_level(_("Unavailable repository '%s' " \ "referenced by masters entry in '%s'\n") % \ (master_name, layout_filename), level=logging.ERROR, noiselevel=-1) else: master_repos.append(prepos[master_name]) repo.masters = tuple(master_repos) #The 'eclass_overrides' key currently contains repo names. Replace them with the matching repo paths. for repo_name, repo in prepos.items(): if repo_name == "DEFAULT": continue eclass_locations = [] eclass_locations.extend(master_repo.location for master_repo in repo.masters) # Only append the current repo to eclass_locations if it's not # there already. This allows masters to have more control over # eclass override order, which may be useful for scenarios in # which there is a plan to migrate eclasses to a master repo. if repo.location not in eclass_locations: eclass_locations.append(repo.location) if repo.eclass_overrides: for other_repo_name in repo.eclass_overrides: if other_repo_name in self.treemap: eclass_locations.append( self.get_location_for_name(other_repo_name)) else: writemsg_level(_("Unavailable repository '%s' " \ "referenced by eclass-overrides entry for " \ "'%s'\n") % (other_repo_name, repo_name), \ level=logging.ERROR, noiselevel=-1) repo.eclass_locations = tuple(eclass_locations) eclass_dbs = {} for repo_name, repo in prepos.items(): if repo_name == "DEFAULT": continue eclass_db = None for eclass_location in repo.eclass_locations: tree_db = eclass_dbs.get(eclass_location) if tree_db is None: tree_db = eclass_cache.cache(eclass_location) eclass_dbs[eclass_location] = tree_db if eclass_db is None: eclass_db = tree_db.copy() else: eclass_db.append(tree_db) repo.eclass_db = eclass_db for repo_name, repo in prepos.items(): if repo_name == "DEFAULT": continue if repo._masters_orig is None and self.mainRepo() and \ repo.name != self.mainRepo().name and not portage._sync_mode: # TODO: Delete masters code in pym/portage/tests/resolver/ResolverPlayground.py when deleting this warning. writemsg_level( "!!! %s\n" % _("Repository '%s' is missing masters attribute in '%s'") % (repo.name, os.path.join(repo.location, "metadata", "layout.conf")) + "!!! %s\n" % _("Set 'masters = %s' in this file for future compatibility" ) % self.mainRepo().name, level=logging.WARNING, noiselevel=-1) self._prepos_changed = True self._repo_location_list = [] self._check_locations()
def _add_repositories(portdir, portdir_overlay, prepos, ignored_map, local_config, default_portdir): """Add overlays in PORTDIR_OVERLAY as repositories""" overlays = [] portdir_orig = None if portdir: portdir = normalize_path(portdir) portdir_orig = portdir overlays.append(portdir) try: port_ov = [normalize_path(i) for i in shlex_split(portdir_overlay)] except ValueError as e: #File "/usr/lib/python3.2/shlex.py", line 168, in read_token # raise ValueError("No closing quotation") writemsg(_("!!! Invalid PORTDIR_OVERLAY:" " %s: %s\n") % (e, portdir_overlay), noiselevel=-1) port_ov = [] overlays.extend(port_ov) default_repo_opts = {} if prepos['DEFAULT'].aliases is not None: default_repo_opts['aliases'] = \ ' '.join(prepos['DEFAULT'].aliases) if prepos['DEFAULT'].eclass_overrides is not None: default_repo_opts['eclass-overrides'] = \ ' '.join(prepos['DEFAULT'].eclass_overrides) if prepos['DEFAULT'].masters is not None: default_repo_opts['masters'] = \ ' '.join(prepos['DEFAULT'].masters) if overlays: # We need a copy of the original repos.conf data, since we're # going to modify the prepos dict and some of the RepoConfig # objects that we put in prepos may have to be discarded if # they get overridden by a repository with the same name but # a different location. This is common with repoman, for example, # when temporarily overriding an rsync repo with another copy # of the same repo from CVS. repos_conf = prepos.copy() #overlay priority is negative because we want them to be looked before any other repo base_priority = 0 for ov in overlays: # Ignore missing directory for 'gentoo' so that # first sync with emerge-webrsync is possible. if isdir_raise_eaccess(ov) or \ (base_priority == 0 and ov is portdir): repo_opts = default_repo_opts.copy() repo_opts['location'] = ov repo = RepoConfig(None, repo_opts, local_config=local_config) # repos_conf_opts contains options from repos.conf repos_conf_opts = repos_conf.get(repo.name) if repos_conf_opts is not None: # Selectively copy only the attributes which # repos.conf is allowed to override. for k in ('aliases', 'auto_sync', 'eclass_overrides', 'force', 'masters', 'priority', 'sync_depth', 'sync_hooks_only_on_change', 'sync_type', 'sync_umask', 'sync_uri', 'sync_user', 'module_specific_options'): v = getattr(repos_conf_opts, k, None) if v is not None: setattr(repo, k, v) if repo.name in prepos: # Silently ignore when PORTDIR overrides the location # setting from the default repos.conf (bug #478544). old_location = prepos[repo.name].location if old_location is not None and \ old_location != repo.location and \ not (base_priority == 0 and old_location == default_portdir): ignored_map.setdefault(repo.name, []).append(old_location) if old_location == portdir: portdir = repo.location if repo.priority is None: if base_priority == 0 and ov == portdir_orig: # If it's the original PORTDIR setting and it's not # in PORTDIR_OVERLAY, then it will be assigned a # special priority setting later. pass else: repo.priority = base_priority base_priority += 1 prepos[repo.name] = repo else: if not portage._sync_mode: writemsg( _("!!! Invalid PORTDIR_OVERLAY (not a dir): '%s'\n" ) % ov, noiselevel=-1) return portdir