|
Packit |
6f3914 |
# repolist.py
|
|
Packit |
6f3914 |
# repolist CLI command.
|
|
Packit |
6f3914 |
#
|
|
Packit |
6f3914 |
# Copyright (C) 2014-2016 Red Hat, Inc.
|
|
Packit |
6f3914 |
#
|
|
Packit |
6f3914 |
# This copyrighted material is made available to anyone wishing to use,
|
|
Packit |
6f3914 |
# modify, copy, or redistribute it subject to the terms and conditions of
|
|
Packit |
6f3914 |
# the GNU General Public License v.2, or (at your option) any later version.
|
|
Packit |
6f3914 |
# This program is distributed in the hope that it will be useful, but WITHOUT
|
|
Packit |
6f3914 |
# ANY WARRANTY expressed or implied, including the implied warranties of
|
|
Packit |
6f3914 |
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
|
|
Packit |
6f3914 |
# Public License for more details. You should have received a copy of the
|
|
Packit |
6f3914 |
# GNU General Public License along with this program; if not, write to the
|
|
Packit |
6f3914 |
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit |
6f3914 |
# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
|
|
Packit |
6f3914 |
# source code or documentation are not subject to the GNU General Public
|
|
Packit |
6f3914 |
# License and may only be used or replicated with the express permission of
|
|
Packit |
6f3914 |
# Red Hat, Inc.
|
|
Packit |
6f3914 |
#
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
from __future__ import absolute_import
|
|
Packit |
6f3914 |
from __future__ import unicode_literals
|
|
Packit |
6f3914 |
from dnf.cli import commands
|
|
Packit |
6f3914 |
from dnf.i18n import _, ucd, fill_exact_width, exact_width
|
|
Packit |
6f3914 |
from dnf.cli.option_parser import OptionParser
|
|
Packit |
6f3914 |
import dnf.cli.format
|
|
Packit |
6f3914 |
import dnf.pycomp
|
|
Packit |
6f3914 |
import dnf.util
|
|
Packit |
6f3914 |
import fnmatch
|
|
Packit |
6f3914 |
import hawkey
|
|
Packit |
6f3914 |
import logging
|
|
Packit |
6f3914 |
import operator
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
logger = logging.getLogger('dnf')
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
def _expire_str(repo, md):
|
|
Packit |
6f3914 |
last = dnf.util.normalize_time(repo._repo.getTimestamp()) if md else _("unknown")
|
|
Packit |
6f3914 |
if repo.metadata_expire <= -1:
|
|
Packit |
6f3914 |
return _("Never (last: %s)") % last
|
|
Packit |
6f3914 |
elif not repo.metadata_expire:
|
|
Packit |
6f3914 |
return _("Instant (last: %s)") % last
|
|
Packit |
6f3914 |
else:
|
|
Packit |
6f3914 |
num = _num2ui_num(repo.metadata_expire)
|
|
Packit |
6f3914 |
return _("%s second(s) (last: %s)") % (num, last)
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
def _num2ui_num(num):
|
|
Packit |
6f3914 |
return ucd(dnf.pycomp.format("%d", num, True))
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
def _repo_match(repo, patterns):
|
|
Packit |
6f3914 |
rid = repo.id.lower()
|
|
Packit |
6f3914 |
rnm = repo.name.lower()
|
|
Packit |
6f3914 |
for pat in patterns:
|
|
Packit |
6f3914 |
if fnmatch.fnmatch(rid, pat):
|
|
Packit |
6f3914 |
return True
|
|
Packit |
6f3914 |
if fnmatch.fnmatch(rnm, pat):
|
|
Packit |
6f3914 |
return True
|
|
Packit |
6f3914 |
return False
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
def _repo_size(sack, repo):
|
|
Packit |
6f3914 |
ret = 0
|
|
Packit |
6f3914 |
for pkg in sack.query(flags=hawkey.IGNORE_EXCLUDES).filterm(reponame__eq=repo.id):
|
|
Packit |
6f3914 |
ret += pkg._size
|
|
Packit |
6f3914 |
return dnf.cli.format.format_number(ret)
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
class RepoListCommand(commands.Command):
|
|
Packit |
6f3914 |
"""A class containing methods needed by the cli to execute the
|
|
Packit |
6f3914 |
repolist command.
|
|
Packit |
6f3914 |
"""
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
aliases = ('repolist', 'repoinfo')
|
|
Packit |
6f3914 |
summary = _('display the configured software repositories')
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
@staticmethod
|
|
Packit |
6f3914 |
def set_argparser(parser):
|
|
Packit |
6f3914 |
repolimit = parser.add_mutually_exclusive_group()
|
|
Packit |
6f3914 |
repolimit.add_argument('--all', dest='_repos_action',
|
|
Packit |
6f3914 |
action='store_const', const='all', default=None,
|
|
Packit |
6f3914 |
help=_("show all repos"))
|
|
Packit |
6f3914 |
repolimit.add_argument('--enabled', dest='_repos_action',
|
|
Packit |
6f3914 |
action='store_const', const='enabled',
|
|
Packit |
6f3914 |
help=_("show enabled repos (default)"))
|
|
Packit |
6f3914 |
repolimit.add_argument('--disabled', dest='_repos_action',
|
|
Packit |
6f3914 |
action='store_const', const='disabled',
|
|
Packit |
6f3914 |
help=_("show disabled repos"))
|
|
Packit |
6f3914 |
parser.add_argument('repos', nargs='*', default='enabled-default', metavar="REPOSITORY",
|
|
Packit |
6f3914 |
choices=['all', 'enabled', 'disabled'],
|
|
Packit |
6f3914 |
action=OptionParser.PkgNarrowCallback,
|
|
Packit |
6f3914 |
help=_("Repository specification"))
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
def pre_configure(self):
|
|
Packit |
6f3914 |
if not self.opts.verbose and not self.opts.quiet:
|
|
Packit |
6f3914 |
self.cli.redirect_logger(stdout=logging.WARNING, stderr=logging.INFO)
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
def configure(self):
|
|
Packit |
6f3914 |
if not self.opts.verbose and not self.opts.quiet:
|
|
Packit |
6f3914 |
self.cli.redirect_repo_progress()
|
|
Packit |
6f3914 |
demands = self.cli.demands
|
|
Packit |
6f3914 |
if any((self.opts.verbose, ('repoinfo' in self.opts.command))):
|
|
Packit |
6f3914 |
demands.available_repos = True
|
|
Packit |
6f3914 |
demands.sack_activation = True
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
if self.opts._repos_action:
|
|
Packit |
6f3914 |
self.opts.repos_action = self.opts._repos_action
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
def run(self):
|
|
Packit |
6f3914 |
arg = self.opts.repos_action
|
|
Packit |
6f3914 |
extcmds = [x.lower() for x in self.opts.repos]
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
verbose = self.base.conf.verbose
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
repos = list(self.base.repos.values())
|
|
Packit |
6f3914 |
repos.sort(key=operator.attrgetter('id'))
|
|
Packit |
6f3914 |
term = self.output.term
|
|
Packit |
6f3914 |
on_ehibeg = term.FG_COLOR['green'] + term.MODE['bold']
|
|
Packit |
6f3914 |
on_dhibeg = term.FG_COLOR['red']
|
|
Packit |
6f3914 |
on_hiend = term.MODE['normal']
|
|
Packit |
6f3914 |
tot_num = 0
|
|
Packit |
6f3914 |
cols = []
|
|
Packit |
6f3914 |
if not repos:
|
|
Packit |
6f3914 |
logger.warning(_('No repositories available'))
|
|
Packit |
6f3914 |
return
|
|
Packit |
6f3914 |
include_status = arg == 'all' or (arg == 'enabled-default' and extcmds)
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
for repo in repos:
|
|
Packit |
6f3914 |
if len(extcmds) and not _repo_match(repo, extcmds):
|
|
Packit |
6f3914 |
continue
|
|
Packit |
6f3914 |
(ehibeg, dhibeg, hiend) = '', '', ''
|
|
Packit |
6f3914 |
ui_enabled = ''
|
|
Packit |
6f3914 |
ui_endis_wid = 0
|
|
Packit |
6f3914 |
ui_excludes_num = ''
|
|
Packit |
6f3914 |
if include_status:
|
|
Packit |
6f3914 |
(ehibeg, dhibeg, hiend) = (on_ehibeg, on_dhibeg, on_hiend)
|
|
Packit |
6f3914 |
if repo.enabled:
|
|
Packit |
6f3914 |
enabled = True
|
|
Packit |
6f3914 |
if arg == 'disabled':
|
|
Packit |
6f3914 |
continue
|
|
Packit |
6f3914 |
if any((include_status, verbose, 'repoinfo' in self.opts.command)):
|
|
Packit |
6f3914 |
ui_enabled = ehibeg + _('enabled') + hiend
|
|
Packit |
6f3914 |
ui_endis_wid = exact_width(_('enabled'))
|
|
Packit |
6f3914 |
if verbose or ('repoinfo' in self.opts.command):
|
|
Packit |
6f3914 |
ui_size = _repo_size(self.base.sack, repo)
|
|
Packit |
6f3914 |
else:
|
|
Packit |
6f3914 |
enabled = False
|
|
Packit |
6f3914 |
if arg == 'enabled' or (arg == 'enabled-default' and not extcmds):
|
|
Packit |
6f3914 |
continue
|
|
Packit |
6f3914 |
ui_enabled = dhibeg + _('disabled') + hiend
|
|
Packit |
6f3914 |
ui_endis_wid = exact_width(_('disabled'))
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
if not any((verbose, ('repoinfo' in self.opts.command))):
|
|
Packit |
6f3914 |
rid = ucd(repo.id)
|
|
Packit |
6f3914 |
cols.append((rid, repo.name, (ui_enabled, ui_endis_wid)))
|
|
Packit |
6f3914 |
else:
|
|
Packit |
6f3914 |
if enabled:
|
|
Packit |
6f3914 |
md = repo.metadata
|
|
Packit |
6f3914 |
else:
|
|
Packit |
6f3914 |
md = None
|
|
Packit |
6f3914 |
out = [self.output.fmtKeyValFill(_("Repo-id : "), repo.id),
|
|
Packit |
6f3914 |
self.output.fmtKeyValFill(_("Repo-name : "), repo.name)]
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
if include_status:
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(_("Repo-status : "),
|
|
Packit |
6f3914 |
ui_enabled)]
|
|
Packit |
6f3914 |
if md and repo._repo.getRevision():
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(_("Repo-revision : "),
|
|
Packit |
6f3914 |
repo._repo.getRevision())]
|
|
Packit |
6f3914 |
if md and repo._repo.getContentTags():
|
|
Packit |
6f3914 |
tags = repo._repo.getContentTags()
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(_("Repo-tags : "),
|
|
Packit |
6f3914 |
", ".join(sorted(tags)))]
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
if md and repo._repo.getDistroTags():
|
|
Packit |
6f3914 |
distroTagsDict = {k: v for (k, v) in repo._repo.getDistroTags()}
|
|
Packit |
6f3914 |
for (distro, tags) in distroTagsDict.items():
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(
|
|
Packit |
6f3914 |
_("Repo-distro-tags : "),
|
|
Packit |
6f3914 |
"[%s]: %s" % (distro, ", ".join(sorted(tags))))]
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
if md:
|
|
Packit |
6f3914 |
num = len(self.base.sack.query(flags=hawkey.IGNORE_EXCLUDES).filterm(
|
|
Packit |
6f3914 |
reponame__eq=repo.id))
|
|
Packit |
6f3914 |
num_available = len(self.base.sack.query().filterm(reponame__eq=repo.id))
|
|
Packit |
6f3914 |
ui_num = _num2ui_num(num)
|
|
Packit |
6f3914 |
ui_num_available = _num2ui_num(num_available)
|
|
Packit |
6f3914 |
tot_num += num
|
|
Packit |
6f3914 |
out += [
|
|
Packit |
6f3914 |
self.output.fmtKeyValFill(
|
|
Packit |
6f3914 |
_("Repo-updated : "),
|
|
Packit |
6f3914 |
dnf.util.normalize_time(repo._repo.getMaxTimestamp())),
|
|
Packit |
6f3914 |
self.output.fmtKeyValFill(_("Repo-pkgs : "), ui_num),
|
|
Packit |
6f3914 |
self.output.fmtKeyValFill(_("Repo-available-pkgs: "), ui_num_available),
|
|
Packit |
6f3914 |
self.output.fmtKeyValFill(_("Repo-size : "), ui_size)]
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
if repo.metalink:
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(_("Repo-metalink : "),
|
|
Packit |
6f3914 |
repo.metalink)]
|
|
Packit |
6f3914 |
if enabled:
|
|
Packit |
6f3914 |
ts = repo._repo.getTimestamp()
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(
|
|
Packit |
6f3914 |
_(" Updated : "), dnf.util.normalize_time(ts))]
|
|
Packit |
6f3914 |
elif repo.mirrorlist:
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(_("Repo-mirrors : "),
|
|
Packit |
6f3914 |
repo.mirrorlist)]
|
|
Packit |
6f3914 |
baseurls = repo.baseurl
|
|
Packit |
6f3914 |
if baseurls:
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(_("Repo-baseurl : "),
|
|
Packit |
6f3914 |
", ".join(baseurls))]
|
|
Packit |
6f3914 |
elif enabled:
|
|
Packit |
6f3914 |
mirrors = repo._repo.getMirrors()
|
|
Packit |
6f3914 |
if mirrors:
|
|
Packit |
6f3914 |
url = "%s (%d more)" % (mirrors[0], len(mirrors) - 1)
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(_("Repo-baseurl : "), url)]
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
expire = _expire_str(repo, md)
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(_("Repo-expire : "), expire)]
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
if repo.excludepkgs:
|
|
Packit |
6f3914 |
# TRANSLATORS: Packages that are excluded - their names like (dnf systemd)
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(_("Repo-exclude : "),
|
|
Packit |
6f3914 |
", ".join(repo.excludepkgs))]
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
if repo.includepkgs:
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(_("Repo-include : "),
|
|
Packit |
6f3914 |
", ".join(repo.includepkgs))]
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
if ui_excludes_num:
|
|
Packit |
6f3914 |
# TRANSLATORS: Number of packages that where excluded (5)
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(_("Repo-excluded : "),
|
|
Packit |
6f3914 |
ui_excludes_num)]
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
if repo.repofile:
|
|
Packit |
6f3914 |
out += [self.output.fmtKeyValFill(_("Repo-filename : "),
|
|
Packit |
6f3914 |
repo.repofile)]
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
print("\n" + "\n".join(map(ucd, out)))
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
if not verbose and cols:
|
|
Packit |
6f3914 |
# Work out the first (id) and last (enabled/disabled/count),
|
|
Packit |
6f3914 |
# then chop the middle (name)...
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
id_len = exact_width(_('repo id'))
|
|
Packit |
6f3914 |
nm_len = 0
|
|
Packit |
6f3914 |
st_len = 0
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
for (rid, rname, (ui_enabled, ui_endis_wid)) in cols:
|
|
Packit |
6f3914 |
if id_len < exact_width(rid):
|
|
Packit |
6f3914 |
id_len = exact_width(rid)
|
|
Packit |
6f3914 |
if nm_len < exact_width(rname):
|
|
Packit |
6f3914 |
nm_len = exact_width(rname)
|
|
Packit |
6f3914 |
if st_len < ui_endis_wid:
|
|
Packit |
6f3914 |
st_len = ui_endis_wid
|
|
Packit |
6f3914 |
# Need this as well as above for: fill_exact_width()
|
|
Packit |
6f3914 |
if include_status:
|
|
Packit |
6f3914 |
if exact_width(_('status')) > st_len:
|
|
Packit |
6f3914 |
left = term.columns - (id_len + len(_('status')) + 2)
|
|
Packit |
6f3914 |
else:
|
|
Packit |
6f3914 |
left = term.columns - (id_len + st_len + 2)
|
|
Packit |
6f3914 |
else: # Don't output a status column.
|
|
Packit |
6f3914 |
left = term.columns - (id_len + 1)
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
if left < nm_len: # Name gets chopped
|
|
Packit |
6f3914 |
nm_len = left
|
|
Packit |
6f3914 |
else: # Share the extra...
|
|
Packit |
6f3914 |
left -= nm_len
|
|
Packit |
6f3914 |
id_len += left // 2
|
|
Packit |
6f3914 |
nm_len += left - (left // 2)
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
txt_rid = fill_exact_width(_('repo id'), id_len)
|
|
Packit |
6f3914 |
if include_status:
|
|
Packit |
6f3914 |
txt_rnam = fill_exact_width(_('repo name'), nm_len, nm_len)
|
|
Packit |
6f3914 |
else:
|
|
Packit |
6f3914 |
txt_rnam = _('repo name')
|
|
Packit |
6f3914 |
if not include_status: # Don't output a status column.
|
|
Packit |
6f3914 |
print("%s %s" % (txt_rid, txt_rnam))
|
|
Packit |
6f3914 |
else:
|
|
Packit |
6f3914 |
print("%s %s %s" % (txt_rid, txt_rnam, _('status')))
|
|
Packit |
6f3914 |
for (rid, rname, (ui_enabled, ui_endis_wid)) in cols:
|
|
Packit |
6f3914 |
if not include_status: # Don't output a status column.
|
|
Packit |
6f3914 |
print("%s %s" % (fill_exact_width(rid, id_len), rname))
|
|
Packit |
6f3914 |
continue
|
|
Packit |
6f3914 |
|
|
Packit |
6f3914 |
print("%s %s %s" % (fill_exact_width(rid, id_len),
|
|
Packit |
6f3914 |
fill_exact_width(rname, nm_len, nm_len),
|
|
Packit |
6f3914 |
ui_enabled))
|
|
Packit |
6f3914 |
if any((verbose, ('repoinfo' in self.opts.command))):
|
|
Packit |
6f3914 |
msg = _('Total packages: {}')
|
|
Packit |
6f3914 |
print(msg.format(_num2ui_num(tot_num)))
|