From 37370c64d68a64cf2f990d887ca314350b7660dc Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Fri, 19 Feb 2010 10:16:30 +0000 Subject: [PATCH] Merged from trunk -r15360:15370 | 15361 | Fix type in CLEAN_DELAY docs. | | zmedico | | | 15362 | Bug #303567 - Merge libc asap, in order to account for | | zmedico | implicit dependencies. | | 15363 | Add @rebuilt-binaries set which uses BUILD_TIME to pull in | | zmedico | binary packages that have a different build time from a | | | currently installed package of the exact same version. | | 15364 | Add a --rebuilt-binaries[=n] option, causing automatic | | zmedico | replacement of installed packages with binary packages that | | | have been rebuilt. Rebuilds are detected by comparison of | | | BUILD_TIME package metadata. This option is enabled | | | automatically when using binary packages, so rebuilt | | | binaries are installed with a user's typical update command. | | | This isn't possible with the existing @rebuild-binaries | | | package set since that only works with --selective=n and | | | therefore can't be used with a typical world update. The | | | package set framework should support this type of behavior | | | sometime in the future. | | 15365 | Bug #305393 - Handle new sdiff exit status for | | zmedico | diffutils-2.9. | | 15366 | Add a comment about slowness in _serialize_tasks when there | | zmedico | are lots of blockers to solve. | | 15367 | Fix colors for --rebuilt-binaries docs. | | zmedico | | | 15368 | Fix broken diffutils vercmp code. | | zmedico | | | 15369 | Update the spinner in depgraph._serialize_tasks when | | zmedico | searching for suitable uninstall tasks. | | 15370 | Remove diffutils version detection code since it's not | | zmedico | really needed. | svn path=/main/branches/prefix/; revision=15386 --- bin/dispatch-conf | 4 +++ cnf/sets.conf | 6 ++++ man/emerge.1 | 7 ++++ man/make.conf.5 | 3 +- pym/_emerge/depgraph.py | 42 ++++++++++++++++++---- pym/_emerge/help.py | 9 +++++ pym/_emerge/main.py | 75 +++++++++++++++++++++++---------------- pym/portage/const.py | 1 + pym/portage/sets/dbapi.py | 25 ++++++++++++- 9 files changed, 133 insertions(+), 39 deletions(-) diff --git a/bin/dispatch-conf b/bin/dispatch-conf index 1adbae441..a1c183d72 100755 --- a/bin/dispatch-conf +++ b/bin/dispatch-conf @@ -119,6 +119,7 @@ class dispatch: "use-rcs=yes in config; fatal', file=sys.stderr) return False + merge_cmd = self.options.get("merge", "").split() # config file freezing support frozen_files = set(self.options.get("frozen-files", "").split()) @@ -269,6 +270,9 @@ class dispatch: merged = SCRATCH_DIR+"/"+os.path.basename(conf['current']) print() ret = os.system (self.options['merge'] % (merged, conf ['current'], newconf)) + ret = os.WEXITSTATUS(ret) + if ret < 2: + ret = 0 if ret: print("Failure running 'merge' command") continue diff --git a/cnf/sets.conf b/cnf/sets.conf index 46c86e750..87280cef6 100644 --- a/cnf/sets.conf +++ b/cnf/sets.conf @@ -65,6 +65,12 @@ class = portage.sets.dbapi.OwnerSet world-candidate = False files = %(ROOT)slib/modules +# Binary packages that have a different build time from a currently +# installed package of the exact same version. +[rebuilt-binaries] +class = portage.sets.dbapi.RebuiltBinaries +world-candidate = False + # Installed packages for which the highest visible ebuild # version is lower than the currently installed version. [downgrade] diff --git a/man/emerge.1 b/man/emerge.1 index bf9cdaa96..f88513c8a 100644 --- a/man/emerge.1 +++ b/man/emerge.1 @@ -477,6 +477,13 @@ output from portage's displays. Redirect all build output to logs alone, and do not display it on stdout. .TP +.BR "\-\-rebuilt\-binaries[=n]" +Replace installed packages with binary packages that have +been rebuilt. Rebuilds are detected by comparison of +BUILD_TIME package metadata. This option is enabled +automatically when using binary packages (see +\fB\-\-usepkg\fR and \fB\-\-getbinpkg\fR). +.TP .BR "\-\-reinstall changed\-use" Tells emerge to include installed packages where USE flags have changed since installation. Unlike \fB\-\-newuse\fR, this option does diff --git a/man/make.conf.5 b/man/make.conf.5 index d22c43cd7..18d769f32 100644 --- a/man/make.conf.5 +++ b/man/make.conf.5 @@ -115,7 +115,8 @@ http://gcc.gnu.org/onlinedocs/gcc\-3.2/gcc/Submodel\-Options.html http://gcc.gnu.org/onlinedocs/gcc\-2.95.3/gcc_2.html .TP \fBCLEAN_DELAY\fR = \fIinteger\fR -Determines how long the countdown delay will be after running `emerge clean`. +Determines how long the countdown delay will be after running +`emerge --unmerge`. .br Defaults to 5 seconds. .TP diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index eb7463a92..00dd31f84 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -229,11 +229,6 @@ class _dynamic_depgraph_config(object): ]["vartree"].dbapi._aux_cache_keys) dbs.append((vardb, "installed", True, True, db_keys)) self._filtered_trees[myroot]["dbs"] = dbs - if "--usepkg" in depgraph._frozen_config.myopts: - depgraph._frozen_config._trees_orig[myroot - ]["bintree"].populate( - "--getbinpkg" in depgraph._frozen_config.myopts, - "--getbinpkgonly" in depgraph._frozen_config.myopts) class depgraph(object): @@ -2401,6 +2396,9 @@ class depgraph(object): atom_set = InternalPackageSet(initial_atoms=(atom,)) existing_node = None myeb = None + usepkg = "--usepkg" in self._frozen_config.myopts + rebuilt_binaries = usepkg and \ + self._frozen_config.myopts.get('--rebuilt-binaries') != 'n' usepkgonly = "--usepkgonly" in self._frozen_config.myopts empty = "empty" in self._dynamic_config.myparams selective = "selective" in self._dynamic_config.myparams @@ -2620,10 +2618,26 @@ class depgraph(object): if pkg.cp == cp] break + if existing_node is not None and \ + existing_node in matched_packages: + return existing_node, existing_node + if len(matched_packages) > 1: + if rebuilt_binaries: + inst_pkg = None + built_pkg = None + for pkg in matched_packages: + if pkg.installed: + inst_pkg = pkg + elif pkg.built: + built_pkg = pkg + if built_pkg is not None and inst_pkg is not None: + if built_pkg >= inst_pkg and \ + built_pkg.metadata['BUILD_TIME'] != \ + inst_pkg.metadata['BUILD_TIME']: + return built_pkg, built_pkg + if avoid_update: - if existing_node is not None: - return existing_node, existing_node for pkg in matched_packages: if pkg.installed: return pkg, existing_node @@ -3335,6 +3349,15 @@ class depgraph(object): runtime_deps.update(atom for atom in atoms \ if not atom.blocker) + # Merge libc asap, in order to account for implicit + # dependencies. See bug #303567. + libc_pkg = self._dynamic_config.mydbapi[running_root].match_pkgs( + portage.const.LIBC_PACKAGE_ATOM) + if libc_pkg: + libc_pkg = libc_pkg[0] + if libc_pkg.operation == 'merge': + asap_nodes.append(libc_pkg) + def gather_deps(ignore_priority, mergeable_nodes, selected_nodes, node): """ @@ -3523,6 +3546,10 @@ class depgraph(object): min_parent_deps = None uninst_task = None + + # FIXME: This loop can be extremely slow when + # there of lots of blockers to solve + # (especially the gather_deps part). for task in myblocker_uninstalls.leaf_nodes(): # Do some sanity checks so that system or world packages # don't get uninstalled inappropriately here (only really @@ -3646,6 +3673,7 @@ class depgraph(object): # best possible choice, but the current algorithm # is simple and should be near optimal for most # common cases. + self._spinner_update() mergeable_parent = False parent_deps = set() for parent in mygraph.parent_nodes(task): diff --git a/pym/_emerge/help.py b/pym/_emerge/help.py index 88b818cfb..afdaa1cab 100644 --- a/pym/_emerge/help.py +++ b/pym/_emerge/help.py @@ -506,6 +506,15 @@ def help(myopts, havecolor=1): for line in wrap(desc, desc_width): print(desc_indent + line) print() + print(" "+green("--rebuilt-binaries") + "[=%s]" % turquoise("n")) + desc = "Replace installed packages with binary packages that have " + \ + "been rebuilt. Rebuilds are detected by comparison of " + \ + "BUILD_TIME package metadata. This option is enabled " + \ + "automatically when using binary packages (see " + \ + "--usepkg and --getbinpkg)." + for line in wrap(desc, desc_width): + print(desc_indent + line) + print() print(" "+green("--reinstall ") + turquoise("changed-use")) print(" Tells emerge to include installed packages where USE flags have") print(" changed since installation. Unlike --newuse, this option does") diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py index b5f97a81a..9a3054867 100644 --- a/pym/_emerge/main.py +++ b/pym/_emerge/main.py @@ -396,6 +396,7 @@ def insert_optional_args(args): '--getbinpkgonly' : ('n',), '--jobs' : valid_integers, '--keep-going' : ('n',), + '--rebuilt-binaries' : ('n',), '--root-deps' : ('rdeps',), '--select' : ('n',), '--selective' : ('n',), @@ -621,6 +622,13 @@ def parse_opts(tmpcmdline, silent=False): "choices" : ("True", "n") }, + "--rebuilt-binaries": { + "help" : "replace installed packages with binary " + \ + "packages that have been rebuilt", + "type" : "choice", + "choices" : ("True", "n") + }, + "--root": { "help" : "specify the target root filesystem for merging packages", "action" : "store" @@ -733,6 +741,10 @@ def parse_opts(tmpcmdline, silent=False): else: myoptions.keep_going = None + if myoptions.rebuilt_binaries in ("True",): + # The depgraph will enable this by default unless 'n' is specified. + myoptions.rebuilt_binaries = None + if myoptions.root_deps == "True": myoptions.root_deps = True @@ -1209,10 +1221,43 @@ def emerge_main(): config_protect_check(trees) check_procfs() + if "getbinpkg" in settings.features: + myopts["--getbinpkg"] = True + + if "--getbinpkgonly" in myopts: + myopts["--getbinpkg"] = True + + if "--getbinpkgonly" in myopts: + myopts["--usepkgonly"] = True + + if "--getbinpkg" in myopts: + myopts["--usepkg"] = True + + if "--usepkgonly" in myopts: + myopts["--usepkg"] = True + + if "buildpkg" in settings.features or "--buildpkgonly" in myopts: + myopts["--buildpkg"] = True + + if "--buildpkgonly" in myopts: + # --buildpkgonly will not merge anything, so + # it cancels all binary package options. + for opt in ("--getbinpkg", "--getbinpkgonly", + "--usepkg", "--usepkgonly"): + myopts.pop(opt, None) + for mytrees in trees.values(): mydb = mytrees["porttree"].dbapi # Freeze the portdbapi for performance (memoize all xmatch results). mydb.freeze() + + if "--usepkg" in myopts: + # Populate the bintree with current --getbinpkg setting. + # This needs to happen before expand_set_arguments(), in case + # any sets use the bintree. + mytrees["bintree"].populate( + getbinpkgs="--getbinpkg" in myopts) + del mytrees, mydb if "moo" in myfiles: @@ -1271,42 +1316,12 @@ def emerge_main(): spinner.update = spinner.update_quiet portage.util.noiselimit = -1 - # Always create packages if FEATURES=buildpkg - # Imply --buildpkg if --buildpkgonly - if ("buildpkg" in settings.features) or ("--buildpkgonly" in myopts): - if "--buildpkg" not in myopts: - myopts["--buildpkg"] = True - - # Always try and fetch binary packages if FEATURES=getbinpkg - if ("getbinpkg" in settings.features): - myopts["--getbinpkg"] = True - - if "--buildpkgonly" in myopts: - # --buildpkgonly will not merge anything, so - # it cancels all binary package options. - for opt in ("--getbinpkg", "--getbinpkgonly", - "--usepkg", "--usepkgonly"): - myopts.pop(opt, None) - if "--fetch-all-uri" in myopts: myopts["--fetchonly"] = True if "--skipfirst" in myopts and "--resume" not in myopts: myopts["--resume"] = True - if ("--getbinpkgonly" in myopts) and not ("--usepkgonly" in myopts): - myopts["--usepkgonly"] = True - - if ("--getbinpkgonly" in myopts) and not ("--getbinpkg" in myopts): - myopts["--getbinpkg"] = True - - if ("--getbinpkg" in myopts) and not ("--usepkg" in myopts): - myopts["--usepkg"] = True - - # Also allow -K to apply --usepkg/-k - if ("--usepkgonly" in myopts) and not ("--usepkg" in myopts): - myopts["--usepkg"] = True - # Allow -p to remove --ask if "--pretend" in myopts: myopts.pop("--ask", None) diff --git a/pym/portage/const.py b/pym/portage/const.py index b176382fa..fd26f486e 100644 --- a/pym/portage/const.py +++ b/pym/portage/const.py @@ -84,6 +84,7 @@ REPO_NAME_FILE = "repo_name" REPO_NAME_LOC = "profiles" + "/" + REPO_NAME_FILE PORTAGE_PACKAGE_ATOM = "sys-apps/portage" +LIBC_PACKAGE_ATOM = "virtual/libc" INCREMENTALS = ("USE", "USE_EXPAND", "USE_EXPAND_HIDDEN", "FEATURES", "ACCEPT_KEYWORDS", diff --git a/pym/portage/sets/dbapi.py b/pym/portage/sets/dbapi.py index a5d7c7153..3ece6f642 100644 --- a/pym/portage/sets/dbapi.py +++ b/pym/portage/sets/dbapi.py @@ -21,7 +21,7 @@ class EverythingSet(PackageSet): "atoms to match all installed packages" _filter = None - def __init__(self, vdbapi): + def __init__(self, vdbapi, **kwargs): super(EverythingSet, self).__init__() self._db = vdbapi @@ -313,3 +313,26 @@ class AgeSet(EverythingSet): return AgeSet(vardb=trees["vartree"].dbapi, mode=mode, age=age) singleBuilder = classmethod(singleBuilder) + +class RebuiltBinaries(EverythingSet): + _operations = ('merge',) + _aux_keys = ('BUILD_TIME',) + + def __init__(self, vardb, bindb=None): + super(RebuiltBinaries, self).__init__(vardb, bindb=bindb) + self._bindb = bindb + + def _filter(self, atom): + cpv = self._db.match(atom)[0] + inst_build_time, = self._db.aux_get(cpv, self._aux_keys) + try: + bin_build_time, = self._bindb.aux_get(cpv, self._aux_keys) + except KeyError: + return False + return inst_build_time != bin_build_time + + def singleBuilder(cls, options, settings, trees): + return RebuiltBinaries(trees["vartree"].dbapi, + bindb=trees["bintree"].dbapi) + + singleBuilder = classmethod(singleBuilder) -- 2.26.2