Make update_config_files() take a dict of {repo_name: list} since it's more
authorZac Medico <zmedico@gentoo.org>
Sun, 1 Aug 2010 08:14:51 +0000 (01:14 -0700)
committerZac Medico <zmedico@gentoo.org>
Sun, 1 Aug 2010 08:14:51 +0000 (01:14 -0700)
efficient this way, and this function can't be called separately for each
repo if /etc/portage is under CONFIG_PROTECT (because it would produce
separate updated files for each repo).

pym/portage/_global_updates.py
pym/portage/update.py

index 7e6ae3300774dd403e6b11fa8e38b5942bb40de9..e9ec45305096498fd061af996e035b10cb173b4e 100644 (file)
@@ -142,10 +142,6 @@ def _global_updates(trees, prev_mtimes):
                                                if _world_repo_match(atom, new_atom):
                                                        world_list[pos] = new_atom
                                                        world_modified = True
-                       update_config_files(root,
-                               shlex_split(mysettings.get("CONFIG_PROTECT", "")),
-                               shlex_split(mysettings.get("CONFIG_PROTECT_MASK", "")),
-                               myupd, match_callback=_world_repo_match)
 
                        for update_cmd in myupd:
                                if update_cmd[0] == "move":
@@ -167,6 +163,27 @@ def _global_updates(trees, prev_mtimes):
 
        if retupd:
 
+                       def _config_repo_match(repo_name, atoma, atomb):
+                               """
+                               Check whether to perform a world change from atoma to atomb.
+                               If best vardb match for atoma comes from the same repository
+                               as the update file, allow that. Additionally, if portdb still
+                               can find a match for old atom name, warn about that.
+                               """
+                               matches = vardb.match(atoma)
+                               if not matches:
+                                       matches = vardb.match(atomb)
+                                       if not matches:
+                                               return False
+                               repository = vardb.aux_get(best(matches), ['repository'])[0]
+                               return repository == repo_name or \
+                                       (repo_name == master_repo and repository not in repo_map)
+
+                       update_config_files(root,
+                               shlex_split(mysettings.get("CONFIG_PROTECT", "")),
+                               shlex_split(mysettings.get("CONFIG_PROTECT_MASK", "")),
+                               repo_map, match_callback=_config_repo_match)
+
                        # The above global updates proceed quickly, so they
                        # are considered a single mtimedb transaction.
                        if timestamps:
index b24c9cb0ce87ec582d533235efe96f427425b32d..7892f537d073831de9436ffba2fdc4643226aa3e 100644 (file)
@@ -187,10 +187,18 @@ def update_config_files(config_root, protect, protect_mask, update_iter, match_c
        config_root - location of files to update
        protect - list of paths from CONFIG_PROTECT
        protect_mask - list of paths from CONFIG_PROTECT_MASK
-       update_iter - list of update commands as returned from parse_updates()
-       match_callback - a callback which will be called with old and new atoms
+       update_iter - list of update commands as returned from parse_updates(),
+               or dict of {repo_name: list}
+       match_callback - a callback which will be called with three arguments:
+               match_callback(repo_name, old_atom, new_atom)
        and should return boolean value determining whether to perform the update"""
 
+       repo_dict = None
+       if isinstance(update_iter, dict):
+               repo_dict = update_iter
+       if match_callback is None:
+               def match_callback(repo_name, atoma, atomb):
+                       return True
        config_root = normalize_path(config_root)
        update_files = {}
        file_contents = {}
@@ -242,24 +250,29 @@ def update_config_files(config_root, protect, protect_mask, update_iter, match_c
 
        # update /etc/portage/packages.*
        ignore_line_re = re.compile(r'^#|^\s*$')
-       for update_cmd in update_iter:
-               for x, contents in file_contents.items():
-                       for pos, line in enumerate(contents):
-                               if ignore_line_re.match(line):
-                                       continue
-                               atom = line.split()[0]
-                               if atom.startswith("-"):
-                                       # package.mask supports incrementals
-                                       atom = atom[1:]
-                               if not isvalidatom(atom):
-                                       continue
-                               new_atom = update_dbentry(update_cmd, atom)
-                               if atom != new_atom:
-                                       if match_callback(atom, new_atom):
-                                               contents[pos] = line.replace(atom, new_atom)
-                                               update_files[x] = 1
-                                               sys.stdout.write("p")
-                                               sys.stdout.flush()
+       if repo_dict is None:
+               update_items = [(None, update_iter)]
+       else:
+               update_items = [x for x in repo_dict.items() if x[0] != 'DEFAULT']
+       for repo_name, update_iter in update_items:
+               for update_cmd in update_iter:
+                       for x, contents in file_contents.items():
+                               for pos, line in enumerate(contents):
+                                       if ignore_line_re.match(line):
+                                               continue
+                                       atom = line.split()[0]
+                                       if atom[:1] == "-":
+                                               # package.mask supports incrementals
+                                               atom = atom[1:]
+                                       if not isvalidatom(atom):
+                                               continue
+                                       new_atom = update_dbentry(update_cmd, atom)
+                                       if atom != new_atom:
+                                               if match_callback(repo_name, atom, new_atom):
+                                                       contents[pos] = line.replace(atom, new_atom, 1)
+                                                       update_files[x] = 1
+                                                       sys.stdout.write("p")
+                                                       sys.stdout.flush()
 
        protect_obj = ConfigProtect(
                config_root, protect, protect_mask)