diff options
Diffstat (limited to 'pym/portage/package/ebuild/config.py')
-rw-r--r-- | pym/portage/package/ebuild/config.py | 247 |
1 files changed, 28 insertions, 219 deletions
diff --git a/pym/portage/package/ebuild/config.py b/pym/portage/package/ebuild/config.py index d49b23552..315166659 100644 --- a/pym/portage/package/ebuild/config.py +++ b/pym/portage/package/ebuild/config.py @@ -31,7 +31,7 @@ from portage.const import CACHE_PATH, CUSTOM_PROFILE_PATH, \ from portage.dbapi import dbapi from portage.dbapi.porttree import portdbapi from portage.dbapi.vartree import vartree -from portage.dep import Atom, best_match_to_list, \ +from portage.dep import Atom, \ isvalidatom, match_from_list, \ remove_slot, use_reduce from portage.eapi import eapi_exports_AA, eapi_supports_prefix, eapi_exports_replace_vars @@ -47,6 +47,9 @@ from portage.util import ensure_dirs, getconfig, grabdict, \ writemsg, writemsg_level from portage.versions import catpkgsplit, catsplit, cpv_getkey +from portage.package.ebuild._config.LicenseManager import LicenseManager +from portage.package.ebuild._config.helper import ordered_by_atom_specificity + if sys.hexversion >= 0x3000000: basestring = str @@ -95,40 +98,6 @@ def best_from_dict(key, top_dict, key_order, EmptyOnError=1, FullCopy=1, AllowEm else: raise KeyError("Key not found in list; '%s'" % key) -def _ordered_by_atom_specificity(cpdict, pkg): - """ - Return a list of matched values from the given cpdict, - in ascending order by atom specificity. The rationale - for this order is that package.* config files are - typically written in ChangeLog like fashion, so it's - most friendly if the order that the atoms are written - does not matter. Therefore, settings from more specific - atoms override those of less specific atoms. Without - this behavior, settings from relatively unspecific atoms - would (somewhat confusingly) override the settings of - more specific atoms, requiring people to make adjustments - to the order that atoms are listed in the config file in - order to achieve desired results (and thus corrupting - the ChangeLog like ordering of the file). - """ - - results = [] - keys = list(cpdict) - - while keys: - bestmatch = best_match_to_list(pkg, keys) - if bestmatch: - keys.remove(bestmatch) - results.append(cpdict[bestmatch]) - else: - break - - if results: - # reverse, so the most specific atoms come last - results.reverse() - - return results - class _features_set(object): """ Provides relevant set operations needed for access and modification of @@ -190,7 +159,6 @@ class _features_set(object): self._features.remove(k) self._sync_env_var() - def _lazy_iuse_regex(iuse_implicit): """ The PORTAGE_IUSE value is lazily evaluated since re.escape() is slow @@ -402,7 +370,6 @@ class config(object): _environ_filter = frozenset(_environ_filter) - _undef_lic_groups = set() _default_globals = ( ('ACCEPT_LICENSE', '* -@EULA'), ('ACCEPT_PROPERTIES', '*'), @@ -460,9 +427,7 @@ class config(object): self.modifiedkeys = [] self.uvlist = [] self._accept_chost_re = None - self._accept_license = None - self._accept_license_str = None - self._license_groups = {} + self._license_manager = LicenseManager() self._accept_properties = None self._features_overrides = [] @@ -553,9 +518,7 @@ class config(object): self.features._features = copy.deepcopy(clone.features._features) self._features_overrides = copy.deepcopy(clone._features_overrides) - self._accept_license = copy.deepcopy(clone._accept_license) - self._plicensedict = copy.deepcopy(clone._plicensedict) - self._license_groups = copy.deepcopy(clone._license_groups) + self._license_manager = LicenseManager(clone._license_manager) self._accept_properties = copy.deepcopy(clone._accept_properties) self._ppropertiesdict = copy.deepcopy(clone._ppropertiesdict) self._penvdict = copy.deepcopy(clone._penvdict) @@ -968,7 +931,6 @@ class config(object): self.pusedict = portage.dep.ExtendedAtomDict(dict) self.pkeywordsdict = portage.dep.ExtendedAtomDict(dict) - self._plicensedict = portage.dep.ExtendedAtomDict(dict) self._ppropertiesdict = portage.dep.ExtendedAtomDict(dict) self._penvdict = portage.dep.ExtendedAtomDict(dict) self.punmaskdict = portage.dep.ExtendedAtomDict(list) @@ -1053,17 +1015,10 @@ class config(object): self.pkeywordsdict.setdefault(k.cp, {})[k] = v #package.license - licdict = grabdict_package(os.path.join( - abs_user_config, "package.license"), recursive=1, allow_wildcard=True) - v = licdict.pop("*/*", None) - if v is not None: - if "ACCEPT_LICENSE" in self.configdict["conf"]: - self.configdict["conf"]["ACCEPT_LICENSE"] += " " + " ".join(v) - else: - self.configdict["conf"]["ACCEPT_LICENSE"] = " ".join(v) - for k, v in licdict.items(): - self._plicensedict.setdefault(k.cp, {})[k] = \ - self.expandLicenseTokens(v) + self._license_manager.read_config_files(abs_user_config) + self.configdict["conf"]["ACCEPT_LICENSE"] = \ + self._license_manager.extract_global_changes(\ + self.configdict["conf"].get("ACCEPT_LICENSE", "")) #package.properties propdict = grabdict_package(os.path.join( @@ -1196,11 +1151,7 @@ class config(object): self.pprovideddict[mycatpkg]=[x] # parse licensegroups - license_groups = self._license_groups - for x in locations: - for k, v in grabdict( - os.path.join(x, "license_groups")).items(): - license_groups.setdefault(k, []).extend(v) + self._license_manager.parse_license_groups(locations) # reasonable defaults; this is important as without USE_ORDER, # USE will always be "" (nothing set)! @@ -1305,49 +1256,7 @@ class config(object): """ Take a token from ACCEPT_LICENSE or package.license and expand it if it's a group token (indicated by @) or just return it if it's not a group. If a group is negated then negate all group elements.""" - expanded_tokens = [] - for x in tokens: - expanded_tokens.extend(self._expandLicenseToken(x, None)) - return expanded_tokens - - def _expandLicenseToken(self, token, traversed_groups): - negate = False - rValue = [] - if token.startswith("-"): - negate = True - license_name = token[1:] - else: - license_name = token - if not license_name.startswith("@"): - rValue.append(token) - return rValue - group_name = license_name[1:] - if traversed_groups is None: - traversed_groups = set() - license_group = self._license_groups.get(group_name) - if group_name in traversed_groups: - writemsg(_("Circular license group reference" - " detected in '%s'\n") % group_name, noiselevel=-1) - rValue.append("@"+group_name) - elif license_group: - traversed_groups.add(group_name) - for l in license_group: - if l.startswith("-"): - writemsg(_("Skipping invalid element %s" - " in license group '%s'\n") % (l, group_name), - noiselevel=-1) - else: - rValue.extend(self._expandLicenseToken(l, traversed_groups)) - else: - if self._license_groups and \ - group_name not in self._undef_lic_groups: - self._undef_lic_groups.add(group_name) - writemsg(_("Undefined license group '%s'\n") % group_name, - noiselevel=-1) - rValue.append("@"+group_name) - if negate: - rValue = ["-" + token for token in rValue] - return rValue + return self._license_manager.expandLicenseTokens(tokens) def validate(self): """Validate miscellaneous settings and display warnings if necessary. @@ -1498,41 +1407,12 @@ class config(object): use = self.built_use if use is None: use = frozenset(settings['PORTAGE_USE'].split()) - values['ACCEPT_LICENSE'] = self._accept_license(use, settings) + + values['ACCEPT_LICENSE'] = settings._license_manager.get_prunned_accept_license( \ + settings.mycpv, use, settings['LICENSE'], settings['SLOT']) values['PORTAGE_RESTRICT'] = self._restrict(use, settings) return values - def _accept_license(self, use, settings): - """ - Generate a pruned version of ACCEPT_LICENSE, by intersection with - LICENSE. This is required since otherwise ACCEPT_LICENSE might be - too big (bigger than ARG_MAX), causing execve() calls to fail with - E2BIG errors as in bug #262647. - """ - try: - licenses = set(use_reduce(settings['LICENSE'], uselist=use, flat=True)) - except InvalidDependString: - licenses = set() - licenses.discard('||') - - accept_license = settings._getPkgAcceptLicense( - settings.mycpv, {'SLOT' : settings['SLOT']}) - - if accept_license: - acceptable_licenses = set() - for x in accept_license: - if x == '*': - acceptable_licenses.update(licenses) - elif x == '-*': - acceptable_licenses.clear() - elif x[:1] == '-': - acceptable_licenses.discard(x[1:]) - elif x in licenses: - acceptable_licenses.add(x) - - licenses = acceptable_licenses - return ' '.join(sorted(licenses)) - def _restrict(self, use, settings): try: restrict = set(use_reduce(settings['RESTRICT'], uselist=use, flat=True)) @@ -1712,7 +1592,7 @@ class config(object): defaults.append(self.make_defaults_use[i]) cpdict = pkgprofileuse_dict.get(cp) if cpdict: - pkg_defaults = _ordered_by_atom_specificity(cpdict, cpv_slot) + pkg_defaults = ordered_by_atom_specificity(cpdict, cpv_slot) if pkg_defaults: defaults.extend(pkg_defaults) defaults = " ".join(defaults) @@ -1733,7 +1613,7 @@ class config(object): self.puse = "" cpdict = self.pusedict.get(cp) if cpdict: - puse_matches = _ordered_by_atom_specificity(cpdict, cpv_slot) + puse_matches = ordered_by_atom_specificity(cpdict, cpv_slot) if puse_matches: puse_list = [] for x in puse_matches: @@ -1754,7 +1634,7 @@ class config(object): self._penv = [] cpdict = self._penvdict.get(cp) if cpdict: - penv_matches = _ordered_by_atom_specificity(cpdict, cpv_slot) + penv_matches = ordered_by_atom_specificity(cpdict, cpv_slot) if penv_matches: for x in penv_matches: self._penv.extend(x) @@ -1967,7 +1847,7 @@ class config(object): usemask.append(self.usemask_list[i]) cpdict = pusemask_dict.get(cp) if cpdict: - pkg_usemask = _ordered_by_atom_specificity(cpdict, pkg) + pkg_usemask = ordered_by_atom_specificity(cpdict, pkg) if pkg_usemask: usemask.extend(pkg_usemask) return set(stack_lists(usemask, incremental=True)) @@ -1982,7 +1862,7 @@ class config(object): useforce.append(self.useforce_list[i]) cpdict = puseforce_dict.get(cp) if cpdict: - pkg_useforce = _ordered_by_atom_specificity(cpdict, pkg) + pkg_useforce = ordered_by_atom_specificity(cpdict, pkg) if pkg_useforce: useforce.extend(pkg_useforce) return set(stack_lists(useforce, incremental=True)) @@ -2049,7 +1929,7 @@ class config(object): for pkeywords_dict in self._pkeywords_list: cpdict = pkeywords_dict.get(cp) if cpdict: - pkg_keywords = _ordered_by_atom_specificity(cpdict, pkg) + pkg_keywords = ordered_by_atom_specificity(cpdict, pkg) if pkg_keywords: keywords.extend(pkg_keywords) return stack_lists(keywords, incremental=True) @@ -2089,7 +1969,7 @@ class config(object): cpdict = d.get(cp) if cpdict: pkg_accept_keywords = \ - _ordered_by_atom_specificity(cpdict, cpv_slot) + ordered_by_atom_specificity(cpdict, cpv_slot) if pkg_accept_keywords: for x in pkg_accept_keywords: if not x: @@ -2101,7 +1981,7 @@ class config(object): if pkgdict: cpv_slot = "%s:%s" % (cpv, metadata["SLOT"]) pkg_accept_keywords = \ - _ordered_by_atom_specificity(pkgdict, cpv_slot) + ordered_by_atom_specificity(pkgdict, cpv_slot) if pkg_accept_keywords: for x in pkg_accept_keywords: pgroups.extend(x) @@ -2152,22 +2032,6 @@ class config(object): missing = mygroups return missing - def _getPkgAcceptLicense(self, cpv, metadata): - """ - Get an ACCEPT_LICENSE list, accounting for package.license. - """ - accept_license = self._accept_license - cp = cpv_getkey(cpv) - cpdict = self._plicensedict.get(cp) - if cpdict: - cpv_slot = "%s:%s" % (cpv, metadata["SLOT"]) - plicence_list = _ordered_by_atom_specificity(cpdict, cpv_slot) - if plicence_list: - accept_license = list(self._accept_license) - for x in plicence_list: - accept_license.extend(x) - return accept_license - def _getMissingLicenses(self, cpv, metadata): """ Take a LICENSE string and return a list any licenses that the user may @@ -2182,61 +2046,8 @@ class config(object): @rtype: List @return: A list of licenses that have not been accepted. """ - - - licenses = set(use_reduce(metadata["LICENSE"], matchall=1, flat=True)) - licenses.discard('||') - - acceptable_licenses = set() - for x in self._getPkgAcceptLicense(cpv, metadata): - if x == '*': - acceptable_licenses.update(licenses) - elif x == '-*': - acceptable_licenses.clear() - elif x[:1] == '-': - acceptable_licenses.discard(x[1:]) - else: - acceptable_licenses.add(x) - - license_str = metadata["LICENSE"] - if "?" in license_str: - use = metadata["USE"].split() - else: - use = [] - - license_struct = use_reduce(license_str, uselist=use, opconvert=True) - return self._getMaskedLicenses(license_struct, acceptable_licenses) - - def _getMaskedLicenses(self, license_struct, acceptable_licenses): - if not license_struct: - return [] - if license_struct[0] == "||": - ret = [] - for element in license_struct[1:]: - if isinstance(element, list): - if element: - tmp = self._getMaskedLicenses(element, acceptable_licenses) - if not tmp: - return [] - ret.extend(tmp) - else: - if element in acceptable_licenses: - return [] - ret.append(element) - # Return all masked licenses, since we don't know which combination - # (if any) the user will decide to unmask. - return ret - - ret = [] - for element in license_struct: - if isinstance(element, list): - if element: - ret.extend(self._getMaskedLicenses(element, - acceptable_licenses)) - else: - if element not in acceptable_licenses: - ret.append(element) - return ret + return self._license_manager.getMissingLicenses( \ + cpv, metadata["USE"], metadata["LICENSE"], metadata["SLOT"]) def _getMissingProperties(self, cpv, metadata): """ @@ -2257,7 +2068,7 @@ class config(object): cpdict = self._ppropertiesdict.get(cp) if cpdict: cpv_slot = "%s:%s" % (cpv, metadata["SLOT"]) - pproperties_list = _ordered_by_atom_specificity(cpdict, cpv_slot) + pproperties_list = ordered_by_atom_specificity(cpdict, cpv_slot) if pproperties_list: accept_properties = list(self._accept_properties) for x in pproperties_list: @@ -2474,12 +2285,10 @@ class config(object): mysplit = self._prune_incremental(mysplit) accept_license_str = ' '.join(mysplit) self.configlist[-1]['ACCEPT_LICENSE'] = accept_license_str - if accept_license_str != self._accept_license_str: - self._accept_license_str = accept_license_str - self._accept_license = tuple(self.expandLicenseTokens(mysplit)) + self._license_manager.set_accept_license_str(accept_license_str) else: # repoman will accept any license - self._accept_license = ('*',) + self._license_manager.set_accept_license_str("*") # ACCEPT_PROPERTIES works like ACCEPT_LICENSE, without groups if self.local_config: |