|
Packit Service |
27f74b |
# changelog.py
|
|
Packit Service |
27f74b |
# DNF plugin adding a command changelog.
|
|
Packit Service |
27f74b |
#
|
|
Packit Service |
27f74b |
# Copyright (C) 2014 Red Hat, Inc.
|
|
Packit Service |
27f74b |
#
|
|
Packit Service |
27f74b |
# This copyrighted material is made available to anyone wishing to use,
|
|
Packit Service |
27f74b |
# modify, copy, or redistribute it subject to the terms and conditions of
|
|
Packit Service |
27f74b |
# the GNU General Public License v.2, or (at your option) any later version.
|
|
Packit Service |
27f74b |
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
Packit Service |
27f74b |
# ANY WARRANTY expressed or implied, including the implied warranties of
|
|
Packit Service |
27f74b |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
Packit Service |
27f74b |
# Public License for more details. You should have received a copy of the
|
|
Packit Service |
27f74b |
# GNU General Public License along with this program; if not, write to the
|
|
Packit Service |
27f74b |
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
27f74b |
# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
|
|
Packit Service |
27f74b |
# source code or documentation are not subject to the GNU General Public
|
|
Packit Service |
27f74b |
# License and may only be used or replicated with the express permission of
|
|
Packit Service |
27f74b |
# Red Hat, Inc.
|
|
Packit Service |
27f74b |
#
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
from __future__ import absolute_import
|
|
Packit Service |
27f74b |
from __future__ import unicode_literals
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
import argparse
|
|
Packit Service |
27f74b |
import collections
|
|
Packit Service |
27f74b |
import dateutil.parser
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
from dnfpluginscore import _, P_, logger
|
|
Packit Service |
27f74b |
import dnf
|
|
Packit Service |
27f74b |
import dnf.cli
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
def validate_date(val):
|
|
Packit Service |
27f74b |
try:
|
|
Packit Service |
27f74b |
return dateutil.parser.parse(val, fuzzy=True)
|
|
Packit Service |
27f74b |
except (ValueError, TypeError, OverflowError):
|
|
Packit Service |
27f74b |
raise argparse.ArgumentTypeError(_('Not a valid date: "{0}".').format(val))
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
@dnf.plugin.register_command
|
|
Packit Service |
27f74b |
class ChangelogCommand(dnf.cli.Command):
|
|
Packit Service |
27f74b |
aliases = ('changelog',)
|
|
Packit Service |
27f74b |
summary = _('Show changelog data of packages')
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
@staticmethod
|
|
Packit Service |
27f74b |
def set_argparser(parser):
|
|
Packit Service |
27f74b |
filter_group = parser.add_mutually_exclusive_group()
|
|
Packit Service |
27f74b |
filter_group.add_argument(
|
|
Packit Service |
27f74b |
'--since', metavar="DATE", default=None,
|
|
Packit Service |
27f74b |
type=validate_date,
|
|
Packit Service |
27f74b |
help=_('show changelog entries since DATE. To avoid ambiguosity, '
|
|
Packit Service |
27f74b |
'YYYY-MM-DD format is recommended.'))
|
|
Packit Service |
27f74b |
filter_group.add_argument(
|
|
Packit Service |
27f74b |
'--count', default=None, type=int,
|
|
Packit Service |
27f74b |
help=_('show given number of changelog entries per package'))
|
|
Packit Service |
27f74b |
filter_group.add_argument(
|
|
Packit Service |
27f74b |
'--upgrades', default=False, action='store_true',
|
|
Packit Service |
27f74b |
help=_('show only new changelog entries for packages, that provide an '
|
|
Packit Service |
27f74b |
'upgrade for some of already installed packages.'))
|
|
Packit Service |
27f74b |
parser.add_argument("package", nargs='*', metavar=_('PACKAGE'))
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
def configure(self):
|
|
Packit Service |
27f74b |
demands = self.cli.demands
|
|
Packit Service |
27f74b |
demands.available_repos = True
|
|
Packit Service |
27f74b |
demands.sack_activation = True
|
|
Packit Service |
27f74b |
demands.changelogs = True
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
def query(self):
|
|
Packit Service |
27f74b |
q = self.base.sack.query()
|
|
Packit Service |
27f74b |
if self.opts.package:
|
|
Packit Service |
27f74b |
q.filterm(empty=True)
|
|
Packit Service |
27f74b |
for pkg in self.opts.package:
|
|
Packit Service |
27f74b |
pkg_q = dnf.subject.Subject(pkg, ignore_case=True).get_best_query(
|
|
Packit Service |
27f74b |
self.base.sack, with_nevra=True,
|
|
Packit Service |
27f74b |
with_provides=False, with_filenames=False)
|
|
Packit Service |
27f74b |
if self.opts.repo:
|
|
Packit Service |
27f74b |
pkg_q.filterm(reponame=self.opts.repo)
|
|
Packit Service |
27f74b |
if pkg_q:
|
|
Packit Service |
27f74b |
q = q.union(pkg_q.latest())
|
|
Packit Service |
27f74b |
else:
|
|
Packit Service |
27f74b |
logger.info(_('No match for argument: %s') % pkg)
|
|
Packit Service |
27f74b |
elif self.opts.repo:
|
|
Packit Service |
27f74b |
q.filterm(reponame=self.opts.repo)
|
|
Packit Service |
27f74b |
if self.opts.upgrades:
|
|
Packit Service |
27f74b |
q = q.upgrades()
|
|
Packit Service |
27f74b |
else:
|
|
Packit Service |
27f74b |
q = q.available()
|
|
Packit Service |
27f74b |
return q
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
def by_srpm(self, packages):
|
|
Packit Service |
27f74b |
by_srpm = collections.OrderedDict()
|
|
Packit Service |
27f74b |
for pkg in sorted(packages):
|
|
Packit Service |
27f74b |
by_srpm.setdefault((pkg.source_name or pkg.name, pkg.evr), []).append(pkg)
|
|
Packit Service |
27f74b |
return by_srpm
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
def filter_changelogs(self, package):
|
|
Packit Service |
27f74b |
if self.opts.upgrades:
|
|
Packit Service |
27f74b |
return self.base.latest_changelogs(package)
|
|
Packit Service |
27f74b |
elif self.opts.count:
|
|
Packit Service |
27f74b |
return package.changelogs[:self.opts.count]
|
|
Packit Service |
27f74b |
elif self.opts.since:
|
|
Packit Service |
27f74b |
return [chlog for chlog in package.changelogs
|
|
Packit Service |
27f74b |
if chlog['timestamp'] >= self.opts.since.date()]
|
|
Packit Service |
27f74b |
else:
|
|
Packit Service |
27f74b |
return package.changelogs
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
def run(self):
|
|
Packit Service |
27f74b |
if self.opts.since:
|
|
Packit Service |
27f74b |
logger.info(_('Listing changelogs since {}').format(self.opts.since))
|
|
Packit Service |
27f74b |
elif self.opts.count:
|
|
Packit Service |
27f74b |
logger.info(P_('Listing only latest changelog',
|
|
Packit Service |
27f74b |
'Listing {} latest changelogs',
|
|
Packit Service |
27f74b |
self.opts.count).format(self.opts.count))
|
|
Packit Service |
27f74b |
elif self.opts.upgrades:
|
|
Packit Service |
27f74b |
logger.info(
|
|
Packit Service |
27f74b |
_('Listing only new changelogs since installed version of the package'))
|
|
Packit Service |
27f74b |
else:
|
|
Packit Service |
27f74b |
logger.info(_('Listing all changelogs'))
|
|
Packit Service |
27f74b |
|
|
Packit Service |
27f74b |
by_srpm = self.by_srpm(self.query())
|
|
Packit Service |
27f74b |
for name in by_srpm:
|
|
Packit Service |
27f74b |
print(_('Changelogs for {}').format(
|
|
Packit Service |
27f74b |
', '.join(sorted({str(pkg) for pkg in by_srpm[name]}))))
|
|
Packit Service |
27f74b |
for chlog in self.filter_changelogs(by_srpm[name][0]):
|
|
Packit Service |
27f74b |
print(self.base.format_changelog(chlog))
|