def __init__(self, pmask_locations, abs_user_config, user_config=True): self._punmaskdict = ExtendedAtomDict(list) self._pmaskdict = ExtendedAtomDict(list) pkgmasklines = [] pkgunmasklines = [] for x in pmask_locations: pkgmasklines.append( grabfile_package(os.path.join(x, "package.mask"), recursive=1)) pkgunmasklines.append( grabfile_package(os.path.join(x, "package.unmask"), recursive=1)) if user_config: pkgmasklines.append( grabfile_package(os.path.join(abs_user_config, "package.mask"), recursive=1, allow_wildcard=True)) pkgunmasklines.append( grabfile_package(os.path.join(abs_user_config, "package.unmask"), recursive=1, allow_wildcard=True)) pkgmasklines = stack_lists(pkgmasklines, incremental=1) pkgunmasklines = stack_lists(pkgunmasklines, incremental=1) for x in pkgmasklines: self._pmaskdict.setdefault(x.cp, []).append(x) for x in pkgunmasklines: self._punmaskdict.setdefault(x.cp, []).append(x)
def _parse_user_files_to_extatomdict(self, file_name, location, user_config): ret = ExtendedAtomDict(dict) if user_config: pusedict = grabdict_package(os.path.join(location, file_name), recursive=1, newlines=1, allow_wildcard=True, allow_repo=True, verify_eapi=False, allow_build_id=True, allow_use=False) for k, v in pusedict.items(): l = [] use_expand_prefix = '' for flag in v: if flag == "\n": use_expand_prefix = "" continue if flag[-1] == ":": use_expand_prefix = flag[:-1].lower() + "_" continue if flag[0] == "-": nv = "-" + use_expand_prefix + flag[1:] else: nv = use_expand_prefix + flag l.append(nv) ret.setdefault(k.cp, {})[k] = tuple(l) return ret
def __init__(self, profiles, abs_user_config, user_config=True, global_accept_keywords=""): self._pkeywords_list = [] rawpkeywords = [grabdict_package( os.path.join(x.location, "package.keywords"), recursive=x.portage1_directories, verify_eapi=True, eapi=x.eapi, eapi_default=None, allow_build_id=x.allow_build_id) for x in profiles] for pkeyworddict in rawpkeywords: if not pkeyworddict: # Omit non-existent files from the stack. continue cpdict = {} for k, v in pkeyworddict.items(): cpdict.setdefault(k.cp, {})[k] = v self._pkeywords_list.append(cpdict) self._pkeywords_list = tuple(self._pkeywords_list) self._p_accept_keywords = [] raw_p_accept_keywords = [grabdict_package( os.path.join(x.location, "package.accept_keywords"), recursive=x.portage1_directories, verify_eapi=True, eapi=x.eapi, eapi_default=None) for x in profiles] for d in raw_p_accept_keywords: if not d: # Omit non-existent files from the stack. continue cpdict = {} for k, v in d.items(): cpdict.setdefault(k.cp, {})[k] = tuple(v) self._p_accept_keywords.append(cpdict) self._p_accept_keywords = tuple(self._p_accept_keywords) self.pkeywordsdict = ExtendedAtomDict(dict) if user_config: pkgdict = grabdict_package( os.path.join(abs_user_config, "package.keywords"), recursive=1, allow_wildcard=True, allow_repo=True, verify_eapi=False) for k, v in grabdict_package( os.path.join(abs_user_config, "package.accept_keywords"), recursive=1, allow_wildcard=True, allow_repo=True, verify_eapi=False).items(): pkgdict.setdefault(k, []).extend(v) accept_keywords_defaults = global_accept_keywords.split() accept_keywords_defaults = tuple('~' + keyword for keyword in \ accept_keywords_defaults if keyword[:1] not in "~-") for k, v in pkgdict.items(): # default to ~arch if no specific keyword is given if not v: v = accept_keywords_defaults else: v = tuple(v) self.pkeywordsdict.setdefault(k.cp, {})[k] = v
def __init__(self): self._atoms = set() self._atommap = ExtendedAtomDict(set) self._loaded = False self._loading = False self.errors = [] self._nonatoms = set() self.world_candidate = False
def _parse_user_files_to_extatomdict(self, file_name, location, user_config): ret = ExtendedAtomDict(dict) if user_config: pusedict = grabdict_package( os.path.join(location, file_name), recursive=1, allow_wildcard=True, allow_repo=True, verify_eapi=False) for k, v in pusedict.items(): ret.setdefault(k.cp, {})[k] = tuple(v) return ret
def __init__(self, allow_wildcard=False, allow_repo=False): self._atoms = set() self._atommap = ExtendedAtomDict(set) self._loaded = False self._loading = False self.errors = [] self._nonatoms = set() self.world_candidate = False self._allow_wildcard = allow_wildcard self._allow_repo = allow_repo
def testExtendedAtomDict(self): d = ExtendedAtomDict(dict) d["*/*"] = {"test1": "x"} d["dev-libs/*"] = {"test2": "y"} d.setdefault("sys-apps/portage", {})["test3"] = "z" self.assertEqual(d.get("dev-libs/A"), {"test1": "x", "test2": "y"}) self.assertEqual(d.get("sys-apps/portage"), { "test1": "x", "test3": "z" }) self.assertEqual(d["dev-libs/*"], {"test2": "y"}) self.assertEqual(d["sys-apps/portage"], {'test1': 'x', 'test3': 'z'})
def _parse_file_to_dict(self, file_name, juststrings=False, recursive=True, eapi_filter=None, user_config=False): ret = {} location_dict = {} eapi = read_corresponding_eapi_file(file_name, default=None) if eapi is None and not user_config: eapi = "0" if eapi is None: ret = ExtendedAtomDict(dict) else: ret = {} file_dict = grabdict_package(file_name, recursive=recursive, allow_wildcard=(eapi is None), allow_repo=(eapi is None), verify_eapi=(eapi is not None)) if eapi is not None and eapi_filter is not None and not eapi_filter( eapi): if file_dict: writemsg(_("--- EAPI '%s' does not support '%s': '%s'\n") % (eapi, os.path.basename(file_name), file_name), noiselevel=-1) return ret useflag_re = _get_useflag_re(eapi) for k, v in file_dict.items(): useflags = [] for prefixed_useflag in v: if prefixed_useflag[:1] == "-": useflag = prefixed_useflag[1:] else: useflag = prefixed_useflag if useflag_re.match(useflag) is None: writemsg( _("--- Invalid USE flag for '%s' in '%s': '%s'\n") % (k, file_name, prefixed_useflag), noiselevel=-1) else: useflags.append(prefixed_useflag) location_dict.setdefault(k, []).extend(useflags) for k, v in location_dict.items(): if juststrings: v = " ".join(v) else: v = tuple(v) ret.setdefault(k.cp, {})[k] = v return ret
def __init__(self, license_group_locations, abs_user_config, user_config=True): self._accept_license_str = None self._accept_license = None self._license_groups = {} self._plicensedict = ExtendedAtomDict(dict) self._undef_lic_groups = set() if user_config: license_group_locations = list(license_group_locations) + [abs_user_config] self._read_license_groups(license_group_locations) if user_config: self._read_user_config(abs_user_config)
def _parse_file_to_dict(self, file_name, juststrings=False, recursive=True, eapi_filter=None, user_config=False, eapi=None, eapi_default="0", allow_build_id=False): """ @param file_name: input file name @type file_name: str @param juststrings: store dict values as space-delimited strings instead of tuples @type juststrings: bool @param recursive: triggers recursion if the input file is a directory @type recursive: bool @param eapi_filter: a function that accepts a single eapi argument, and returns true if the the current file type is supported by the given EAPI @type eapi_filter: callable @param user_config: current file is part of the local configuration (not repository content) @type user_config: bool @param eapi: the EAPI of the current profile node, which allows a call to read_corresponding_eapi_file to be skipped @type eapi: str @param eapi_default: the default EAPI which applies if the current profile node does not define a local EAPI @type eapi_default: str @param allow_build_id: allow atoms to specify a particular build-id @type allow_build_id: bool @rtype: tuple @return: collection of USE flags """ ret = {} location_dict = {} if eapi is None: eapi = read_corresponding_eapi_file(file_name, default=eapi_default) extended_syntax = eapi is None and user_config if extended_syntax: ret = ExtendedAtomDict(dict) else: ret = {} file_dict = grabdict_package(file_name, recursive=recursive, allow_wildcard=extended_syntax, allow_repo=extended_syntax, verify_eapi=(not extended_syntax), eapi=eapi, eapi_default=eapi_default, allow_build_id=allow_build_id, allow_use=False) if eapi is not None and eapi_filter is not None and not eapi_filter( eapi): if file_dict: writemsg(_("--- EAPI '%s' does not support '%s': '%s'\n") % (eapi, os.path.basename(file_name), file_name), noiselevel=-1) return ret useflag_re = _get_useflag_re(eapi) for k, v in file_dict.items(): useflags = [] use_expand_prefix = '' for prefixed_useflag in v: if extended_syntax and prefixed_useflag == "\n": use_expand_prefix = "" continue if extended_syntax and prefixed_useflag[-1] == ":": use_expand_prefix = prefixed_useflag[:-1].lower() + "_" continue if prefixed_useflag[:1] == "-": useflag = use_expand_prefix + prefixed_useflag[1:] prefixed_useflag = "-" + useflag else: useflag = use_expand_prefix + prefixed_useflag prefixed_useflag = useflag if useflag_re.match(useflag) is None: writemsg( _("--- Invalid USE flag for '%s' in '%s': '%s'\n") % (k, file_name, prefixed_useflag), noiselevel=-1) else: useflags.append(prefixed_useflag) location_dict.setdefault(k, []).extend(useflags) for k, v in location_dict.items(): if juststrings: v = " ".join(v) else: v = tuple(v) ret.setdefault(k.cp, {})[k] = v return ret
def __init__(self, repositories, profiles, abs_user_config, user_config=True, strict_umatched_removal=False): self._punmaskdict = ExtendedAtomDict(list) self._pmaskdict = ExtendedAtomDict(list) # Preserves atoms that are eliminated by negative # incrementals in user_pkgmasklines. self._pmaskdict_raw = ExtendedAtomDict(list) #Read profile/package.mask from 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. # Cache the repository-wide package.mask files as a particular # repo may be often referenced by others as the master. pmask_cache = {} def grab_pmask(loc, repo_config): if loc not in pmask_cache: path = os.path.join(loc, 'profiles', 'package.mask') pmask_cache[loc] = grabfile_package( path, recursive=repo_config.portage1_profiles, remember_source_file=True, verify_eapi=True) if repo_config.portage1_profiles_compat and os.path.isdir( path): warnings.warn( _("Repository '%(repo_name)s' is implicitly using " "'portage-1' profile format in its profiles/package.mask, but " "the repository profiles are not marked as that format. This will break " "in the future. Please either convert the following paths " "to files, or add\nprofile-formats = portage-1\nto the " "repositories layout.conf.\n") % dict(repo_name=repo_config.name)) return pmask_cache[loc] repo_pkgmasklines = [] for repo in repositories.repos_with_profiles(): lines = [] repo_lines = grab_pmask(repo.location, repo) removals = frozenset(line[0][1:] for line in repo_lines if line[0][:1] == "-") matched_removals = set() for master in repo.masters: master_lines = grab_pmask(master.location, master) for line in master_lines: if line[0] in removals: matched_removals.add(line[0]) # Since we don't stack masters recursively, there aren't any # atoms earlier in the stack to be matched by negative atoms in # master_lines. Also, repo_lines may contain negative atoms # that are intended to negate atoms from a different master # than the one with which we are currently stacking. Therefore, # we disable warn_for_unmatched_removal here (see bug #386569). lines.append( stack_lists([master_lines, repo_lines], incremental=1, remember_source_file=True, warn_for_unmatched_removal=False)) # It's safe to warn for unmatched removal if masters have not # been overridden by the user, which is guaranteed when # user_config is false (when called by repoman). if repo.masters: unmatched_removals = removals.difference(matched_removals) if unmatched_removals and not user_config: source_file = os.path.join(repo.location, "profiles", "package.mask") unmatched_removals = list(unmatched_removals) if len(unmatched_removals) > 3: writemsg(_( "--- Unmatched removal atoms in %s: %s and %s more\n" ) % (source_file, ", ".join( "-" + x for x in unmatched_removals[:3]), len(unmatched_removals) - 3), noiselevel=-1) else: writemsg( _("--- Unmatched removal atom(s) in %s: %s\n") % (source_file, ", ".join( "-" + x for x in unmatched_removals)), noiselevel=-1) else: lines.append( stack_lists([repo_lines], incremental=1, remember_source_file=True, warn_for_unmatched_removal=not user_config, strict_warn_for_unmatched_removal= strict_umatched_removal)) repo_pkgmasklines.extend( append_repo(stack_lists(lines), repo.name, remember_source_file=True)) repo_pkgunmasklines = [] for repo in repositories.repos_with_profiles(): if not repo.portage1_profiles: continue 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_pkgunmasklines.extend( append_repo(lines, repo.name, remember_source_file=True)) #Read package.mask from the user's profile. Stack them in the end #to allow profiles to override masks from their parent profiles. profile_pkgmasklines = [] profile_pkgunmasklines = [] for x in profiles: profile_pkgmasklines.append( grabfile_package(os.path.join(x.location, "package.mask"), recursive=x.portage1_directories, remember_source_file=True, verify_eapi=True)) if x.portage1_directories: profile_pkgunmasklines.append( grabfile_package(os.path.join(x.location, "package.unmask"), recursive=x.portage1_directories, remember_source_file=True, verify_eapi=True)) profile_pkgmasklines = stack_lists(profile_pkgmasklines, incremental=1, \ remember_source_file=True, warn_for_unmatched_removal=True, strict_warn_for_unmatched_removal=strict_umatched_removal) profile_pkgunmasklines = stack_lists(profile_pkgunmasklines, incremental=1, \ remember_source_file=True, warn_for_unmatched_removal=True, strict_warn_for_unmatched_removal=strict_umatched_removal) #Read /etc/portage/package.mask. Don't stack it to allow the user to #remove mask atoms from everywhere with -atoms. user_pkgmasklines = [] user_pkgunmasklines = [] if user_config: user_pkgmasklines = grabfile_package( os.path.join(abs_user_config, "package.mask"), recursive=1, \ allow_wildcard=True, allow_repo=True, remember_source_file=True, verify_eapi=False) user_pkgunmasklines = grabfile_package( os.path.join(abs_user_config, "package.unmask"), recursive=1, \ allow_wildcard=True, allow_repo=True, remember_source_file=True, verify_eapi=False) #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. raw_pkgmasklines = stack_lists([repo_pkgmasklines, profile_pkgmasklines], \ incremental=1, remember_source_file=True, warn_for_unmatched_removal=False, ignore_repo=True) pkgmasklines = stack_lists([repo_pkgmasklines, profile_pkgmasklines, user_pkgmasklines], \ 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, ignore_repo=True) for x, source_file in raw_pkgmasklines: self._pmaskdict_raw.setdefault(x.cp, []).append(x) for x, source_file in pkgmasklines: self._pmaskdict.setdefault(x.cp, []).append(x) for x, source_file in pkgunmasklines: self._punmaskdict.setdefault(x.cp, []).append(x) for d in (self._pmaskdict_raw, self._pmaskdict, self._punmaskdict): for k, v in d.items(): d[k] = tuple(v)
def __init__(self, profiles, abs_user_config, user_config=True, global_accept_keywords=""): self._pkeywords_list = [] rawpkeywords = [ grabdict_package( os.path.join(x.location, "package.keywords"), recursive=x.portage1_directories, verify_eapi=True, eapi=x.eapi, eapi_default=None, allow_repo=allow_profile_repo_deps(x), allow_build_id=x.allow_build_id, ) for x in profiles ] for pkeyworddict in rawpkeywords: if not pkeyworddict: # Omit non-existent files from the stack. continue cpdict = {} for k, v in pkeyworddict.items(): cpdict.setdefault(k.cp, {})[k] = v self._pkeywords_list.append(cpdict) self._pkeywords_list = tuple(self._pkeywords_list) self._p_accept_keywords = [] raw_p_accept_keywords = [ grabdict_package( os.path.join(x.location, "package.accept_keywords"), recursive=x.portage1_directories, verify_eapi=True, eapi=x.eapi, eapi_default=None, allow_repo=allow_profile_repo_deps(x), ) for x in profiles ] for d in raw_p_accept_keywords: if not d: # Omit non-existent files from the stack. continue cpdict = {} for k, v in d.items(): cpdict.setdefault(k.cp, {})[k] = tuple(v) self._p_accept_keywords.append(cpdict) self._p_accept_keywords = tuple(self._p_accept_keywords) self.pkeywordsdict = ExtendedAtomDict(dict) if user_config: user_accept_kwrds_path = os.path.join(abs_user_config, "package.accept_keywords") user_kwrds_path = os.path.join(abs_user_config, "package.keywords") pkgdict = grabdict_package( user_kwrds_path, recursive=1, allow_wildcard=True, allow_repo=True, verify_eapi=False, allow_build_id=True, ) if pkgdict and portage._internal_caller: warnings.warn( _("%s is deprecated, use %s instead") % (user_kwrds_path, user_accept_kwrds_path), UserWarning, ) for k, v in grabdict_package( user_accept_kwrds_path, recursive=1, allow_wildcard=True, allow_repo=True, verify_eapi=False, allow_build_id=True, ).items(): pkgdict.setdefault(k, []).extend(v) accept_keywords_defaults = global_accept_keywords.split() accept_keywords_defaults = tuple( "~" + keyword for keyword in accept_keywords_defaults if keyword[:1] not in "~-") for k, v in pkgdict.items(): # default to ~arch if no specific keyword is given if not v: v = accept_keywords_defaults else: v = tuple(v) self.pkeywordsdict.setdefault(k.cp, {})[k] = v