diff options
author | Martin Väth <vaeth at mathematik.uni-wuerzburg.de> | 2012-09-02 13:18:20 -0700 |
---|---|---|
committer | Zac Medico <zmedico@gentoo.org> | 2012-09-02 13:18:20 -0700 |
commit | ce16249658fa99a8b2051a19091b85f712f5dac1 (patch) | |
tree | 3a8705057b61c011115b6c68f4f542f63ac66393 | |
parent | b7f39b5f439cc7c3563706478d1ebafca7fde074 (diff) | |
download | portage-ce16249658fa99a8b2051a19091b85f712f5dac1.tar.gz portage-ce16249658fa99a8b2051a19091b85f712f5dac1.tar.bz2 portage-ce16249658fa99a8b2051a19091b85f712f5dac1.zip |
Add DateSet, bug #433704.
Allow sets of packages installed before or after a specific date.
The date may be specified explicitly (in dateformat which defaults to "%x %X")
or seconds since Epoch, or implicitly as an installation date or a filestamp.
For example, the following sets can be specified in /etc/portage/sets.conf:
[date1]
class = portage.sets.dbapi.DateSet
mode = older
date = 08/31/12 10:00:00
dateformat = %%x %%X
[date2]
class = portage.sets.dbapi.DateSet
mode = newer
seconds = 1346400000
[date3]
class = portage.sets.dbapi.DateSet
package = sys-devel/gcc:4.7
[date4]
class = portage.sets.dbapi.DateSet
filestamp = /usr/bin/gcc
-rw-r--r-- | pym/portage/_sets/dbapi.py | 68 |
1 files changed, 68 insertions, 0 deletions
diff --git a/pym/portage/_sets/dbapi.py b/pym/portage/_sets/dbapi.py index 4982a9244..03c4941df 100644 --- a/pym/portage/_sets/dbapi.py +++ b/pym/portage/_sets/dbapi.py @@ -355,6 +355,74 @@ class AgeSet(EverythingSet): singleBuilder = classmethod(singleBuilder) +class DateSet(EverythingSet): + _operations = ["merge", "unmerge"] + + def __init__(self, vardb, date, mode="older"): + super(DateSet, self).__init__(vardb) + self._mode = mode + self._date = date + + def _filter(self, atom): + + cpv = self._db.match(atom)[0] + path = self._db.getpath(cpv, filename="COUNTER") + date = os.stat(path).st_mtime + # Make sure inequality is _strict_ to exclude tested package + if ((self._mode == "older" and date < self._date) \ + or (self._mode == "newer" and date > self._date)): + return True + else: + return False + + def singleBuilder(cls, options, settings, trees): + vardbapi = trees["vartree"].dbapi + 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) + package = options.get("package") + if package is not None: + format = "package" + else: + filestamp = options.get("filestamp") + if filestamp is not None: + format = "filestamp" + else: + seconds = options.get("seconds") + if seconds is not None: + format = "seconds" + else: + dateopt = options.get("date") + if dateopt is not None: + format = "date" + else: + raise SetConfigError(_("none of these options specified: 'package', 'filestamp', 'seconds', 'date'")) + if (format == "package"): + try: + cpv = vardbapi.match(package)[0] + path = vardbapi.getpath(cpv, filename="COUNTER") + date = os.stat(path).st_mtime + except ValueError: + raise SetConfigError(_("cannot determine installation date of package %s") % package) + elif (format == "filestamp"): + try: + date = os.stat(filestamp).st_mtime + except OSError: + raise SetConfigError(_("cannot determine 'filestamp' of '%s'") % filestamp) + elif (format == "seconds"): + # Do *not* test for integer: + # Modern filesystems support fractional seconds + date = seconds + else: + try: + dateformat = options.get("dateformat", "%x %X") + date = time.mktime(time.strptime(dateopt, dateformat)) + except ValueError: + raise SetConfigError(_("'date=%s' does not match 'dateformat=%s'") % (dateopt, dateformat)) + return DateSet(vardb=vardbapi, date=date, mode=mode) + + singleBuilder = classmethod(singleBuilder) + class RebuiltBinaries(EverythingSet): _operations = ('merge',) _aux_keys = ('BUILD_TIME',) |