Merged from trunk -r11531:11544
authorFabian Groffen <grobian@gentoo.org>
Sat, 27 Sep 2008 16:08:34 +0000 (16:08 -0000)
committerFabian Groffen <grobian@gentoo.org>
Sat, 27 Sep 2008 16:08:34 +0000 (16:08 -0000)
   | 11533   | don't attempt to unmerge a set that doesn't exist anymore    |
   | genone  |                                                              |

   | 11534   | remove deprecation warnings and compat code for 2.1 changes  |
   | genone  | to rsync and action argument syntax                          |

   | 11535   | Bug #230975 - Rename the portage.selinux module to           |
   | zmedico | portage._selinux in order to avoid a relative import issue   |
   |         | which caused portage.selinux to attempt to import itself     |
   |         | instead of the real 'selinux' module. Thanks to Michael      |
   |         | Edenfield for this patch.                                    |

   | 11536   | Import cPickle as pickle instead of vice versa. Eases 2to3's |
   | zmedico | job because cPickle won't exist in py3k and 2to3 does        |
   |         | s/cPickle/pickle. Thanks to Ali Polatel <hawking@g.o> for    |
   |         | this patch.                                                  |

   | 11537   | Fix fetch() mirror:// handling in to comply with section     |
   | zmedico | 9.2.8 of PMS.                                                |

   | 11538   | Bug #238550 - Set world-candidate = False for the @system    |
   | zmedico | since the portage ebuild will now automatically add @system  |
   |         | to world_sets on upgrade and therefore it should no longer   |
   |         | be necessary to add it world_sets via the command line.      |

   | 11539   | Fix the case where all arguments are filtered out by         |
   | zmedico | PORTAGE_COMPRESS_EXCLUDE_SUFFIXES, since otherwise 'set' was |
   |         | called with no arguments which caused the environment to be  |
   |         | displayed on stdout.                                         |

   | 11540   | Add a new AgeSet class to select installed packages that     |
   | genone  | have been installed more/less than n days ago                |

   | 11541   | relocate the post_emerge call so it gets called in more      |
   | genone  | situations.                                                  |

   | 11542   | move set expansion code into its own function                |
   | genone  |                                                              |

   | 11543   | implement simple expression logic for apckage sets to        |
   | genone  | generate unions, intersections and differences of two or     |
   |         | more package sets                                            |

   | 11544   | change set expression syntax: operators now have a @ suffix  |
   | genone  | (IOW: all operands must be prefixed with @) to maintain      |
   |         | compability with existing set names containing hyphens       |

svn path=/main/branches/prefix/; revision=11571

bin/ecompress
cnf/sets.conf
pym/_emerge/__init__.py
pym/portage/__init__.py
pym/portage/_selinux.py [moved from pym/portage/selinux.py with 100% similarity]
pym/portage/dbapi/vartree.py
pym/portage/getbinpkg.py
pym/portage/sets/dbapi.py
pym/portage/util.py

index c5e82c021e79df8d23d5d11961f79e090e06d3e4..39985328c3769becc1176af2e5eaae3ee55e1293 100755 (executable)
@@ -77,7 +77,8 @@ case $1 in
                        filtered_args[$i]=$x
                        (( i++ ))
                done
-               set "${filtered_args[@]}"
+               [ $i -eq 0 ] && exit 0
+               set -- "${filtered_args[@]}"
 
                # If a compressed version of the file already exists, simply
                # delete it so that the compressor doesn't whine (bzip2 will
index c02d143ffd2a91d0cbb01f29c22c715cd4fd047f..f9f351be8e91b281e7231ec9ba67f2f1d4dc300e 100644 (file)
@@ -12,6 +12,7 @@ world-candidate = False
 # Same as for world, though later portage versions might use a different class
 [system]
 class = portage.sets.profiles.PackagesSystemSet
+world-candidate = False
 
 # For security there are multiple classes available, but differences are 
 # rather small (normally there should be no visible difference):
index f9cbf72025e0dc0abfa2697eebb0d67491546570..081bd7e2aa0f4b8057f7c34a7d0928aa8ae07be1 100644 (file)
@@ -88,9 +88,9 @@ from itertools import chain, izip
 from UserDict import DictMixin
 
 try:
