* [gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/, /, man/
@ 2023-02-21 7:16 Sam James
0 siblings, 0 replies; only message in thread
From: Sam James @ 2023-02-21 7:16 UTC (permalink / raw
To: gentoo-commits
commit: 75a4f2c2e07c128fef4d9faf3a8fb9d67565239e
Author: Sam James <sam <AT> gentoo <DOT> org>
AuthorDate: Thu Feb 16 06:26:07 2023 +0000
Commit: Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Tue Feb 21 07:16:27 2023 +0000
URL: https://gitweb.gentoo.org/proj/portage.git/commit/?id=75a4f2c2
emerge: add --update-if-installed
This adds a new emerge option '--update-if-installed'.
The use case for such an option is as follows:
- User finds out libfoo-1.2 is buggy.
- They want to upgrade all their systems if libfoo is installed.
- They don't want to install libfoo if it's not already installed.
Unfortunately, --update fails this last point, hence
the need for a new option.
Closes: https://github.com/gentoo/portage/pull/988
Signed-off-by: Sam James <sam <AT> gentoo.org>
NEWS | 4 ++
lib/_emerge/create_depgraph_params.py | 6 ++
lib/_emerge/depgraph.py | 17 ++++-
lib/_emerge/main.py | 3 +-
lib/portage/tests/resolver/test_update.py | 106 ++++++++++++++++++++++++++++++
man/emerge.1 | 6 ++
6 files changed, 140 insertions(+), 2 deletions(-)
diff --git a/NEWS b/NEWS
index 29e9de038..9389d2c09 100644
--- a/NEWS
+++ b/NEWS
@@ -10,6 +10,10 @@ Features:
* emerge: add --onlydeps-with-ideps=<y|n> option (bug #890777)
+* emerge: add --update-if-installed option. This is useful for one-shot
+ emerge commands to be run across several machines to upgrade packages
+ only if they're installed.
+
* install-qa-check.d: 60pkgconfig: add opt-in QA_PKGCONFIG_VERSION check
* emerge: Log completion of package installs.
diff --git a/lib/_emerge/create_depgraph_params.py b/lib/_emerge/create_depgraph_params.py
index 531230402..1bbca5de9 100644
--- a/lib/_emerge/create_depgraph_params.py
+++ b/lib/_emerge/create_depgraph_params.py
@@ -129,6 +129,12 @@ def create_depgraph_params(myopts, myaction):
if changed_slot:
myparams["changed_slot"] = True
+ # --update-if-installed implies --update
+ update_if_installed = myopts.get("--update-if-installed")
+ if update_if_installed is not None:
+ myparams["update_if_installed"] = update_if_installed
+ myopts["--update"] = True
+
if (
"--update" in myopts
or "--newrepo" in myopts
diff --git a/lib/_emerge/depgraph.py b/lib/_emerge/depgraph.py
index 1631ed126..412dc7b6f 100644
--- a/lib/_emerge/depgraph.py
+++ b/lib/_emerge/depgraph.py
@@ -1,4 +1,4 @@
-# Copyright 1999-2021 Gentoo Authors
+# Copyright 1999-2023 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import errno
@@ -5019,6 +5019,21 @@ class depgraph:
pkg, existing_node = self._select_package(
myroot, atom, onlydeps=onlydeps
)
+
+ # Is the package installed (at any version)?
+ if pkg and "update_if_installed" in self._dynamic_config.myparams:
+ package_is_installed = any(
+ self._iter_match_pkgs(
+ self._frozen_config.roots[myroot], "installed", atom
+ )
+ )
+
+ # This package isn't eligible for selection in the
+ # merge list as the user passed --update-if-installed
+ # and it isn't installed.
+ if not package_is_installed:
+ continue
+
if not pkg:
pprovided_match = False
for virt_choice in virtuals.get(atom.cp, []):
diff --git a/lib/_emerge/main.py b/lib/_emerge/main.py
index 38233e05c..850487d36 100644
--- a/lib/_emerge/main.py
+++ b/lib/_emerge/main.py
@@ -1,4 +1,4 @@
-# Copyright 1999-2020 Gentoo Authors
+# Copyright 1999-2023 Gentoo Authors
# Distributed under the terms of the GNU General Public License v2
import argparse
@@ -52,6 +52,7 @@ options = [
"--tree",
"--unordered-display",
"--update",
+ "--update-if-installed",
]
shortmapping = {
diff --git a/lib/portage/tests/resolver/test_update.py b/lib/portage/tests/resolver/test_update.py
new file mode 100644
index 000000000..e67013f9f
--- /dev/null
+++ b/lib/portage/tests/resolver/test_update.py
@@ -0,0 +1,106 @@
+# Copyright 2022-2023 Gentoo Authors
+# Distributed under the terms of the GNU General Public License v2
+
+from portage.tests import TestCase
+from portage.tests.resolver.ResolverPlayground import (
+ ResolverPlayground,
+ ResolverPlaygroundTestCase,
+)
+
+
+class UpdateIfInstalledTestCase(TestCase):
+ def testUpdateIfInstalledEmerge(self):
+ installed = {
+ "dev-lang/ghc-4": {},
+ "dev-libs/larryware-3": {},
+ "dev-libs/larryware-ng-3": {},
+ "virtual/libc-1": {},
+ }
+
+ ebuilds = installed.copy()
+ ebuilds.update(
+ {
+ "app-misc/cowsay-10": {},
+ "dev-lang/ghc-5": {},
+ "dev-libs/larryware-4": {},
+ "dev-libs/larryware-ng-4": {"RDEPEND": ">=net-libs/moo-1"},
+ "net-libs/moo-1": {},
+ }
+ )
+
+ playground = ResolverPlayground(
+ ebuilds=ebuilds, installed=installed, debug=False
+ )
+
+ test_cases = (
+ # We should only try to update ghc when passed ghc and
+ # --update-if-installed. We don't want larryware to appear here,
+ # despite it being eligible for an upgrade otherwise with --update.
+ ResolverPlaygroundTestCase(
+ ["dev-lang/ghc"],
+ mergelist=["dev-lang/ghc-5"],
+ options={
+ "--update-if-installed": True,
+ },
+ success=True,
+ ),
+ # Only try to upgrade ghc even if passed another candidate,
+ # as there's no upgrade due for it. We don't want to
+ # reinstall virtual/libc for the sake of it.
+ ResolverPlaygroundTestCase(
+ ["dev-lang/ghc", "virtual/libc"],
+ mergelist=["dev-lang/ghc-5"],
+ options={
+ "--update-if-installed": True,
+ },
+ success=True,
+ ),
+ # Try to upgrade a package with no new versions available.
+ # This is just checking we still have --update semantics.
+ ResolverPlaygroundTestCase(
+ ["virtual/libc"],
+ mergelist=[],
+ options={
+ "--update-if-installed": True,
+ },
+ success=True,
+ ),
+ # If a new package is given, we want to do nothing.
+ ResolverPlaygroundTestCase(
+ ["app-misc/cowsay"],
+ mergelist=[],
+ options={
+ "--update-if-installed": True,
+ },
+ success=True,
+ ),
+ # If a new package (app-misc/cowsay) is given combined with
+ # a package eligible for an upgrade (dev-libs/larryware),
+ # upgrade just the latter.
+ ResolverPlaygroundTestCase(
+ ["app-misc/cowsay", "dev-libs/larryware"],
+ mergelist=["dev-libs/larryware-4"],
+ options={
+ "--update-if-installed": True,
+ },
+ success=True,
+ ),
+ # Make sure that we can still pull in upgrades as
+ # dependencies (net-libs/moo) of the package we requested
+ # (dev-libs/larryware-ng).
+ ResolverPlaygroundTestCase(
+ ["dev-libs/larryware-ng"],
+ mergelist=["net-libs/moo-1", "dev-libs/larryware-ng-4"],
+ options={
+ "--update-if-installed": True,
+ },
+ success=True,
+ ),
+ )
+
+ try:
+ for test_case in test_cases:
+ playground.run_TestCase(test_case)
+ self.assertEqual(test_case.test_success, True, test_case.fail_msg)
+ finally:
+ playground.cleanup()
diff --git a/man/emerge.1 b/man/emerge.1
index c85ffd7b6..a1c5f33be 100644
--- a/man/emerge.1
+++ b/man/emerge.1
@@ -1054,6 +1054,12 @@ the command line are greedy, meaning that unspecific
atoms may match multiple versions of slotted packages.
This option also implies the \fB\-\-selective\fR option.
.TP
+.BR \-\-update\-if\-installed
+Acts similar to \fB\-\-update\fR except it updates packages
+passed as arguments to the best version available only if they are
+already installed. This is useful for oneshot commands across
+a series of systems to upgrade away from a buggy version.
+.TP
.BR "\-\-use\-ebuild\-visibility [ y | n ]"
Use unbuilt ebuild metadata for visibility
checks on built packages.
^ permalink raw reply related [flat|nested] only message in thread
only message in thread, other threads:[~2023-02-21 7:16 UTC | newest]
Thread overview: (only message) (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2023-02-21 7:16 [gentoo-commits] proj/portage:master commit in: lib/_emerge/, lib/portage/tests/resolver/, /, man/ Sam James
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox