From 80b72a3e8a1d0e04f430db3a7f5924f123362d7c Mon Sep 17 00:00:00 2001 From: David James Date: Wed, 27 Apr 2011 15:07:12 -0700 Subject: [PATCH] emerge: add 3 new options similar to --exclude Add --nousepkg-atoms, --useoldpkg-atoms, and --reinstall-atoms flag to Portage reinstall-atoms accepts a space separated list of package names or slot atoms. Emerge will treat matching packages as if they are not installed, and reinstall them if necessary. useoldpkg-atoms accepts a space separated list of package names or slot atoms. Emerge will prefer matching binary packages over newer unbuilt packages. This is useful in case you want to request that a particular package won't be rebuilt from source. nousepkg-atoms accepts a space separated list of package names or slot atoms. Emerge will ignore matching binary packages. Change-Id: I0d73039c6a4cd63695b28ffc80215628e0e05c95 BUG=chromium-os:12507 TEST=Try out the flag Review URL: http://codereview.chromium.org/6577024 --- man/emerge.1 | 13 +++++++ pym/_emerge/depgraph.py | 78 ++++++++++++++++++++++++++++++----------- pym/_emerge/main.py | 78 ++++++++++++++++++++++++++++++----------- 3 files changed, 129 insertions(+), 40 deletions(-) diff --git a/man/emerge.1 b/man/emerge.1 index 2693b6753..67f3e4796 100644 --- a/man/emerge.1 +++ b/man/emerge.1 @@ -479,6 +479,10 @@ may have changed. Disables the spinner for the session. The spinner is active when the terminal device is determined to be a TTY. This flag disables it regardless. .TP +.BR "\-\-nousepkg\-atoms " ATOMS +A space separated list of package names or slot atoms. Emerge will ignore +matching binary packages. +.TP .BR "\-\-oneshot " (\fB\-1\fR) Emerge as normal, but do not add the packages to the world file for later updating. @@ -549,6 +553,11 @@ changed since installation. Unlike \fB\-\-newuse\fR, this option does not trigger reinstallation when flags that the user has not enabled are added or removed. .TP +.BR "\-\-reinstall\-atoms " ATOMS +A space separated list of package names or slot atoms. Emerge will treat +matching packages as if they are not installed, and reinstall them if +necessary. +.TP .BR \-\-root=DIR Set the \fBROOT\fR environment variable. .TP @@ -606,6 +615,10 @@ atoms may match multiple versions of slotted packages. Use unbuilt ebuild metadata for visibility checks on built packages. .TP +.BR "\-\-useoldpkg\-atoms " ATOMS +A space separated list of package names or slot atoms. Emerge will prefer +matching binary packages over newer unbuilt packages. +.TP .BR "\-\-usepkg [ y | n ] (\-k short option)" Tells emerge to use binary packages (from $PKGDIR) if they are available, thus possibly avoiding some time\-consuming compiles. This option is useful for CD diff --git a/pym/_emerge/depgraph.py b/pym/_emerge/depgraph.py index a0a4622ee..84e7d24f1 100644 --- a/pym/_emerge/depgraph.py +++ b/pym/_emerge/depgraph.py @@ -70,6 +70,16 @@ class _scheduler_graph_config(object): self.graph = graph self.mergelist = mergelist +def _wildcard_set(atoms): + pkgs = InternalPackageSet(allow_wildcard=True) + for x in atoms: + try: + x = Atom(x, allow_wildcard=True) + except portage.exception.InvalidAtom: + x = Atom("*/" + x, allow_wildcard=True) + pkgs.add(x) + return pkgs + class _frozen_depgraph_config(object): def __init__(self, settings, trees, myopts, spinner): @@ -109,13 +119,14 @@ class _frozen_depgraph_config(object): self._required_set_names = set(["world"]) - self.excluded_pkgs = InternalPackageSet(allow_wildcard=True) - for x in ' '.join(myopts.get("--exclude", [])).split(): - try: - x = Atom(x, allow_wildcard=True) - except portage.exception.InvalidAtom: - x = Atom("*/" + x, allow_wildcard=True) - self.excluded_pkgs.add(x) + atoms = ' '.join(myopts.get("--exclude", [])).split() + self.excluded_pkgs = _wildcard_set(atoms) + atoms = ' '.join(myopts.get("--reinstall-atoms", [])).split() + self.reinstall_atoms = _wildcard_set(atoms) + atoms = ' '.join(myopts.get("--nousepkg-atoms", [])).split() + self.nousepkg_atoms = _wildcard_set(atoms) + atoms = ' '.join(myopts.get("--useoldpkg-atoms", [])).split() + self.useoldpkg_atoms = _wildcard_set(atoms) class _depgraph_sets(object): def __init__(self): @@ -1237,6 +1248,7 @@ class depgraph(object): vardb = root_config.trees["vartree"].dbapi traversed_virt_pkgs = set() + reinstall_atoms = self._frozen_config.reinstall_atoms for atom, child in self._minimize_children( pkg, dep_priority, root_config, selected_atoms[pkg]): @@ -1254,7 +1266,9 @@ class depgraph(object): mypriority = dep_priority.copy() if not atom.blocker: - inst_pkgs = vardb.match_pkgs(atom) + inst_pkgs = [inst_pkg for inst_pkg in vardb.match_pkgs(atom) + if not reinstall_atoms.findAtomForPackage(inst_pkg, + modified_use=self._pkg_use_enabled(inst_pkg))] if inst_pkgs: for inst_pkg in inst_pkgs: if self._pkg_visibility_check(inst_pkg): @@ -1344,7 +1358,9 @@ class depgraph(object): # This is a GLEP 37 virtual, so its deps are all runtime. mypriority = self._priority(runtime=True) if not atom.blocker: - inst_pkgs = vardb.match_pkgs(atom) + inst_pkgs = [inst_pkg for inst_pkg in vardb.match_pkgs(atom) + if not reinstall_atoms.findAtomForPackage(inst_pkg, + modified_use=self._pkg_use_enabled(inst_pkg))] if inst_pkgs: for inst_pkg in inst_pkgs: if self._pkg_visibility_check(inst_pkg): @@ -3161,6 +3177,10 @@ class depgraph(object): dont_miss_updates = "--update" in self._frozen_config.myopts use_ebuild_visibility = self._frozen_config.myopts.get( '--use-ebuild-visibility', 'n') != 'n' + reinstall_atoms = self._frozen_config.reinstall_atoms + nousepkg_atoms = self._frozen_config.nousepkg_atoms + useoldpkg_atoms = self._frozen_config.useoldpkg_atoms + matched_oldpkg = [] # Behavior of the "selective" parameter depends on # whether or not a package matches an argument atom. # If an installed package provides an old-style @@ -3200,7 +3220,14 @@ class depgraph(object): modified_use=self._pkg_use_enabled(pkg)): continue - if packages_with_invalid_use_config and \ + if built and not installed and nousepkg_atoms.findAtomForPackage(pkg, \ + modified_use=self._pkg_use_enabled(pkg)): + break + + useoldpkg = useoldpkg_atoms.findAtomForPackage(pkg, \ + modified_use=self._pkg_use_enabled(pkg)) + + if packages_with_invalid_use_config and (not built or not useoldpkg) and \ (not pkg.installed or dont_miss_updates): # Check if a higher version was rejected due to user # USE configuration. The packages_with_invalid_use_config @@ -3282,7 +3309,7 @@ class depgraph(object): # instances (installed or binary). # If --usepkgonly is enabled, assume that # the ebuild status should be ignored. - if not use_ebuild_visibility and usepkgonly: + if not use_ebuild_visibility and (usepkgonly or useoldpkg): if pkg.installed and pkg.masks: continue else: @@ -3419,7 +3446,7 @@ class depgraph(object): break # Compare built package to current config and # reject the built package if necessary. - if built and (not installed or matched_pkgs_ignore_use) and \ + if built and not useoldpkg and (not installed or matched_pkgs_ignore_use) and \ ("--newuse" in self._frozen_config.myopts or \ "--reinstall" in self._frozen_config.myopts or \ "--binpkg-respect-use" in self._frozen_config.myopts): @@ -3434,7 +3461,7 @@ class depgraph(object): forced_flags.update(pkgsettings.useforce) forced_flags.update(pkgsettings.usemask) cur_iuse = iuses - if myeb and not usepkgonly: + if myeb and not usepkgonly and not useoldpkg: cur_iuse = myeb.iuse.all if self._reinstall_for_flags(forced_flags, old_use, iuses, @@ -3442,7 +3469,7 @@ class depgraph(object): break # Compare current config to installed package # and do not reinstall if possible. - if not installed and \ + if not installed and not useoldpkg and \ ("--newuse" in self._frozen_config.myopts or \ "--reinstall" in self._frozen_config.myopts) and \ cpv in vardb.match(atom): @@ -3460,8 +3487,13 @@ class depgraph(object): cur_use, cur_iuse) if reinstall_for_flags: reinstall = True + if reinstall_atoms.findAtomForPackage(pkg, \ + modified_use=self._pkg_use_enabled(pkg)): + reinstall = True if not built: myeb = pkg + elif useoldpkg: + matched_oldpkg.append(pkg) matched_packages.append(pkg) if reinstall_for_flags: self._dynamic_config._reinstall_nodes[pkg] = \ @@ -3545,14 +3577,20 @@ class depgraph(object): allow_license_changes=allow_license_changes): return pkg, existing_node - bestmatch = portage.best( - [pkg.cpv for pkg in matched_packages \ + visible_matches = [] + if matched_oldpkg: + visible_matches = [pkg.cpv for pkg in matched_oldpkg \ if self._pkg_visibility_check(pkg, allow_unstable_keywords=allow_unstable_keywords, - allow_license_changes=allow_license_changes)]) - if not bestmatch: + allow_license_changes=allow_license_changes)] + if not visible_matches: + visible_matches = [pkg.cpv for pkg in matched_packages \ + if self._pkg_visibility_check(pkg, allow_unstable_keywords=allow_unstable_keywords, + allow_license_changes=allow_license_changes)] + if visible_matches: + bestmatch = portage.best(visible_matches) + else: # all are masked, so ignore visibility - bestmatch = portage.best( - [pkg.cpv for pkg in matched_packages]) + bestmatch = portage.best([pkg.cpv for pkg in matched_packages]) matched_packages = [pkg for pkg in matched_packages \ if portage.dep.cpvequal(pkg.cpv, bestmatch)] diff --git a/pym/_emerge/main.py b/pym/_emerge/main.py index 96fee89ab..6ae267f5a 100644 --- a/pym/_emerge/main.py +++ b/pym/_emerge/main.py @@ -544,6 +544,23 @@ def insert_optional_args(args): return new_args +def _find_bad_atoms(atoms): + bad_atoms = [] + for x in ' '.join(atoms).split(): + bad_atom = False + try: + atom = portage.dep.Atom(x, allow_wildcard=True) + except portage.exception.InvalidAtom: + try: + atom = portage.dep.Atom("*/"+x, allow_wildcard=True) + except portage.exception.InvalidAtom: + bad_atom = True + + if bad_atom or atom.operator or atom.blocker or atom.use: + bad_atoms.append(x) + return bad_atoms + + def parse_opts(tmpcmdline, silent=False): myaction=None myopts = {} @@ -680,6 +697,14 @@ def parse_opts(tmpcmdline, silent=False): "choices":["changed-use"] }, + "--reinstall-atoms": { + "help" :"A space separated list of package names or slot atoms. " + \ + "Emerge will treat matching packages as if they are not " + \ + "installed, and reinstall them if necessary. Implies --deep.", + + "action" : "append", + }, + "--binpkg-respect-use": { "help" : "discard binary packages if their use flags \ don't match the current configuration", @@ -701,6 +726,13 @@ def parse_opts(tmpcmdline, silent=False): "choices" : true_y_or_n }, + "--nousepkg-atoms": { + "help" :"A space separated list of package names or slot atoms. " + \ + "Emerge will ignore matching binary packages. ", + + "action" : "append", + }, + "--package-moves": { "help" : "perform package moves when necessary", "type" : "choice", @@ -764,6 +796,13 @@ def parse_opts(tmpcmdline, silent=False): "choices" : true_y_or_n }, + "--useoldpkg-atoms": { + "help" :"A space separated list of package names or slot atoms. " + \ + "Emerge will prefer matching binary packages over newer unbuilt packages. ", + + "action" : "append", + }, + "--usepkg": { "shortopt" : "-k", "help" : "use binary packages", @@ -852,30 +891,29 @@ def parse_opts(tmpcmdline, silent=False): myoptions.depclean_lib_check = True if myoptions.exclude: - exclude = [] - bad_atoms = [] - for x in ' '.join(myoptions.exclude).split(): - bad_atom = False - try: - atom = portage.dep.Atom(x, allow_wildcard=True) - except portage.exception.InvalidAtom: - try: - atom = portage.dep.Atom("*/"+x, allow_wildcard=True) - except portage.exception.InvalidAtom: - bad_atom = True - - if bad_atom: - bad_atoms.append(x) - else: - if atom.operator or atom.blocker or atom.use: - bad_atoms.append(x) - else: - exclude.append(atom) - + bad_atoms = _find_bad_atoms(myoptions.exclude) if bad_atoms and not silent: parser.error("Invalid Atom(s) in --exclude parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \ (",".join(bad_atoms),)) + if myoptions.reinstall_atoms: + bad_atoms = _find_bad_atoms(myoptions.reinstall_atoms) + if bad_atoms and not silent: + parser.error("Invalid Atom(s) in --reinstall-atoms parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \ + (",".join(bad_atoms),)) + + if myoptions.nousepkg_atoms: + bad_atoms = _find_bad_atoms(myoptions.nousepkg_atoms) + if bad_atoms and not silent: + parser.error("Invalid Atom(s) in --nousepkg-atoms parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \ + (",".join(bad_atoms),)) + + if myoptions.useoldpkg_atoms: + bad_atoms = _find_bad_atoms(myoptions.useoldpkg_atoms) + if bad_atoms and not silent: + parser.error("Invalid Atom(s) in --useoldpkg-atoms parameter: '%s' (only package names and slot atoms (with wildcards) allowed)\n" % \ + (",".join(bad_atoms),)) + if myoptions.fail_clean in true_y: myoptions.fail_clean = True -- 2.26.2