-       import cPickle
+       import cPickle as pickle
 except ImportError:
-       import pickle as cPickle
+       import pickle
 
 try:
        import cStringIO as StringIO
@@ -3686,13 +3686,13 @@ class BlockerCache(DictMixin):
        def _load(self):
                try:
                        f = open(self._cache_filename)
-                       mypickle = cPickle.Unpickler(f)
+                       mypickle = pickle.Unpickler(f)
                        mypickle.find_global = None
                        self._cache_data = mypickle.load()
                        f.close()
                        del f
-               except (IOError, OSError, EOFError, cPickle.UnpicklingError), e:
-                       if isinstance(e, cPickle.UnpicklingError):
+               except (IOError, OSError, EOFError, pickle.UnpicklingError), e:
+                       if isinstance(e, pickle.UnpicklingError):
                                writemsg("!!! Error loading '%s': %s\n" % \
                                        (self._cache_filename, str(e)), noiselevel=-1)
                        del e
@@ -3772,7 +3772,7 @@ class BlockerCache(DictMixin):
                        secpass >= 2:
                        try:
                                f = portage.util.atomic_ofstream(self._cache_filename)
-                               cPickle.dump(self._cache_data, f, -1)
+                               pickle.dump(self._cache_data, f, -1)
                                f.close()
                                portage.util.apply_secpass_permissions(
                                        self._cache_filename, gid=portage.portage_gid, mode=0644)
