From f61286275424458fab0e8a9daa1461571277d241 Mon Sep 17 00:00:00 2001 From: Fabian Groffen Date: Sat, 27 Sep 2008 16:08:34 +0000 Subject: [PATCH] Merged from trunk -r11531:11544 | 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 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 | 3 +- cnf/sets.conf | 1 + pym/_emerge/__init__.py | 280 +++++++++++++----------- pym/portage/__init__.py | 27 ++- pym/portage/{selinux.py => _selinux.py} | 0 pym/portage/dbapi/vartree.py | 16 +- pym/portage/getbinpkg.py | 16 +- pym/portage/sets/dbapi.py | 31 +++ pym/portage/util.py | 8 +- 9 files changed, 220 insertions(+), 162 deletions(-) rename pym/portage/{selinux.py => _selinux.py} (100%) diff --git a/bin/ecompress b/bin/ecompress index c5e82c021..39985328c 100755 --- a/bin/ecompress +++ b/bin/ecompress @@ -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 diff --git a/cnf/sets.conf b/cnf/sets.conf index c02d143ff..f9f351be8 100644 --- a/cnf/sets.conf +++ b/cnf/sets.conf @@ -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): diff --git a/pym/_emerge/__init__.py b/pym/_emerge/__init__.py index f9cbf7202..081bd7e2a 100644 --- a/pym/_emerge/__init__.py +++ b/pym/_emerge/__init__.py @@ -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 diff --git a/pym/portage/__init__.py b/pym/portage/__init__.py index 278aacf44..3a002179b 100644 --- a/pym/portage/__init__.py +++ b/pym/portage/__init__.py @@ -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 diff --git a/pym/portage/selinux.py b/pym/portage/_selinux.py similarity index 100% rename from pym/portage/selinux.py rename to pym/portage/_selinux.py diff --git a/pym/portage/dbapi/vartree.py b/pym/portage/dbapi/vartree.py index 821f874ea..18a22bab7 100644 --- a/pym/portage/dbapi/vartree.py +++ b/pym/portage/dbapi/vartree.py @@ -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 diff --git a/pym/portage/getbinpkg.py b/pym/portage/getbinpkg.py index 6801d8527..f1eff0df3 100644 --- a/pym/portage/getbinpkg.py +++ b/pym/portage/getbinpkg.py @@ -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 diff --git a/pym/portage/sets/dbapi.py b/pym/portage/sets/dbapi.py index 2ddefb861..438c9e2ca 100644 --- a/pym/portage/sets/dbapi.py +++ b/pym/portage/sets/dbapi.py @@ -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) diff --git a/pym/portage/util.py b/pym/portage/util.py index 79fe7cc6f..5f0460e0f 100644 --- a/pym/portage/util.py +++ b/pym/portage/util.py @@ -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() -- 2.26.2