From 2d8be359a0f90a7f71a7c4023b497144316db39b Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Sun, 22 Oct 2006 14:03:16 +0000 Subject: [PATCH] Merged from trunk 4785:4794 Optimize config.setcpv so that it only calls regenerate when necessary. Thanks to Jason Stubbs for the initial patch from bug #17367. Use reset instead of regenerate (revert part of the previous commit) in order to properly clear the env layer of the config. Fix visibility checks so that binary packages aren't masked just because there is no matching ebuild in the tree. Call load_infodir before the setup phase for binary packages so that USE is properly set. Don't put empty incrementals in the environment, unless they are already set. Add support for masking of packages via ACCEPT_LICENSE and /etc/portage/package.license. Thanks to Jason Stubbs for the initial patch from bug #17367. s/str_matches/acceptable_licenses/ typo Fix gcc version parsing once again for bug #137786. sigh. :) svn path=/main/branches/prefix/; revision=4795 --- bin/emerge | 12 +++-- bin/repoman | 1 + pym/portage.py | 125 ++++++++++++++++++++++++++++++++++++------- pym/portage_const.py | 4 +- 4 files changed, 118 insertions(+), 24 deletions(-) diff --git a/bin/emerge b/bin/emerge index 4efc819de..aed9c1be6 100755 --- a/bin/emerge +++ b/bin/emerge @@ -298,8 +298,8 @@ def getgccversion(chost): return myoutput.replace(chost + "-", gcc_ver_prefix, 1) mystatus, myoutput = commands.getstatusoutput("gcc-config -c") - if mystatus == os.EX_OK and len(myoutput.split("-")) > 0: - return gcc_ver_prefix + myoutput.split("-")[-1] + if mystatus == os.EX_OK and myoutput.startswith(chost + "-"): + return myoutput.replace(chost + "-", gcc_ver_prefix, 1) mystatus, myoutput = commands.getstatusoutput( chost + "-" + gcc_ver_command) @@ -968,7 +968,9 @@ class depgraph: pkgsettings = self.pkgsettings[myroot] arg_atoms = [] def visible(mylist): - return portdb.gvisible(portdb.visible(mylist)) + matches = portdb.gvisible(portdb.visible(mylist)) + return [x for x in mylist \ + if x in matches or not portdb.cpv_exists(x)] for x in myfiles: ext = os.path.splitext(x)[1] if ext==".tbz2": @@ -1570,7 +1572,9 @@ class depgraph: portdb = self.trees[self.target_root]["porttree"].dbapi bindb = self.trees[self.target_root]["bintree"].dbapi def visible(mylist): - return portdb.gvisible(portdb.visible(mylist)) + matches = portdb.gvisible(portdb.visible(mylist)) + return [x for x in mylist \ + if x in matches or not portdb.cpv_exists(x)] world_problems = False if mode=="system": mylist = getlist(self.settings, "system") diff --git a/bin/repoman b/bin/repoman index 6548f92a6..b4a108da5 100755 --- a/bin/repoman +++ b/bin/repoman @@ -543,6 +543,7 @@ if quiet < 2: print "PORTDIR_OVERLAY = \""+os.environ["PORTDIR_OVERLAY"]+"\"" # Now that PORTDIR_OVERLAY is properly overridden, create the portdb. +os.environ["ACCEPT_LICENSE"] = "*" repoman_settings = portage.config(local_config=False, config_incrementals=portage_const.INCREMENTALS) trees = portage.create_trees() diff --git a/pym/portage.py b/pym/portage.py index 9ec4863bc..1b8222ac6 100644 --- a/pym/portage.py +++ b/pym/portage.py @@ -916,6 +916,9 @@ class config: self.dirVirtuals = copy.deepcopy(clone.dirVirtuals) self.treeVirtuals = copy.deepcopy(clone.treeVirtuals) self.features = copy.deepcopy(clone.features) + + self._accept_license = copy.deepcopy(clone._accept_license) + self._plicensedict = copy.deepcopy(clone._plicensedict) else: # backupenv is for calculated incremental variables. @@ -1182,6 +1185,7 @@ class config: self.pusedict = {} self.pkeywordsdict = {} + self._plicensedict = {} self.punmaskdict = {} abs_user_config = os.path.join(config_root, USER_CONFIG_PATH.lstrip(os.path.sep)) @@ -1234,6 +1238,14 @@ class config: if not self.pkeywordsdict.has_key(cp): self.pkeywordsdict[cp] = {} self.pkeywordsdict[cp][key] = pkgdict[key] + + #package.license + licdict = grabdict_package( + os.path.join(abs_user_config, "package.license"), + recursive=1) + for k, v in licdict.iteritems(): + self._plicensedict.setdefault( + dep_getkey(k), {})[k] = v #package.unmask pkgunmasklines = grabfile_package( @@ -1327,6 +1339,8 @@ class config: self.regenerate() self.features = portage_util.unique_array(self["FEATURES"].split()) + + self._accept_license = set(self.get("ACCEPT_LICENSE", "*").split()) if "gpg" in self.features: if not os.path.exists(self["PORTAGE_GPG_DIR"]) or \ @@ -1509,6 +1523,7 @@ class config: self.modifying() if self.mycpv == mycpv: return + has_changed = False self.mycpv = mycpv cp = dep_getkey(mycpv) pkginternaluse = "" @@ -1516,7 +1531,9 @@ class config: pkginternaluse = " ".join([x[1:] \ for x in mydb.aux_get(mycpv, ["IUSE"])[0].split() \ if x.startswith("+")]) - self.configdict["pkginternal"]["USE"] = pkginternaluse + if pkginternaluse != self.configdict["pkginternal"].get("USE", ""): + self.configdict["pkginternal"]["USE"] = pkginternaluse + has_changed = True defaults = [] for i in xrange(len(self.profiles)): defaults.append(self.make_defaults_use[i]) @@ -1525,7 +1542,10 @@ class config: best_match = best_match_to_list(self.mycpv, cpdict.keys()) if best_match: defaults.append(cpdict[best_match]) - self.configdict["defaults"]["USE"] = " ".join(defaults) + defaults = " ".join(defaults) + if defaults != self.configdict["defaults"]["USE"]: + self.configdict["defaults"]["USE"] = defaults + has_changed = True useforce = [] for i in xrange(len(self.profiles)): useforce.append(self.useforce_list[i]) @@ -1534,7 +1554,10 @@ class config: best_match = best_match_to_list(self.mycpv, cpdict.keys()) if best_match: useforce.append(cpdict[best_match]) - self.useforce = set(stack_lists(useforce, incremental=True)) + useforce = set(stack_lists(useforce, incremental=True)) + if useforce != self.useforce: + self.useforce = useforce + has_changed = True usemask = [] for i in xrange(len(self.profiles)): usemask.append(self.usemask_list[i]) @@ -1543,17 +1566,34 @@ class config: best_match = best_match_to_list(self.mycpv, cpdict.keys()) if best_match: usemask.append(cpdict[best_match]) - self.usemask = set(stack_lists(usemask, incremental=True)) + usemask = set(stack_lists(usemask, incremental=True)) + if usemask != self.usemask: + self.usemask = usemask + has_changed = True + oldpuse = self.puse self.puse = "" if self.pusedict.has_key(cp): self.pusekey = best_match_to_list(self.mycpv, self.pusedict[cp].keys()) if self.pusekey: self.puse = " ".join(self.pusedict[cp][self.pusekey]) + if oldpuse != self.puse: + has_changed = True self.configdict["pkg"]["PKGUSE"] = self.puse[:] # For saving to PUSE file self.configdict["pkg"]["USE"] = self.puse[:] # this gets appended to USE # CATEGORY is essential for doebuild calls self.configdict["pkg"]["CATEGORY"] = mycpv.split("/")[0] - self.reset(keeping_pkg=1,use_cache=use_cache) + if has_changed: + self.reset(keeping_pkg=1,use_cache=use_cache) + + def acceptable_licenses(self, cpv): + cpdict = self._plicensedict.get(dep_getkey(cpv), None) + if not cpdict: + return self._accept_license.copy() + plicenses = self._accept_license.copy() + matches = match_to_list(cpv, cpdict.keys()) + for atom in matches: + plicenses.update(cpdict[atom]) + return plicenses def setinst(self,mycpv,mydbapi): self.modifying() @@ -1648,7 +1688,8 @@ class config: myflags.sort() #store setting in last element of configlist, the original environment: - self.configlist[-1][mykey]=string.join(myflags," ") + if myflags or mykey in self: + self.configlist[-1][mykey] = " ".join(myflags) del myflags # Do the USE calculation last because it depends on USE_EXPAND. @@ -2574,8 +2615,10 @@ def doebuild_environment(myebuild, mydo, myroot, mysettings, debug, use_cache, m "Invalid ebuild path: '%s'" % myebuild) if mydo != "depend": - # XXX: We're doing a little hack here to curtain the gvisible locking - # XXX: that creates a deadlock... Really need to isolate that. + """For performance reasons, setcpv only triggers reset when it + detects a package-specific change in config. For the ebuild + environment, a reset call is forced in order to ensure that the + latest env.d variables are used.""" mysettings.reset(use_cache=use_cache) mysettings.setcpv(mycpv, use_cache=use_cache, mydb=mydbapi) @@ -2941,6 +2984,12 @@ def doebuild(myebuild, mydo, myroot, mysettings, debug=0, listonly=0, return spawn(EBUILD_SH_BINARY + " " + mydo, mysettings, debug=debug, free=1, logfile=logfile) elif mydo == "setup": + infodir = os.path.join( + mysettings["PORTAGE_BUILDDIR"], "build-info") + if os.path.isdir(infodir): + """Load USE flags for setup phase of a binary package. + Ideally, the environment.bz2 would be used instead.""" + mysettings.load_infodir(infodir) retval = spawn(EBUILD_SH_BINARY + " " + mydo, mysettings, debug=debug, free=1, logfile=logfile) if secpass >= 2: @@ -3429,9 +3478,7 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None, return_all_deps=False): """Takes an unreduced and reduced deplist and removes satisfied dependencies. Returned deplist contains steps that must be taken to satisfy dependencies.""" - if trees is None: - global db - trees = db + writemsg("ZapDeps -- %s\n" % (use_binaries), 2) if not reduced or unreduced == ["||"] or \ (not return_all_deps and dep_eval(reduced)): @@ -3452,6 +3499,17 @@ def dep_zapdeps(unreduced, reduced, myroot, use_binaries=0, trees=None, deps = unreduced[1:] satisfieds = reduced[1:] + if trees is None: + # We don't have trees to check availability against, so we + # just default to the first choice. + if isinstance(deps[0], list): + atoms = dep_zapdeps(deps[0], satisfieds[0], myroot, + use_binaries=use_binaries, trees=trees, + return_all_deps=return_all_deps) + else: + atoms = [deps[0]] + return atoms + # Our preference order is for an the first item that: # a) contains all unmasked packages with the same key as installed packages # b) contains all unmasked packages @@ -3556,7 +3614,8 @@ def dep_expand(mydep, mydb=None, use_cache=1, settings=None): mydep, mydb=mydb, use_cache=use_cache, settings=settings) + postfix def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None, - use_cache=1, use_binaries=0, myroot="/", trees=None, return_all_deps=False): + use_cache=1, use_binaries=0, myroot="/", trees=None, str_matches=None, + return_all_deps=False): """Takes a depend string and parses the condition.""" #check_config_instance(mysettings) @@ -3613,7 +3672,8 @@ def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None, #dependencies were reduced to nothing return [1,[]] mysplit2=mysplit[:] - mysplit2=dep_wordreduce(mysplit2,mysettings,mydbapi,mode,use_cache=use_cache) + mysplit2 = dep_wordreduce(mysplit2, mysettings, mydbapi, mode, + str_matches=str_matches, use_cache=use_cache) if mysplit2 is None: return [0,"Invalid token"] @@ -3634,19 +3694,24 @@ def dep_check(depstring, mydbapi, mysettings, use="yes", mode=None, myuse=None, writemsg("mydict: %s\n" % (mydict), 1) return [1,mydict.keys()] -def dep_wordreduce(mydeplist,mysettings,mydbapi,mode,use_cache=1): +def dep_wordreduce(mydeplist, mysettings, mydbapi, mode, str_matches=None, + use_cache=1): "Reduces the deplist to ones and zeros" mypos=0 deplist=mydeplist[:] while mypos