@@ -10581,6 +10581,8 @@ def unmerge(root_config, myopts, unmerge_action,
                stop = True
                pos = len(installed_sets)
                for s in installed_sets[pos - 1:]:
+                       if s not in sets:
+                               continue
                        candidates = [x[len(SETPREFIX):] for x in sets[s].getNonAtoms() if x.startswith(SETPREFIX)]
                        if candidates:
                                stop = False
@@ -10916,6 +10918,30 @@ def display_news_notification(root_config, myopts):
                print "Use " + colorize("GOOD", "eselect news") + " to read news items."
                print
 
+def display_preserved_libs(vardbapi):
+       MAX_DISPLAY = 3
+
+       if vardbapi.plib_registry.hasEntries():
+               print
+               print colorize("WARN", "!!!") + " existing preserved libs:"
+               plibdata = vardbapi.plib_registry.getPreservedLibs()
+               linkmap = vardbapi.linkmap
+               for cpv in plibdata:
+                       print colorize("WARN", ">>>") + " package: %s" % cpv
+                       for f in plibdata[cpv]:
+                               print colorize("WARN", " * ") + " - %s" % f
+                               consumers = list(linkmap.findConsumers(f))
+                               consumers.sort()
+                               owners = vardbapi._owners.getFileOwnerMap(consumers[:MAX_DISPLAY+2])
+                               for c in consumers[:MAX_DISPLAY]:
+                                       print colorize("WARN", " * ") + "     used by %s (%s)" % (c, ", ".join([x.mycpv for x in owners[c]]))
+                               if len(consumers) > MAX_DISPLAY + 1:
+                                       print colorize("WARN", " * ") + "     used by %d other files" % (len(consumers) - MAX_DISPLAY)
+                               else:
+                                       print colorize("WARN", " * ") + "     used by %s (%s)" % (consumers[MAX_DISPLAY], ", ".join([x.mycpv for x in owners[consumers[MAX_DISPLAY]]]))
+               print "Use " + colorize("GOOD", "emerge @preserved-rebuild") + " to rebuild packages using these libraries"
+
+
 def _flush_elog_mod_echo():
        """
        Dump the mod_echo output now so that our other
@@ -10984,7 +11010,7 @@ def post_emerge(root_config, myopts, mtimedb, retval):
        vdb_path = os.path.join(target_root, portage.VDB_PATH)
        portage.util.ensure_dirs(vdb_path)
        vdb_lock = None
-       if os.access(vdb_path, os.W_OK):
+       if os.access(vdb_path, os.W_OK) and not "--pretend" in myopts:
                vdb_lock = portage.locks.lockdir(vdb_path)
 
        if vdb_lock:
@@ -11000,16 +11026,8 @@ def post_emerge(root_config, myopts, mtimedb, retval):
        chk_updated_cfg_files(target_root + EPREFIX, config_protect)
        
        display_news_notification(root_config, myopts)
-       
-       if vardbapi.plib_registry.hasEntries():
-               print
-               print colorize("WARN", "!!!") + " existing preserved libs:"
-               plibdata = vardbapi.plib_registry.getPreservedLibs()
-               for cpv in plibdata:
-                       print colorize("WARN", ">>>") + " package: %s" % cpv
-                       for f in plibdata[cpv]:
-                               print colorize("WARN", " * ") + " - %s" % f
-               print "Use " + colorize("GOOD", "emerge @preserved-rebuild") + " to rebuild packages using these libraries"
+       if retval in (None, os.EX_OK) or (not "--pretend" in myopts):
+               display_preserved_libs(vardbapi)        
 
        sys.exit(retval)
 
@@ -11197,18 +11215,7 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
                                        "PORTAGE_RSYNC_OPTS (can be overridden with --exclude='!')\n")
                                        rsync_opts.append(opt)
        
-                       if settings["RSYNC_TIMEOUT"] != "":
-                               portage.writemsg("WARNING: usage of RSYNC_TIMEOUT is deprecated, " + \
-                               "use PORTAGE_RSYNC_EXTRA_OPTS instead\n")
-                               try:
-                                       mytimeout = int(settings["RSYNC_TIMEOUT"])
-                                       rsync_opts.append("--timeout=%d" % mytimeout)
-                               except ValueError, e:
-                                       portage.writemsg("!!! %s\n" % str(e))
-       
-                       # TODO: determine options required for official servers
                        if syncuri.rstrip("/").endswith(".gentoo.org/gentoo-portage"):
-
                                def rsync_opt_startswith(opt_prefix):
                                        for x in rsync_opts:
                                                if x.startswith(opt_prefix):
@@ -11235,24 +11242,6 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
                if "--debug" in myopts:
                        rsync_opts.append("--checksum") # Force checksum on all files
 
-               if settings["RSYNC_EXCLUDEFROM"] != "":
-                       portage.writemsg(yellow("WARNING:") + \
-                       " usage of RSYNC_EXCLUDEFROM is deprecated, use " + \
-                       "PORTAGE_RSYNC_EXTRA_OPTS instead\n")
-                       if os.path.exists(settings["RSYNC_EXCLUDEFROM"]):
-                               rsync_opts.append("--exclude-from=%s" % \
-                               settings["RSYNC_EXCLUDEFROM"])
-                       else:
-                               portage.writemsg("!!! RSYNC_EXCLUDEFROM specified," + \
-                               " but file does not exist.\n")
-
-               if settings["RSYNC_RATELIMIT"] != "":
-                       portage.writemsg(yellow("WARNING:") + \
-                       " usage of RSYNC_RATELIMIT is deprecated, use " + \
-                       "PORTAGE_RSYNC_EXTRA_OPTS instead")
-                       rsync_opts.append("--bwlimit=%s" % \
-                       settings["RSYNC_RATELIMIT"])
-
                # Real local timestamp file.
                servertimestampfile = os.path.join(
                        myportdir, "metadata", "timestamp.chk")
@@ -11274,11 +11263,7 @@ def action_sync(settings, trees, mtimedb, myopts, myaction):
                        rsync_initial_timeout = 15
 
                try:
-                       if "RSYNC_RETRIES" in settings:
-                               print yellow("WARNING:")+" usage of RSYNC_RETRIES is deprecated, use PORTAGE_RSYNC_RETRIES instead"
-                               maxretries=int(settings["RSYNC_RETRIES"])                               
-                       else:
-                               maxretries=int(settings["PORTAGE_RSYNC_RETRIES"])
+                       maxretries=int(settings["PORTAGE_RSYNC_RETRIES"])
                except SystemExit, e:
                        raise # Needed else can't exit
                except:
@@ -13088,9 +13073,6 @@ def action_build(settings, trees, mtimedb,
                                        + " problems due to overlapping packages.\n")
                        trees[settings["ROOT"]]["vartree"].dbapi.plib_registry.pruneNonExisting()
 
-               if merge_count and not (buildpkgonly or fetchonly or pretend):
-                       root_config = trees[settings["ROOT"]]["root_config"]
-                       post_emerge(root_config, myopts, mtimedb, retval)
                return retval
 
 def multiple_actions(action1, action2):
@@ -13280,24 +13262,7 @@ def parse_opts(tmpcmdline, silent=False):
                                sys.exit(1)
                        myaction = action_opt
 
-       for x in myargs:
-               if x in actions and myaction != "search":
-                       if not silent:
-                               print red("*** Deprecated use of action '%s', use '--%s' instead" % (x,x))
-                       # special case "search" so people can search for action terms, e.g. emerge -s sync
-                       if myaction:
-                               multiple_actions(myaction, x)
-                               sys.exit(1)
-                       myaction = x
-               else:
-                       myfiles.append(x)
-
-       if "--nocolor" in myopts:
-               if not silent:
-                       sys.stderr.write("*** Deprecated use of '--nocolor', " + \
-                               "use '--color=n' instead.\n")
-               del myopts["--nocolor"]
-               myopts["--color"] = "n"
+       myfiles += myargs
 
        return myaction, myopts, myfiles
 
@@ -13478,6 +13443,110 @@ def display_missing_pkg_set(root_config, set_name):
        writemsg_level("".join("%s\n" % l for l in msg),
                level=logging.ERROR, noiselevel=-1)
 
+def expand_set_arguments(myfiles, myaction, root_config):
+       retval = os.EX_OK
+       setconfig = root_config.setconfig
+
+       # display errors that occured while loading the SetConfig instance
+       for e in setconfig.errors:
+               print colorize("BAD", "Error during set creation: %s" % e)
+       
+       sets = setconfig.getSets()
+
+       # emerge relies on the existance of sets with names "world" and "system"
+       required_sets = ("world", "system")
+
+       for s in required_sets:
+               if s not in sets:
+                       msg = ["emerge: incomplete set configuration, " + \
+                               "no \"%s\" set defined" % s]
+                       msg.append("        sets defined: %s" % ", ".join(sets))
+                       for line in msg:
+                               sys.stderr.write(line + "\n")
+                       retval = 1
+       unmerge_actions = ("unmerge", "prune", "clean", "depclean")
+       
+       # In order to know exactly which atoms/sets should be added to the
+       # world file, the depgraph performs set expansion later. It will get
+       # confused about where the atoms came from if it's not allowed to
+       # expand them itself.
+       do_not_expand = (None, )
+       newargs = []
+       for a in myfiles:
+               if a in ("system", "world"):
+                       newargs.append(SETPREFIX+a)
+               else:
+                       newargs.append(a)
+       myfiles = newargs
+       del newargs
+       newargs = []
+       
+       # WARNING: all operators must be of equal length
+       IS_OPERATOR = "/@"
+       DIFF_OPERATOR = "-@"
+       UNION_OPERATOR = "+@"
+       
+       for a in myfiles:
+               if a.startswith(SETPREFIX):
+                       # support simple set operations (intersection, difference and union)
+                       # on the commandline. Expressions are evaluated strictly left-to-right
+                       if IS_OPERATOR in a or DIFF_OPERATOR in a or UNION_OPERATOR in a:
+                               expression = a[len(SETPREFIX):]
+                               expr_sets = []
+                               expr_ops = []
+                               while IS_OPERATOR in expression or DIFF_OPERATOR in expression or UNION_OPERATOR in expression:
+                                       is_pos = expression.rfind(IS_OPERATOR)
+                                       diff_pos = expression.rfind(DIFF_OPERATOR)
+                                       union_pos = expression.rfind(UNION_OPERATOR)
+                                       op_pos = max(is_pos, diff_pos, union_pos)
+                                       s1 = expression[:op_pos]
+                                       s2 = expression[op_pos+len(IS_OPERATOR):]
+                                       op = expression[op_pos:op_pos+len(IS_OPERATOR)]
+                                       if not s2 in sets:
+                                               display_missing_pkg_set(root_config, s2)
+                                               return (None, 1)
+                                       expr_sets.insert(0, s2)
+                                       expr_ops.insert(0, op)
+                                       expression = s1
+                               if not expression in sets:
+                                       display_missing_pkg_set(root_config, expression)
+                                       return (None, 1)
+                               expr_sets.insert(0, expression)
+                               result = set(setconfig.getSetAtoms(expression))
+                               for i in range(0, len(expr_ops)):
+                                       s2 = setconfig.getSetAtoms(expr_sets[i+1])
+                                       if expr_ops[i] == IS_OPERATOR:
+                                               result.intersection_update(s2)
+                                       elif expr_ops[i] == DIFF_OPERATOR:
+                                               result.difference_update(s2)
+                                       elif expr_ops[i] == UNION_OPERATOR:
+                                               result.update(s2)
+                                       else:
+                                               raise NotImplementedError("unknown set operator %s" % expr_ops[i])
+                               newargs.extend(result)
+                       else:                   
+                               s = a[len(SETPREFIX):]
+                               if s not in sets:
+                                       display_missing_pkg_set(root_config, s)
+                                       return (None, 1)
+                               setconfig.active.append(s)
+                               if myaction in unmerge_actions and \
+                                               not sets[s].supportsOperation("unmerge"):
+                                       sys.stderr.write("emerge: the given set '%s' does " % s + \
+                                               "not support unmerge operations\n")
+                                       retval = 1
+                               elif not setconfig.getSetAtoms(s):
+                                       print "emerge: '%s' is an empty set" % s
+                               elif myaction not in do_not_expand:
+                                       newargs.extend(setconfig.getSetAtoms(s))
+                               else:
+                                       newargs.append(SETPREFIX+s)
+                               for e in sets[s].errors:
+                                       print e
+               else:
+                       newargs.append(a)
+       return (newargs, retval)
+
 def emerge_main():
        global portage  # NFC why this is necessary now - genone
        portage._disable_legacy_globals()
@@ -13617,62 +13686,10 @@ def emerge_main():
        # only expand sets for actions taking package arguments
        oldargs = myfiles[:]
        if myaction in ("clean", "config", "depclean", "info", "prune", "unmerge", None):
-               setconfig = root_config.setconfig
-               # display errors that occured while loading the SetConfig instance
-               for e in setconfig.errors:
-                       print colorize("BAD", "Error during set creation: %s" % e)
-               
-               sets = setconfig.getSets()
-               # emerge relies on the existance of sets with names "world" and "system"
-               required_sets = ("world", "system")
-               for s in required_sets:
-                       if s not in sets:
-                               msg = ["emerge: incomplete set configuration, " + \
-                                       "no \"%s\" set defined" % s]
-                               msg.append("        sets defined: %s" % ", ".join(sets))
-                               for line in msg:
-                                       sys.stderr.write(line + "\n")
-                               return 1
-               unmerge_actions = ("unmerge", "prune", "clean", "depclean")
-               
-               # In order to know exactly which atoms/sets should be added to the
-               # world file, the depgraph performs set expansion later. It will get
-               # confused about where the atoms came from if it's not allowed to
-               # expand them itself.
-               do_not_expand = (None, )
-               newargs = []
-               for a in myfiles:
-                       if a in ("system", "world"):
-                               newargs.append(SETPREFIX+a)
-                       else:
-                               newargs.append(a)
-               myfiles = newargs
-               del newargs
-               newargs = []
-               for a in myfiles:
-                       if a.startswith(SETPREFIX):
-                               s = a[len(SETPREFIX):]
-                               if s not in sets:
-                                       display_missing_pkg_set(root_config, s)
-                                       return 1
-                               setconfig.active.append(s)
-                               if myaction in unmerge_actions and \
-                                               not sets[s].supportsOperation("unmerge"):
-                                       sys.stderr.write("emerge: the given set '%s' does " % s + \
-                                               "not support unmerge operations\n")
-                                       return 1
-                               if not setconfig.getSetAtoms(s):
-                                       print "emerge: '%s' is an empty set" % s
-                               elif myaction not in do_not_expand:
-                                       newargs.extend(setconfig.getSetAtoms(s))
-                               else:
-                                       newargs.append(SETPREFIX+s)
-                               for e in sets[s].errors:
-                                       print e
-                       else:
-                               newargs.append(a)
-               myfiles = newargs
-               del newargs
+               myfiles, retval = expand_set_arguments(myfiles, myaction, root_config)
+               if retval != os.EX_OK:
+                       return retval
+
                # Need to handle empty sets specially, otherwise emerge will react 
                # with the help message for empty argument lists
                if oldargs and not myfiles:
@@ -13948,8 +13965,7 @@ def emerge_main():
                        display_news_notification(root_config, myopts)
                retval = action_build(settings, trees, mtimedb,
                        myopts, myaction, myfiles, spinner)
-               # if --pretend was not enabled then display_news_notification 
-               # was already called by post_emerge
-               if "--pretend" in myopts:
-                       display_news_notification(root_config, myopts)
+               root_config = trees[settings["ROOT"]]["root_config"]
+               post_emerge(root_config, myopts, mtimedb, retval)
+
                return retval
index 278aacf44bb5f038761c76e9b320c7bd8974de59..3a002179b234dfef4e408b26d192ef60d7e4c66c 100644 (file)
@@ -20,9 +20,9 @@ try:
        import shutil
        import time
        try:
-               import cPickle
+               import cPickle as pickle
        except ImportError:
-               import pickle as cPickle
+               import pickle
 
        import stat
        import commands
@@ -141,7 +141,7 @@ except ImportError, e:
 
 
 try:
-       import portage.selinux as selinux
+       import portage._selinux as selinux
 except OSError, e:
        writemsg("!!! SELinux not loaded: %s\n" % str(e), noiselevel=-1)
        del e
@@ -3528,11 +3528,19 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
                        eidx = myuri.find("/", 9)
                        if eidx != -1:
                                mirrorname = myuri[9:eidx]
+                               if myfile != os.path.basename(myuri):
+                                       # If a SRC_URI arrow is used together with
+                                       # mirror://, preserve the remote path that's
+                                       # specified within the uri.
+                                       path = myuri[eidx+1:]
+                               else:
+                                       path = myfile
 
                                # Try user-defined mirrors first
                                if mirrorname in custommirrors:
                                        for cmirr in custommirrors[mirrorname]:
-                                               filedict[myfile].append(cmirr+"/"+myuri[eidx+1:])
+                                               filedict[myfile].append(
+                                                       cmirr.rstrip("/") + "/" + path)
                                                # remove the mirrors we tried from the list of official mirrors
                                                if cmirr.strip() in thirdpartymirrors[mirrorname]:
                                                        thirdpartymirrors[mirrorname].remove(cmirr)
@@ -3541,7 +3549,8 @@ def fetch(myuris, mysettings, listonly=0, fetchonly=0, locks_in_subdir=".locks",
                                        shuffle(thirdpartymirrors[mirrorname])
 
                                        for locmirr in thirdpartymirrors[mirrorname]:
-                                               filedict[myfile].append(locmirr+"/"+myuri[eidx+1:])
+                                               filedict[myfile].append(
+                                                       locmirr.rstrip("/") + "/" + path)
 
                                if not filedict[myfile]:
                                        writemsg("No known mirror by the name: %s\n" % (mirrorname))
@@ -7110,7 +7119,7 @@ def commit_mtimedb(mydict=None, filename=None):
        d.update(mydict)
        try:
                f = atomic_ofstream(filename)
-               cPickle.dump(d, f, -1)
+               pickle.dump(d, f, -1)
                f.close()
                portage.util.apply_secpass_permissions(filename, uid=uid, gid=portage_gid, mode=0664)
        except (IOError, OSError), e:
@@ -7264,13 +7273,13 @@ class MtimeDB(dict):
        def _load(self, filename):
                try:
                        f = open(filename)
-                       mypickle = cPickle.Unpickler(f)
+                       mypickle = pickle.Unpickler(f)
                        mypickle.find_global = None
                        d = mypickle.load()
                        f.close()
                        del f
-               except (IOError, OSError, EOFError, cPickle.UnpicklingError), e:
-                       if isinstance(e, cPickle.UnpicklingError):
+               except (IOError, OSError, EOFError, pickle.UnpicklingError), e:
+                       if isinstance(e, pickle.UnpicklingError):
                                writemsg("!!! Error loading '%s': %s\n" % \
                                        (filename, str(e)), noiselevel=-1)
                        del e
index 821f874ea3f9c1a4939b1d0bd847b612048eb8b2..18a22bab718cb0af7e54daff68ac83e844a8035b 100644 (file)
@@ -37,9 +37,9 @@ import shlex
 from itertools import izip
 
 try:
-       import cPickle
+       import cPickle as pickle
 except ImportError:
-       import pickle as cPickle
+       import pickle
 
 class PreservedLibsRegistry(object):
        """ This class handles the tracking of preserved library objects """
@@ -57,7 +57,7 @@ class PreservedLibsRegistry(object):
        def load(self):
                """ Reload the registry data from file """
                try:
-                       self._data = cPickle.load(open(self._filename, "r"))
+                       self._data = pickle.load(open(self._filename, "r"))
                except (EOFError, IOError), e:
                        if isinstance(e, EOFError) or e.errno == errno.ENOENT:
                                self._data = {}
@@ -74,7 +74,7 @@ class PreservedLibsRegistry(object):
                        return
                try:
                        f = atomic_ofstream(self._filename)
-                       cPickle.dump(self._data, f)
+                       pickle.dump(self._data, f)
                        f.close()
                except EnvironmentError, e:
                        if e.errno != PermissionDenied.errno:
@@ -1394,7 +1394,7 @@ class vardbapi(dbapi):
                        del self._aux_cache["modified"]
                        try:
                                f = atomic_ofstream(self._aux_cache_filename)
-                               cPickle.dump(self._aux_cache, f, -1)
+                               pickle.dump(self._aux_cache, f, -1)
                                f.close()
                                apply_secpass_permissions(
                                        self._aux_cache_filename, gid=portage_gid, mode=0644)
@@ -1412,13 +1412,13 @@ class vardbapi(dbapi):
                aux_cache = None
                try:
                        f = open(self._aux_cache_filename)
-                       mypickle = cPickle.Unpickler(f)
+                       mypickle = pickle.Unpickler(f)
                        mypickle.find_global = None
                        aux_cache = mypickle.load()
                        f.close()
                        del f
-               except (IOError, OSError, EOFError, cPickle.UnpicklingError), e:
-                       if isinstance(e, cPickle.UnpicklingError):
+               except (IOError, OSError, EOFError, pickle.UnpicklingError), e:
+                       if isinstance(e, pickle.UnpicklingError):
                                writemsg("!!! Error loading '%s': %s\n" % \
                                        (self._aux_cache_filename, str(e)), noiselevel=-1)
                        del e
index 6801d8527ccb1d90674a6febb215151d1953c963..f1eff0df328761f2c0b96706ea2358c7169bfee7 100644 (file)
@@ -16,9 +16,9 @@ import urllib2
 from portage.const import CACHE_PATH
 
 try:
-       import cPickle
+       import cPickle as pickle
 except ImportError:
-       import pickle as cPickle
+       import pickle
 
 try:
        import ftplib
@@ -474,11 +474,11 @@ def dir_get_metadata(baseurl, conn=None, chunk_size=3000, verbose=1, usingcache=
        out = sys.stdout
        try:
                metadatafile = open(CACHE_PATH+"/remote_metadata.pickle")
-               metadata = cPickle.load(metadatafile)
+               metadata = pickle.load(metadatafile)
                out.write("Loaded metadata pickle.\n")
                out.flush()
                metadatafile.close()
-       except (cPickle.UnpicklingError, OSError, IOError, EOFError):
+       except (pickle.UnpicklingError, OSError, IOError, EOFError):
                metadata = {}
        if baseurl not in metadata:
                metadata[baseurl]={}
@@ -547,7 +547,7 @@ def dir_get_metadata(baseurl, conn=None, chunk_size=3000, verbose=1, usingcache=
                                                sys.stderr.flush()
                                        mytempfile.close()
                                try:
-                                       metadata[baseurl]["data"] = cPickle.loads(data)
+                                       metadata[baseurl]["data"] = pickle.loads(data)
                                        del data
                                        metadata[baseurl]["indexname"] = mfile
                                        metadata[baseurl]["timestamp"] = int(time.time())
@@ -563,7 +563,7 @@ def dir_get_metadata(baseurl, conn=None, chunk_size=3000, verbose=1, usingcache=
                                        sys.stderr.flush()
                        try:
                                metadatafile = open(CACHE_PATH+"/remote_metadata.pickle", "w+")
-                               cPickle.dump(metadata,metadatafile)
+                               pickle.dump(metadata,metadatafile)
                                metadatafile.close()
                        except SystemExit, e:
                                raise
@@ -653,11 +653,11 @@ def dir_get_metadata(baseurl, conn=None, chunk_size=3000, verbose=1, usingcache=
                if "modified" in metadata[baseurl] and metadata[baseurl]["modified"]:
                        metadata[baseurl]["timestamp"] = int(time.time())
                        metadatafile = open(CACHE_PATH+"/remote_metadata.pickle", "w+")
-                       cPickle.dump(metadata,metadatafile)
+                       pickle.dump(metadata,metadatafile)
                        metadatafile.close()
                if makepickle:
                        metadatafile = open(makepickle, "w")
-                       cPickle.dump(metadata[baseurl]["data"],metadatafile)
+                       pickle.dump(metadata[baseurl]["data"],metadatafile)
                        metadatafile.close()
        except SystemExit, e:
                raise
index 2ddefb8618ab073034cb1b988bccb7af419b7711..438c9e2ca82146de7faf5b1f9f01398def8104f2 100644 (file)
@@ -248,3 +248,34 @@ class CategorySet(PackageSet):
                return rValue
        multiBuilder = classmethod(multiBuilder)
 
+class AgeSet(EverythingSet):
+       _operations = ["merge", "unmerge"]
+
+       def __init__(self, vardb, mode="older", age=7):
+               super(AgeSet, self).__init__(vardb)
+               self._mode = mode
+               self._age = age
+
+       def _filter(self, atom):
+               import time, os
+       
+               cpv = self._db.match(atom)[0]
+               path = self._db.getpath(cpv, filename="COUNTER")
+               age = (time.time() - os.stat(path).st_mtime) / (3600 * 24)
+               if ((self._mode == "older" and age <= self._age) \
+                       or (self._mode == "newer" and age >= self._age)):
+                       return False
+               else:
+                       return True
+       
+       def singleBuilder(cls, options, settings, trees):
+               mode = options.get("mode", "older")
+               if str(mode).lower() not in ["newer", "older"]:
+                       raise SetConfigError("invalid 'mode' value %s (use either 'newer' or 'older')" % mode)
+               try:
+                       age = int(options.get("age", "7"))
+               except ValueError, e:
+                       raise SetConfigError("value of option 'age' is not an integer")
+               return AgeSet(vardb=trees["vartree"].dbapi, mode=mode, age=age)
+
+       singleBuilder = classmethod(singleBuilder)
index 79fe7cc6fc744a8cacbf62721429c61937767d69..5f0460e0fee51909ce39c0c96fecc87dd5a187ce 100644 (file)
@@ -18,9 +18,9 @@ from portage.dep import isvalidatom
 from portage.const import EPREFIX, EPREFIX_LSTRIP
 
 try:
-       import cPickle
+       import cPickle as pickle
 except ImportError:
-       import pickle as cPickle
+       import pickle
 
 try:
        import cStringIO as StringIO
@@ -569,7 +569,7 @@ def pickle_write(data,filename,debug=0):
        import os
        try:
                myf=open(filename,"w")
-               cPickle.dump(data,myf,-1)
+               pickle.dump(data,myf,-1)
                myf.flush()
                myf.close()
                writemsg("Wrote pickle: "+str(filename)+"\n",1)
@@ -589,7 +589,7 @@ def pickle_read(filename,default=None,debug=0):
        data = None
        try:
                myf = open(filename)
-               mypickle = cPickle.Unpickler(myf)
+               mypickle = pickle.Unpickler(myf)
                mypickle.find_global = None
                data = mypickle.load()
                myf.close()