commit:     b6a2901f66b6c242bff58e91d600d9529c0732a3
Author:     Zac Medico <zmedico <AT> gentoo <DOT> org>
AuthorDate: Sun Dec 15 19:49:00 2024 +0000
Commit:     Zac Medico <zmedico <AT> gentoo <DOT> org>
CommitDate: Mon Dec 16 02:26:22 2024 +0000
URL:        https://gitweb.gentoo.org/proj/portage.git/commit/?id=b6a2901f

Support cross-root package moves

Bug: https://bugs.gentoo.org/946326
Signed-off-by: Zac Medico <zmedico <AT> gentoo.org>

 NEWS                                            |  2 ++
 bin/fixpackages                                 |  4 ++-
 lib/_emerge/actions.py                          | 47 +++++++++++++++----------
 lib/portage/_global_updates.py                  | 15 ++++----
 lib/portage/emaint/modules/sync/sync.py         | 24 +++++++++----
 lib/portage/tests/update/test_move_ent.py       |  6 ++--
 lib/portage/tests/update/test_move_slot_ent.py  |  4 +--
 lib/portage/tests/update/test_update_dbentry.py |  4 +--
 8 files changed, 67 insertions(+), 39 deletions(-)

diff --git a/NEWS b/NEWS
index 2e61f995bb..2ba46c04b7 100644
--- a/NEWS
+++ b/NEWS
@@ -23,6 +23,8 @@ Bug fixes:
 
 * eend: Missing argument is now an error (bug #703520).
 
+* Support cross-root package moves (bug #946326).
+
 portage-3.0.66.1 (2024-09-18)
 --------------
 

diff --git a/bin/fixpackages b/bin/fixpackages
index 76c8f6d388..ea8986eebe 100755
--- a/bin/fixpackages
+++ b/bin/fixpackages
@@ -54,7 +54,9 @@ def main():
         portage.writemsg(f"!!! {str(e)}\n")
         del e
 
-    _global_updates(mytrees, mtimedb["updates"], if_mtime_changed=False)
+    _global_updates(
+        mysettings["EROOT"], mytrees, mtimedb["updates"], 
if_mtime_changed=False
+    )
 
     print()
     print("Done.")

diff --git a/lib/_emerge/actions.py b/lib/_emerge/actions.py
index 4554445999..65702d38fb 100644
--- a/lib/_emerge/actions.py
+++ b/lib/_emerge/actions.py
@@ -2956,6 +2956,12 @@ def load_emerge_config(emerge_config=None, env=None, 
**kargs):
     emerge_config.running_config = emerge_config.trees[
         emerge_config.trees._running_eroot
     ]["root_config"]
+    if target_eroot != emerge_config.trees._running_eroot:
+        emerge_config.running_config.mtimedb = portage.MtimeDB(
+            os.path.join(
+                emerge_config.trees._running_eroot, portage.CACHE_PATH, 
"mtimedb"
+            )
+        )
     QueryCommand._db = emerge_config.trees
 
     return emerge_config
@@ -3433,25 +3439,30 @@ def repo_name_duplicate_check(trees):
 
 def run_action(emerge_config):
     # skip global updates prior to sync, since it's called after sync
-    if (
-        emerge_config.action not in ("help", "info", "sync", "version")
-        and emerge_config.opts.get("--package-moves") != "n"
-        and _global_updates(
-            emerge_config.trees,
-            emerge_config.target_config.mtimedb["updates"],
-            quiet=("--quiet" in emerge_config.opts),
-        )
-    ):
-        emerge_config.target_config.mtimedb.commit()
-        # Reload the whole config from scratch.
-        load_emerge_config(emerge_config=emerge_config)
+    configs = [emerge_config.target_config]
+    if emerge_config.target_config.root != emerge_config.running_config.root:
+        configs.append(emerge_config.running_config)
+    for root_config in configs:
+        if (
+            emerge_config.action not in ("help", "info", "sync", "version")
+            and emerge_config.opts.get("--package-moves") != "n"
+            and _global_updates(
+                root_config.root,
+                emerge_config.trees,
+                root_config.mtimedb["updates"],
+                quiet=("--quiet" in emerge_config.opts),
+            )
+        ):
+            root_config.mtimedb.commit()
+            # Reload the whole config from scratch.
+            load_emerge_config(emerge_config=emerge_config)
 
-        # Let's autoclean if we applied updates, rather than always doing it
-        # bug #792195
-        emerge_config.target_config.settings.unlock()
-        emerge_config.target_config.settings["AUTOCLEAN"] = "yes"
-        emerge_config.target_config.settings.backup_changes("AUTOCLEAN")
-        emerge_config.target_config.settings.lock()
+            # Let's autoclean if we applied updates, rather than always doing 
it
+            # bug #792195
+            root_config.settings.unlock()
+            root_config.settings["AUTOCLEAN"] = "yes"
+            root_config.settings.backup_changes("AUTOCLEAN")
+            root_config.settings.lock()
 
     xterm_titles = "notitles" not in 
emerge_config.target_config.settings.features
     if xterm_titles:

diff --git a/lib/portage/_global_updates.py b/lib/portage/_global_updates.py
index 4ed8a3f9a7..82e0372eee 100644
--- a/lib/portage/_global_updates.py
+++ b/lib/portage/_global_updates.py
@@ -18,7 +18,7 @@ from portage.update import (
 from portage.util import grabfile, writemsg, writemsg_stdout, write_atomic
 
 
-def _global_updates(trees, prev_mtimes, quiet=False, if_mtime_changed=True):
+def _global_updates(root, trees, prev_mtimes, quiet=False, 
if_mtime_changed=True):
     """
     Perform new global updates if they exist in 'profiles/updates/'
     subdirectories of all active repositories (PORTDIR + PORTDIR_OVERLAY).
@@ -35,21 +35,24 @@ def _global_updates(trees, prev_mtimes, quiet=False, 
if_mtime_changed=True):
     """
     # only do this if we're root and not running repoman/ebuild digest
 
-    if secpass < 2 or "SANDBOX_ACTIVE" in os.environ or len(trees) != 1:
+    if secpass < 2 or "SANDBOX_ACTIVE" in os.environ:
         return False
 
-    vardb = trees[trees._running_eroot]["vartree"].dbapi
+    vardb = trees[root]["vartree"].dbapi
     vardb.lock()
     try:
         return _do_global_updates(
-            trees, prev_mtimes, quiet=quiet, if_mtime_changed=if_mtime_changed
+            root,
+            trees,
+            prev_mtimes,
+            quiet=quiet,
+            if_mtime_changed=if_mtime_changed,
         )
     finally:
         vardb.unlock()
 
 
-def _do_global_updates(trees, prev_mtimes, quiet=False, if_mtime_changed=True):
-    root = trees._running_eroot
+def _do_global_updates(root, trees, prev_mtimes, quiet=False, 
if_mtime_changed=True):
     mysettings = trees[root]["vartree"].settings
     portdb = trees[root]["porttree"].dbapi
     vardb = trees[root]["vartree"].dbapi

diff --git a/lib/portage/emaint/modules/sync/sync.py 
b/lib/portage/emaint/modules/sync/sync.py
index 3c397c2a4b..ac0b41cb73 100644
--- a/lib/portage/emaint/modules/sync/sync.py
+++ b/lib/portage/emaint/modules/sync/sync.py
@@ -270,14 +270,24 @@ class SyncRepos:
         return (returncode, None)
 
     def _do_pkg_moves(self):
-        if self.emerge_config.opts.get("--package-moves") != "n" and 
_global_updates(
-            self.emerge_config.trees,
-            self.emerge_config.target_config.mtimedb["updates"],
-            quiet=("--quiet" in self.emerge_config.opts),
+        configs = [self.emerge_config.target_config]
+        if (
+            self.emerge_config.target_config.root
+            != self.emerge_config.running_config.root
         ):
-            self.emerge_config.target_config.mtimedb.commit()
-            # Reload the whole config.
-            self._reload_config()
+            configs.append(self.emerge_config.running_config)
+        for root_config in configs:
+            if self.emerge_config.opts.get(
+                "--package-moves"
+            ) != "n" and _global_updates(
+                root_config.root,
+                self.emerge_config.trees,
+                root_config.mtimedb["updates"],
+                quiet=("--quiet" in self.emerge_config.opts),
+            ):
+                root_config.mtimedb.commit()
+                # Reload the whole config.
+                self._reload_config()
 
     def _check_updates(self):
         mybestpv = 
self.emerge_config.target_config.trees["porttree"].dbapi.xmatch(

diff --git a/lib/portage/tests/update/test_move_ent.py 
b/lib/portage/tests/update/test_move_ent.py
index 99e725e1c6..7f10b075fc 100644
--- a/lib/portage/tests/update/test_move_ent.py
+++ b/lib/portage/tests/update/test_move_ent.py
@@ -93,7 +93,7 @@ class MoveEntTestCase(TestCase):
                     global_noiselimit = portage.util.noiselimit
                     portage.util.noiselimit = -2
                     try:
-                        _do_global_updates(trees, {})
+                        _do_global_updates(trees._running_eroot, trees, {})
                     finally:
                         portage.util.noiselimit = global_noiselimit
 
@@ -198,7 +198,7 @@ class MoveEntTestCase(TestCase):
                     global_noiselimit = portage.util.noiselimit
                     portage.util.noiselimit = -2
                     try:
-                        _do_global_updates(trees, {})
+                        _do_global_updates(trees._running_eroot, trees, {})
                     finally:
                         portage.util.noiselimit = global_noiselimit
 
@@ -318,7 +318,7 @@ class MoveEntTestCase(TestCase):
                     global_noiselimit = portage.util.noiselimit
                     portage.util.noiselimit = -2
                     try:
-                        _do_global_updates(trees, {})
+                        _do_global_updates(trees._running_eroot, trees, {})
                     finally:
                         portage.util.noiselimit = global_noiselimit
                 finally:

diff --git a/lib/portage/tests/update/test_move_slot_ent.py 
b/lib/portage/tests/update/test_move_slot_ent.py
index 62b5c35446..5dd1508c88 100644
--- a/lib/portage/tests/update/test_move_slot_ent.py
+++ b/lib/portage/tests/update/test_move_slot_ent.py
@@ -121,7 +121,7 @@ class MoveSlotEntTestCase(TestCase):
                     global_noiselimit = portage.util.noiselimit
                     portage.util.noiselimit = -2
                     try:
-                        _do_global_updates(trees, {})
+                        _do_global_updates(trees._running_eroot, trees, {})
                     finally:
                         portage.util.noiselimit = global_noiselimit
 
@@ -264,7 +264,7 @@ class MoveSlotEntTestCase(TestCase):
                     global_noiselimit = portage.util.noiselimit
                     portage.util.noiselimit = -2
                     try:
-                        _do_global_updates(trees, {})
+                        _do_global_updates(trees._running_eroot, trees, {})
                     finally:
                         portage.util.noiselimit = global_noiselimit
 

diff --git a/lib/portage/tests/update/test_update_dbentry.py 
b/lib/portage/tests/update/test_update_dbentry.py
index 3b3f0caae6..32335eaff0 100644
--- a/lib/portage/tests/update/test_update_dbentry.py
+++ b/lib/portage/tests/update/test_update_dbentry.py
@@ -312,7 +312,7 @@ class UpdateDbentryTestCase(TestCase):
                     global_noiselimit = portage.util.noiselimit
                     portage.util.noiselimit = -2
                     try:
-                        _do_global_updates(trees, {})
+                        _do_global_updates(trees._running_eroot, trees, {})
                     finally:
                         portage.util.noiselimit = global_noiselimit
 
@@ -478,7 +478,7 @@ class UpdateDbentryTestCase(TestCase):
                     global_noiselimit = portage.util.noiselimit
                     portage.util.noiselimit = -2
                     try:
-                        _do_global_updates(trees, {})
+                        _do_global_updates(trees._running_eroot, trees, {})
                     finally:
                         portage.util.noiselimit = global_noiselimit
 

Reply via email to