Hello community, here is the log from the commit of package dnf for openSUSE:Factory checked in at 2020-02-27 16:57:42 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/dnf (Old) and /work/SRC/openSUSE:Factory/.dnf.new.26092 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "dnf" Thu Feb 27 16:57:42 2020 rev:17 rq:779943 version:4.2.19 Changes: -------- --- /work/SRC/openSUSE:Factory/dnf/dnf.changes 2020-01-19 20:58:33.904085786 +0100 +++ /work/SRC/openSUSE:Factory/.dnf.new.26092/dnf.changes 2020-02-27 16:57:43.678846666 +0100 @@ -1,0 +2,19 @@ +Thu Feb 27 14:13:22 UTC 2020 - Neal Gompa <[email protected]> + +- Update to version 4.2.19 + + List arguments: only first empty value is used (rh#1788154) + + Report missing profiles or default as broken module (rh#1790967) + + repoquery: fix rich deps matching by using provide expansion from libdnf (rh#1534123) + + [documentation] repoquery --what* with multiple arguments (rh#1790262) + + Format history table to use actual terminal width (rh#1786316) + + Update `dnf alias` documentation + + Handle custom exceptions from libdnf + + Fix _skipped_packages to return only skipped (rh#1774617) + + Add setter for tsi.reason + + Add new hook for commands: Run_resolved + + Add doc entry: include url (RhBug 1786072) + + Clean also .yaml repository metadata + + New API function base.setup_loggers() (rh#1788212) + + Use WantedBy=timers.target for all dnf timers (rh#1798475) + +------------------------------------------------------------------- Old: ---- dnf-4.2.18.tar.gz New: ---- dnf-4.2.19.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ dnf.spec ++++++ --- /var/tmp/diff_new_pack.lg7HuI/_old 2020-02-27 16:57:45.670849996 +0100 +++ /var/tmp/diff_new_pack.lg7HuI/_new 2020-02-27 16:57:45.670849996 +0100 @@ -17,7 +17,7 @@ # -%global hawkey_version 0.43.1 +%global hawkey_version 0.45.0 %global libcomps_version 0.1.8 %global rpm_version 4.14.0 %global min_plugins_core 4.0.12 @@ -48,7 +48,7 @@ %bcond_with tests Name: dnf -Version: 4.2.18 +Version: 4.2.19 Release: 0 Summary: Package manager forked from Yum, using libsolv as a dependency resolver # For a breakdown of the licensing, see PACKAGE-LICENSING ++++++ dnf-4.2.18.tar.gz -> dnf-4.2.19.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/VERSION.cmake new/dnf-4.2.19/VERSION.cmake --- old/dnf-4.2.18/VERSION.cmake 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/VERSION.cmake 2020-02-24 15:09:08.000000000 +0100 @@ -1,4 +1,4 @@ -set (DEFAULT_DNF_VERSION "4.2.18") +set (DEFAULT_DNF_VERSION "4.2.19") if(DEFINED DNF_VERSION) if(NOT ${DEFAULT_DNF_VERSION} STREQUAL ${DNF_VERSION}) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/dnf/base.py new/dnf-4.2.19/dnf/base.py --- old/dnf-4.2.18/dnf/base.py 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/dnf/base.py 2020-02-24 15:09:08.000000000 +0100 @@ -2538,6 +2538,14 @@ msg = _('All matches were filtered out by exclude filtering for argument') raise dnf.exceptions.PackagesNotInstalledError(msg, pkg_spec) + def setup_loggers(self): + # :api + """ + Setup DNF file loggers based on given configuration file. The loggers are set the same + way as if DNF was run from CLI. + """ + self._logging._setup_from_dnf_conf(self.conf, file_loggers_only=True) + def _msg_installed(pkg): name = ucd(pkg) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/dnf/cli/commands/__init__.py new/dnf-4.2.19/dnf/cli/commands/__init__.py --- old/dnf-4.2.18/dnf/cli/commands/__init__.py 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/dnf/cli/commands/__init__.py 2020-02-24 15:09:08.000000000 +0100 @@ -150,6 +150,10 @@ """Execute the command.""" pass + def run_resolved(self): + """Finalize operation after resolvement""" + pass + def run_transaction(self): """Finalize operations post-transaction.""" pass diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/dnf/cli/commands/repoquery.py new/dnf-4.2.19/dnf/cli/commands/repoquery.py --- old/dnf-4.2.18/dnf/cli/commands/repoquery.py 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/dnf/cli/commands/repoquery.py 2020-02-24 15:09:08.000000000 +0100 @@ -303,6 +303,12 @@ "(optionally with '--alldeps', but not with '--exactdeps'), or with " "'--requires <REQ> --resolve'")) + if self.opts.alldeps or self.opts.exactdeps: + if not (self.opts.whatrequires or self.opts.whatdepends): + raise dnf.cli.CliError( + _("argument {} requires --whatrequires or --whatdepends option".format( + '--alldeps' if self.opts.alldeps else '--exactdeps'))) + if self.opts.srpm: self.base.repos.enable_source_repos() @@ -343,55 +349,62 @@ # there don't exist on the dnf Package object. raise dnf.exceptions.Error(str(e)) - def _get_recursive_deps_query(self, query_in, query_select, done=None, recursive=False, - all_deps=False): - done = done if done else self.base.sack.query().filterm(empty=True) - t = self.base.sack.query().filterm(empty=True) - set_requires = set() - set_all_deps = set() + def _resolve_nevras(self, nevras, base_query): + resolved_nevras_query = self.base.sack.query().filterm(empty=True) + for nevra in nevras: + resolved_nevras_query = resolved_nevras_query.union(base_query.intersection( + dnf.subject.Subject(nevra).get_best_query( + self.base.sack, + with_provides=False, + with_filenames=False + ) + )) + + return resolved_nevras_query - for pkg in query_select.run(): - pkg_provides = pkg.provides - set_requires.update(pkg_provides) - set_requires.update(pkg.files) - if all_deps: - set_all_deps.update(pkg_provides) - - t = t.union(query_in.filter(requires=set_requires)) - if set_all_deps: - t = t.union(query_in.filter(recommends=set_all_deps)) - t = t.union(query_in.filter(enhances=set_all_deps)) - t = t.union(query_in.filter(supplements=set_all_deps)) - t = t.union(query_in.filter(suggests=set_all_deps)) - if recursive: - query_select = t.difference(done) - if query_select: - done = self._get_recursive_deps_query(query_in, query_select, done=t.union(done), - recursive=recursive, all_deps=all_deps) - return t.union(done) + def _do_recursive_deps(self, query_in, query_select, done=None): + done = done if done else query_select - def by_all_deps(self, requires_name, depends_name, query): - names = requires_name or depends_name - defaultquery = self.base.sack.query().filterm(empty=True) - for name in names: - defaultquery = defaultquery.union(query.intersection( - dnf.subject.Subject(name).get_best_query(self.base.sack, with_provides=False, - with_filenames=False))) - requiresquery = query.filter(requires__glob=names) - if depends_name: - requiresquery = requiresquery.union(query.filter(recommends__glob=depends_name)) - requiresquery = requiresquery.union(query.filter(enhances__glob=depends_name)) - requiresquery = requiresquery.union(query.filter(supplements__glob=depends_name)) - requiresquery = requiresquery.union(query.filter(suggests__glob=depends_name)) + query_required = query_in.filter(requires=query_select) + + query_select = query_required.difference(done) + done = query_required.union(done) + + if query_select: + done = self._do_recursive_deps(query_in, query_select, done=done) - done = requiresquery.union(self._get_recursive_deps_query(query, defaultquery, - all_deps=depends_name)) - if self.opts.recursive: - done = done.union(self._get_recursive_deps_query(query, done, - recursive=self.opts.recursive, - all_deps=depends_name)) return done + def by_all_deps(self, names, query, all_dep_types=False): + # in case of arguments being NEVRAs, resolve them to packages + resolved_nevras_query = self._resolve_nevras(names, query) + + # filter the arguments directly as reldeps + depquery = query.filter(requires__glob=names) + + # filter the resolved NEVRAs as packages + depquery = depquery.union(query.filter(requires=resolved_nevras_query)) + + if all_dep_types: + # TODO this is very inefficient, as it resolves the `names` glob to + # reldeps four more times, which in a reasonably wide glob like + # `dnf repoquery --whatdepends "libdnf*"` can take roughly 50% of + # the total execution time. + depquery = depquery.union(query.filter(recommends__glob=names)) + depquery = depquery.union(query.filter(enhances__glob=names)) + depquery = depquery.union(query.filter(supplements__glob=names)) + depquery = depquery.union(query.filter(suggests__glob=names)) + + depquery = depquery.union(query.filter(recommends=resolved_nevras_query)) + depquery = depquery.union(query.filter(enhances=resolved_nevras_query)) + depquery = depquery.union(query.filter(supplements=resolved_nevras_query)) + depquery = depquery.union(query.filter(suggests=resolved_nevras_query)) + + if self.opts.recursive: + depquery = self._do_recursive_deps(query, depquery) + + return depquery + def _get_recursive_providers_query(self, query_in, providers, done=None): done = done if done else self.base.sack.query().filterm(empty=True) t = self.base.sack.query().filterm(empty=True) @@ -486,7 +499,8 @@ if self.opts.file: q.filterm(file__glob=self.opts.file) if self.opts.whatconflicts: - q.filterm(conflicts=self.opts.whatconflicts) + rels = q.filter(conflicts__glob=self.opts.whatconflicts) + q = rels.union(q.filter(conflicts=self._resolve_nevras(self.opts.whatconflicts, q))) if self.opts.whatobsoletes: q.filterm(obsoletes=self.opts.whatobsoletes) if self.opts.whatprovides: @@ -495,36 +509,36 @@ q = query_for_provide else: q.filterm(file__glob=self.opts.whatprovides) - if self.opts.alldeps or self.opts.exactdeps: - if not (self.opts.whatrequires or self.opts.whatdepends): - raise dnf.exceptions.Error( - _("argument {} requires --whatrequires or --whatdepends option".format( - '--alldeps' if self.opts.alldeps else '--exactdeps'))) - if self.opts.alldeps: - q = self.by_all_deps(self.opts.whatrequires, self.opts.whatdepends, q) + + if self.opts.whatrequires: + if (self.opts.exactdeps): + q.filterm(requires__glob=self.opts.whatrequires) else: - if self.opts.whatrequires: - q.filterm(requires__glob=self.opts.whatrequires) - else: - dependsquery = q.filter(requires__glob=self.opts.whatdepends) - dependsquery = dependsquery.union( - q.filter(recommends__glob=self.opts.whatdepends)) - dependsquery = dependsquery.union( - q.filter(enhances__glob=self.opts.whatdepends)) - dependsquery = dependsquery.union( - q.filter(supplements__glob=self.opts.whatdepends)) - q = dependsquery.union(q.filter(suggests__glob=self.opts.whatdepends)) + q = self.by_all_deps(self.opts.whatrequires, q) + + if self.opts.whatdepends: + if (self.opts.exactdeps): + dependsquery = q.filter(requires__glob=self.opts.whatdepends) + dependsquery = dependsquery.union(q.filter(recommends__glob=self.opts.whatdepends)) + dependsquery = dependsquery.union(q.filter(enhances__glob=self.opts.whatdepends)) + dependsquery = dependsquery.union(q.filter(supplements__glob=self.opts.whatdepends)) + q = dependsquery.union(q.filter(suggests__glob=self.opts.whatdepends)) + else: + q = self.by_all_deps(self.opts.whatdepends, q, True) - elif self.opts.whatrequires or self.opts.whatdepends: - q = self.by_all_deps(self.opts.whatrequires, self.opts.whatdepends, q) if self.opts.whatrecommends: - q.filterm(recommends__glob=self.opts.whatrecommends) + rels = q.filter(recommends__glob=self.opts.whatrecommends) + q = rels.union(q.filter(recommends=self._resolve_nevras(self.opts.whatrecommends, q))) if self.opts.whatenhances: - q.filterm(enhances__glob=self.opts.whatenhances) + rels = q.filter(enhances__glob=self.opts.whatenhances) + q = rels.union(q.filter(enhances=self._resolve_nevras(self.opts.whatenhances, q))) if self.opts.whatsupplements: - q.filterm(supplements__glob=self.opts.whatsupplements) + rels = q.filter(supplements__glob=self.opts.whatsupplements) + q = rels.union(q.filter(supplements=self._resolve_nevras(self.opts.whatsupplements, q))) if self.opts.whatsuggests: - q.filterm(suggests__glob=self.opts.whatsuggests) + rels = q.filter(suggests__glob=self.opts.whatsuggests) + q = rels.union(q.filter(suggests=self._resolve_nevras(self.opts.whatsuggests, q))) + if self.opts.latest_limit: q = q.latest(self.opts.latest_limit) # reduce a query to security upgrades if they are specified @@ -672,7 +686,7 @@ ar[querypkg.name + "." + querypkg.arch] = querypkg pkgquery = self.base.sack.query().filterm(pkg=list(ar.values())) else: - pkgquery = self.by_all_deps(pkg.name, None, aquery) if opts.alldeps \ + pkgquery = self.by_all_deps((pkg.name, ), aquery) if opts.alldeps \ else aquery.filter(requires__glob=pkg.name) self.tree_seed(pkgquery, aquery, opts, level + 1, usedpkgs) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/dnf/cli/main.py new/dnf-4.2.19/dnf/cli/main.py --- old/dnf-4.2.18/dnf/cli/main.py 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/dnf/cli/main.py 2020-02-24 15:09:08.000000000 +0100 @@ -37,6 +37,8 @@ import dnf.logging import dnf.util import errno +import hawkey +import libdnf.error import logging import os import os.path @@ -74,6 +76,12 @@ return 1 except dnf.exceptions.Error as e: return ex_Error(e) + except hawkey.Exception as e: + logger.critical(_('Error: %s'), ucd(e)) + return 1 + except libdnf.error.Error as e: + logger.critical(_('Error: %s'), ucd(e)) + return 1 except IOError as e: return ex_IOError(e) except KeyboardInterrupt as e: @@ -158,6 +166,8 @@ base.resolve(cli.demands.allow_erasing) logger.info(_('Dependencies resolved.')) + cli.command.run_resolved() + # Run the transaction displays = [] if cli.demands.transaction_display is not None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/dnf/cli/option_parser.py new/dnf-4.2.19/dnf/cli/option_parser.py --- old/dnf-4.2.18/dnf/cli/option_parser.py 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/dnf/cli/option_parser.py 2020-02-24 15:09:08.000000000 +0100 @@ -82,9 +82,15 @@ SPLITTER = r'\s*[,\s]\s*' def __call__(self, parser, namespace, values, opt_str): + first = True for val in re.split(self.SPLITTER, values): - super(OptionParser._SplitCallback, - self).__call__(parser, namespace, val, opt_str) + if first or val: + # Empty values are sometimes used to clear existing content of the option. + # Only the first value in the parsed string can be empty. Other empty values + # are ignored. + super(OptionParser._SplitCallback, + self).__call__(parser, namespace, val, opt_str) + first = False class _SplitExtendDictCallback(argparse.Action): """ Split string at "," or whitespace to (key, value). diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/dnf/cli/output.py new/dnf-4.2.19/dnf/cli/output.py --- old/dnf-4.2.18/dnf/cli/output.py 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/dnf/cli/output.py 2020-02-24 15:09:08.000000000 +0100 @@ -1056,7 +1056,7 @@ out[0:0] = self._banner(col_data, (_('Group'), _('Packages'), '', '')) return '\n'.join(out) - def _skipped_packages(self, report_problems): + def _skipped_packages(self, report_problems, transaction): """returns set of conflicting packages and set of packages with broken dependency that would be additionally installed when --best and --allowerasing""" if self.base._goal.actions & (hawkey.INSTALL | hawkey.UPGRADE | hawkey.UPGRADE_ALL): @@ -1073,7 +1073,19 @@ logger.warning(msg) problem_conflicts = set(ng.problem_conflicts(available=True)) problem_dependency = set(ng.problem_broken_dependency(available=True)) - problem_conflicts - return problem_conflicts, problem_dependency + + def _nevra(item): + return hawkey.NEVRA(name=item.name, epoch=item.epoch, version=item.version, + release=item.release, arch=item.arch) + + # Sometimes, pkg is not in transaction item, therefore, comparing by nevra + transaction_nevras = [_nevra(tsi) for tsi in transaction] + skipped_conflicts = set( + [pkg for pkg in problem_conflicts if _nevra(pkg) not in transaction_nevras]) + skipped_dependency = set( + [pkg for pkg in problem_dependency if _nevra(pkg) not in transaction_nevras]) + + return skipped_conflicts, skipped_dependency def list_transaction(self, transaction, total_width=None): """Return a string representation of the transaction in an @@ -1254,7 +1266,8 @@ # show skipped conflicting packages if not self.conf.best and self.base._goal.actions & forward_actions: lines = [] - skipped_conflicts, skipped_broken = self._skipped_packages(report_problems=True) + skipped_conflicts, skipped_broken = self._skipped_packages( + report_problems=True, transaction=transaction) skipped_broken = dict((str(pkg), pkg) for pkg in skipped_broken) for pkg in sorted(skipped_conflicts): a_wid = _add_line(lines, data, a_wid, pkg, []) @@ -1468,7 +1481,9 @@ out = '' list_bunch = _make_lists(transaction, self.base._goal) - skipped_conflicts, skipped_broken = self._skipped_packages(report_problems=False) + + skipped_conflicts, skipped_broken = self._skipped_packages( + report_problems=False, transaction=transaction) skipped = skipped_conflicts.union(skipped_broken) for (action, tsis) in [(_('Upgraded'), list_bunch.upgraded), @@ -1613,15 +1628,20 @@ fmt = "%s | %s | %s | %s | %s" if len(uids) == 1: name = _("Command line") + name_width = self.term.columns - 55 if self.term.columns > 79 else 24 else: # TRANSLATORS: user names who executed transaction in history command output name = _("User name") + name_width = 24 print(fmt % (fill_exact_width(_("ID"), 6, 6), - fill_exact_width(name, 24, 24), + fill_exact_width(name, name_width, name_width), fill_exact_width(_("Date and time"), 16, 16), fill_exact_width(_("Action(s)"), 14, 14), fill_exact_width(_("Altered"), 7, 7))) - print("-" * 79) + + # total table width: each column length +3 (padding and separator between columns) + table_width = 6 + 3 + name_width + 3 + 16 + 3 + 14 + 3 + 7 + print("-" * table_width) fmt = "%6u | %s | %-16.16s | %s | %4u" for transaction in transactions: @@ -1633,7 +1653,7 @@ tm = time.strftime("%Y-%m-%d %H:%M", time.localtime(transaction.beg_timestamp)) num, uiacts = self._history_uiactions(transaction.data()) - name = fill_exact_width(name, 24, 24) + name = fill_exact_width(name, name_width, name_width) uiacts = fill_exact_width(uiacts, 14, 14) rmark = lmark = ' ' if transaction.return_code is None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/dnf/db/history.py new/dnf-4.2.19/dnf/db/history.py --- old/dnf-4.2.18/dnf/db/history.py 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/dnf/db/history.py 2020-02-24 15:09:08.000000000 +0100 @@ -89,6 +89,10 @@ def reason(self): return self._item.getReason() + @reason.setter + def reason(self, value): + return self._item.setReason(value) + @property def action_name(self): try: @@ -302,11 +306,11 @@ del self._tid except AttributeError: pass - self.swdb.closeTransaction() self._rpm = None self._group = None self._env = None if self._swdb: + self._swdb.closeTransaction() self._swdb.closeDatabase() self._swdb = None self._output = [] diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/dnf/logging.py new/dnf-4.2.19/dnf/logging.py --- old/dnf-4.2.18/dnf/logging.py 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/dnf/logging.py 2020-02-24 15:09:08.000000000 +0100 @@ -132,12 +132,14 @@ class Logging(object): def __init__(self): self.stdout_handler = self.stderr_handler = None - - @only_once - def _presetup(self): logging.addLevelName(DDEBUG, "DDEBUG") logging.addLevelName(SUBDEBUG, "SUBDEBUG") logging.addLevelName(TRACE, "TRACE") + logging.captureWarnings(True) + logging.raiseExceptions = False + + @only_once + def _presetup(self): logger_dnf = logging.getLogger("dnf") logger_dnf.setLevel(TRACE) @@ -155,24 +157,19 @@ self.stderr_handler = stderr @only_once - def _setup(self, verbose_level, error_level, logdir, log_size, log_rotate): - self._presetup() + def _setup_file_loggers(self, verbose_level, logdir, log_size, log_rotate): logger_dnf = logging.getLogger("dnf") + logger_dnf.setLevel(TRACE) # setup file logger logfile = os.path.join(logdir, dnf.const.LOG) handler = _create_filehandler(logfile, log_size, log_rotate) logger_dnf.addHandler(handler) - # temporarily turn off stdout/stderr handlers: - self.stdout_handler.setLevel(SUPERCRITICAL) - self.stderr_handler.setLevel(SUPERCRITICAL) # put the marker in the file now: _paint_mark(logger_dnf) # setup Python warnings - logging.captureWarnings(True) logger_warnings = logging.getLogger("py.warnings") - logger_warnings.addHandler(self.stderr_handler) logger_warnings.addHandler(handler) lr_logfile = os.path.join(logdir, dnf.const.LOG_LIBREPO) @@ -184,22 +181,41 @@ logger_rpm.setLevel(SUBDEBUG) logfile = os.path.join(logdir, dnf.const.LOG_RPM) handler = _create_filehandler(logfile, log_size, log_rotate) - logger_rpm.addHandler(self.stdout_handler) - logger_rpm.addHandler(self.stderr_handler) logger_rpm.addHandler(handler) _paint_mark(logger_rpm) + + @only_once + def _setup(self, verbose_level, error_level, logdir, log_size, log_rotate): + self._presetup() + + # temporarily turn off stdout/stderr handlers: + self.stdout_handler.setLevel(SUPERCRITICAL) + self.stderr_handler.setLevel(SUPERCRITICAL) + + self._setup_file_loggers(verbose_level, logdir, log_size, log_rotate) + + logger_warnings = logging.getLogger("py.warnings") + logger_warnings.addHandler(self.stderr_handler) + + # setup RPM callbacks logger + logger_rpm = logging.getLogger("dnf.rpm") + logger_rpm.addHandler(self.stdout_handler) + logger_rpm.addHandler(self.stderr_handler) + # bring std handlers to the preferred level self.stdout_handler.setLevel(verbose_level) self.stderr_handler.setLevel(error_level) - logging.raiseExceptions = False - def _setup_from_dnf_conf(self, conf): + def _setup_from_dnf_conf(self, conf, file_loggers_only=False): verbose_level_r = _cfg_verbose_val2level(conf.debuglevel) error_level_r = _cfg_err_val2level(conf.errorlevel) logdir = conf.logdir log_size = conf.log_size log_rotate = conf.log_rotate - return self._setup(verbose_level_r, error_level_r, logdir, log_size, log_rotate) + if file_loggers_only: + return self._setup_file_loggers(verbose_level_r, logdir, log_size, log_rotate) + else: + return self._setup(verbose_level_r, error_level_r, logdir, log_size, log_rotate) class Timer(object): diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/dnf/module/module_base.py new/dnf-4.2.19/dnf/module/module_base.py --- old/dnf-4.2.18/dnf/module/module_base.py 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/dnf/module/module_base.py 2020-02-24 15:09:08.000000000 +0100 @@ -119,16 +119,16 @@ ": {}").format( name, stream, profile_names) else: - msg = _("No default profiles for module {}:{}").format(name, stream) + msg = _("No profiles for module {}:{}").format(name, stream) logger.error(msg) - no_match_specs.append(spec) + error_specs.append(spec) for profile in set(profiles_strings): module_profiles = latest_module.getProfiles(profile) if not module_profiles: logger.error( _("Default profile {} not available in module {}:{}").format( profile, name, stream)) - no_match_specs.append(spec) + error_specs.append(spec) profiles.extend(module_profiles) for profile in profiles: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/dnf/repo.py new/dnf-4.2.19/dnf/repo.py --- old/dnf-4.2.18/dnf/repo.py 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/dnf/repo.py 2020-02-24 15:09:08.000000000 +0100 @@ -59,7 +59,7 @@ # particular type. The filename is expected to not contain the base cachedir # path components. CACHE_FILES = { - 'metadata': r'^%s\/.*(xml(\.gz|\.xz|\.bz2|.zck)?|asc|cachecookie|%s)$' % + 'metadata': r'^%s\/.*((xml|yaml)(\.gz|\.xz|\.bz2|.zck)?|asc|cachecookie|%s)$' % (_CACHEDIR_RE, _MIRRORLIST_FILENAME), 'packages': r'^%s\/%s\/.+rpm$' % (_CACHEDIR_RE, _PACKAGES_RELATIVE_DIR), 'dbcache': r'^.+(solv|solvx)$', diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/dnf.spec new/dnf-4.2.19/dnf.spec --- old/dnf-4.2.18/dnf.spec 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/dnf.spec 2020-02-24 15:09:08.000000000 +0100 @@ -1,5 +1,5 @@ # default dependencies -%global hawkey_version 0.41.0 +%global hawkey_version 0.45.0 %global libcomps_version 0.1.8 %global libmodulemd_version 1.4.0 %global rpm_version 4.14.0 @@ -81,7 +81,7 @@ It supports RPMs, modules and comps groups & environments. Name: dnf -Version: 4.2.18 +Version: 4.2.19 Release: 1%{?dist} Summary: %{pkg_summary} # For a breakdown of the licensing, see PACKAGE-LICENSING @@ -195,9 +195,6 @@ Recommends: deltarpm Recommends: python2-unbound %endif -%if 0%{?centos} -Requires: deltarpm -%endif Requires: python2-hawkey >= %{hawkey_version} Requires: python2-libdnf >= %{hawkey_version} Requires: python2-libcomps >= %{libcomps_version} @@ -235,9 +232,6 @@ %if 0%{?fedora} Recommends: deltarpm %endif -%if 0%{?centos} -Requires: deltarpm -%endif Requires: python3-hawkey >= %{hawkey_version} Requires: python3-libdnf >= %{hawkey_version} Requires: python3-libcomps >= %{libcomps_version} @@ -510,6 +504,23 @@ %endif %changelog +* Mon Feb 24 2020 Aleš Matěj <[email protected]> - 4.2.19-1 +- match RHEL behavior for CentOS and do not require deltarpm +- List arguments: only first empty value is used (RhBug:1788154) +- Report missing profiles or default as broken module (RhBug:1790967) +- repoquery: fix rich deps matching by using provide expansion from libdnf (RhBug:1534123) +- [documentation] repoquery --what* with multiple arguments (RhBug:1790262) +- Format history table to use actual terminal width (RhBug:1786316) +- Update `dnf alias` documentation +- Handle custom exceptions from libdnf +- Fix _skipped_packages to return only skipped (RhBug:1774617) +- Add setter for tsi.reason +- Add new hook for commands: Run_resolved +- Add doc entry: include url (RhBug 1786072) +- Clean also .yaml repository metadata +- New API function base.setup_loggers() (RhBug:1788212) +- Use WantedBy=timers.target for all dnf timers (RhBug:1798475) + * Wed Jan 15 2020 Aleš Matěj <[email protected]> - 4.2.18-1 - [doc] Remove note about user-agent whitelist - Do a substitution of variables in repo_id (RhBug:1748841) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/doc/api_queries.rst new/dnf-4.2.19/doc/api_queries.rst --- old/dnf-4.2.18/doc/api_queries.rst 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/doc/api_queries.rst 2020-02-24 15:09:08.000000000 +0100 @@ -101,17 +101,20 @@ release string match against packages' releases reponame string match against packages repositories' names version string match against packages' versions - obsoletes Query match packages that obsolete any package from query pkg Query match against packages in query pkg* list match against hawkey.Packages in list provides string match against packages' provides provides* Hawkey.Reldep match against packages' provides - requires string match against packages' requirements - requires* Hawkey.Reldep match against packages' requirements + <DEP> string match against packages' <DEP> + <DEP>* Hawkey.Reldep match a reldep against packages' <DEP> + <DEP>* Query match the result of a query against packages' <DEP> + <DEP>* list(Package) match the list of hawkey.Packages against packages' <DEP> sourcerpm string match against packages' source rpm upgrades boolean see :meth:`upgrades`. Defaults to ``False``. =============== ============== ====================================================== + ``<DEP>`` can be any of: requires, conflicts, obsoletes, enhances, recomments, suggests, supplements + \* The key can also accept a list of values with specified type. The key name can be supplemented with a relation-specifying suffix, separated by ``__``: @@ -133,6 +136,8 @@ q = base.sack.query().filter(name__substr="club") + Note that using packages or queries for dependency filtering performs a more advanced resolution than using a string or a reldep. When a package list or a query is used, rich dependencies are resolved in a more precise way than what is possible when a string or a reldep is used. + .. method:: filterm(\*\*kwargs) Similar to :meth:`dnf.query.Query.filter` but it modifies the query in place. diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/doc/cli_vs_yum.rst new/dnf-4.2.19/doc/cli_vs_yum.rst --- old/dnf-4.2.18/doc/cli_vs_yum.rst 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/doc/cli_vs_yum.rst 2020-02-24 15:09:08.000000000 +0100 @@ -93,6 +93,12 @@ ``include`` directive name of [main] and Repo configuration is a more logical and better named counterpart of ``exclude`` in DNF. +======================================= +The ``include`` option has been removed +======================================= + +Inclusion of other configuration files in the main configuration file is no longer supported. + ==================================================== ``dnf provides /bin/<file>`` is not fully supported ==================================================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/doc/command_ref.rst new/dnf-4.2.19/doc/command_ref.rst --- old/dnf-4.2.18/doc/command_ref.rst 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/doc/command_ref.rst 2020-02-24 15:09:08.000000000 +0100 @@ -458,9 +458,9 @@ ``dnf alias add rm=remove`` Adds a new command alias called ``rm`` which works the same as the ``remove`` command. -``dnf alias add update="\update --skip-broken --disableexcludes=all --obsoletes"`` - Adds a new command alias called ``update`` which works the same as the ``update`` command, - with additional options. Note that the original ``update`` command is prefixed with a ``\`` +``dnf alias add upgrade="\upgrade --skip-broken --disableexcludes=all --obsoletes"`` + Adds a new command alias called ``upgrade`` which works the same as the ``upgrade`` command, + with additional options. Note that the original ``upgrade`` command is prefixed with a ``\`` to prevent an infinite loop in alias processing. .. _alias_processing_examples-label: @@ -1201,37 +1201,37 @@ .. _whatdepends_option-label: -``--whatdepends <capability>`` +``--whatdepends <capability>[,<capability>...]`` Limit the resulting set only to packages that require, enhance, recommend, suggest or - supplement ``<capability>``. + supplement any of ``<capabilities>``. -``--whatconflicts <capability>`` - Limit the resulting set only to packages that conflict ``<capability>``. +``--whatconflicts <capability>[,<capability>...]`` + Limit the resulting set only to packages that conflict with any of ``<capabilities>``. -``--whatenhances <capability>`` - Limit the resulting set only to packages that enhance ``<capability>``. Use \-\ +``--whatenhances <capability>[,<capability>...]`` + Limit the resulting set only to packages that enhance any of ``<capabilities>``. Use \-\ :ref:`-whatdepends <whatdepends_option-label>` if you want to list all depending packages. -``--whatobsoletes <capability>`` - Limit the resulting set only to packages that obsolete ``<capability>``. +``--whatobsoletes <capability>[,<capability>...]`` + Limit the resulting set only to packages that obsolete any of ``<capabilities>``. -``--whatprovides <capability>`` - Limit the resulting set only to packages that provide ``<capability>``. +``--whatprovides <capability>[,<capability>...]`` + Limit the resulting set only to packages that provide any of ``<capabilities>``. -``--whatrecommends <capability>`` - Limit the resulting set only to packages that recommend ``<capability>``. Use \-\ +``--whatrecommends <capability>[,<capability>...]`` + Limit the resulting set only to packages that recommend any of ``<capabilities>``. Use \-\ :ref:`-whatdepends <whatdepends_option-label>` if you want to list all depending packages. -``--whatrequires <capability>`` - Limit the resulting set only to packages that require ``<capability>``. Use \-\ +``--whatrequires <capability>[,<capability>...]`` + Limit the resulting set only to packages that require any of ``<capabilities>``. Use \-\ :ref:`-whatdepends <whatdepends_option-label>` if you want to list all depending packages. -``--whatsuggests <capability>`` - Limit the resulting set only to packages that suggest ``<capability>``. Use \-\ +``--whatsuggests <capability>[,<capability>...]`` + Limit the resulting set only to packages that suggest any of ``<capabilities>``. Use \-\ :ref:`-whatdepends <whatdepends_option-label>` if you want to list all depending packages. -``--whatsupplements <capability>`` - Limit the resulting set only to packages that supplement ``<capability>``. Use \-\ +``--whatsupplements <capability>[,<capability>...]`` + Limit the resulting set only to packages that supplement any of ``<capabilities>``. Use \-\ :ref:`-whatdepends <whatdepends_option-label>` if you want to list all depending packages. ``--alldeps`` @@ -1389,7 +1389,7 @@ Display source packages that require a <provide> for a build:: - dnf repoquery --disablerepo=* --enablerepo=*-source --arch=src --whatrequires <provide> + dnf repoquery --disablerepo="*" --enablerepo="*-source" --arch=src --whatrequires <provide> .. _repo_pkgs_command-label: @@ -1821,7 +1821,7 @@ To disable all excludes for e.g. the install command you can use the following combination of command line options: -``dnf --disableexcludes=all --disableplugin=* install bash`` +``dnf --disableexcludes=all --disableplugin="*" install bash`` ----------------- Modular Filtering diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/doc/release_notes.rst new/dnf-4.2.19/doc/release_notes.rst --- old/dnf-4.2.18/doc/release_notes.rst 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/doc/release_notes.rst 2020-02-24 15:09:08.000000000 +0100 @@ -20,6 +20,38 @@ ################### ==================== +4.2.19 Release Notes +==================== + +- match RHEL behavior for CentOS and do not require deltarpm +- List arguments: only first empty value is used (RhBug:1788154) +- Report missing profiles or default as broken module (RhBug:1790967) +- repoquery: fix rich deps matching by using provide expansion from libdnf (RhBug:1534123) +- [documentation] repoquery --what* with multiple arguments (RhBug:1790262) +- Format history table to use actual terminal width (RhBug:1786316) +- Update `dnf alias` documentation +- Handle custom exceptions from libdnf +- Fix _skipped_packages to return only skipped (RhBug:1774617) +- Add setter for tsi.reason +- Add new hook for commands: Run_resolved +- Add doc entry: include url (RhBug 1786072) +- Clean also .yaml repository metadata +- New API function base.setup_loggers() (RhBug:1788212) +- Use WantedBy=timers.target for all dnf timers (RhBug:1798475) + +Bugs fixed in 4.2.19: + +* :rhbug:`1798475` +* :rhbug:`1788212` +* :rhbug:`1677774` +* :rhbug:`1786316` +* :rhbug:`1790967` +* :rhbug:`1774617` +* :rhbug:`1534123` +* :rhbug:`1790262` +* :rhbug:`1788154` + +==================== 4.2.18 Release Notes ==================== diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/doc/summaries_cache new/dnf-4.2.19/doc/summaries_cache --- old/dnf-4.2.18/doc/summaries_cache 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/doc/summaries_cache 2020-02-24 15:09:08.000000000 +0100 @@ -3054,5 +3054,41 @@ [ 1781769, "Dnf does not correctly detect the latest version of the module stream" + ], + [ + 1798475, + "[RHEL8/Bug] dnf-makecache timer not on timers.target" + ], + [ + 1788212, + "Packages installed via DNF Python api are not logged to /var/log/dnf.rpm.log or /var/log/dnf.log" + ], + [ + 1677774, + "dnf aborts trying to remove some packages" + ], + [ + 1786316, + "dnf history command output is trimmed because of hardcoded 79 cols limit" + ], + [ + 1790967, + "Misleading Error message when trying to install module without default stream and profile: \"missing groups or modules: <module-name>\"" + ], + [ + 1774617, + "mpv reported as package to be installed and skipped at the same time" + ], + [ + 1534123, + "repoquery: --whatrequires is broken with rich deps" + ], + [ + 1790262, + "dnf repoquery --whatprovides does not support multi paremeters" + ], + [ + 1788154, + "Adding a trailing comma to excludes option causes all items listed for exclusion to be ignored." ] ] \ No newline at end of file diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/etc/systemd/dnf-automatic-download.timer new/dnf-4.2.19/etc/systemd/dnf-automatic-download.timer --- old/dnf-4.2.18/etc/systemd/dnf-automatic-download.timer 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/etc/systemd/dnf-automatic-download.timer 2020-02-24 15:09:08.000000000 +0100 @@ -10,4 +10,4 @@ Persistent=true [Install] -WantedBy=multi-user.target +WantedBy=timers.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/etc/systemd/dnf-automatic-install.timer new/dnf-4.2.19/etc/systemd/dnf-automatic-install.timer --- old/dnf-4.2.18/etc/systemd/dnf-automatic-install.timer 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/etc/systemd/dnf-automatic-install.timer 2020-02-24 15:09:08.000000000 +0100 @@ -10,4 +10,4 @@ Persistent=true [Install] -WantedBy=multi-user.target +WantedBy=timers.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/etc/systemd/dnf-automatic-notifyonly.timer new/dnf-4.2.19/etc/systemd/dnf-automatic-notifyonly.timer --- old/dnf-4.2.18/etc/systemd/dnf-automatic-notifyonly.timer 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/etc/systemd/dnf-automatic-notifyonly.timer 2020-02-24 15:09:08.000000000 +0100 @@ -10,4 +10,4 @@ Persistent=true [Install] -WantedBy=multi-user.target +WantedBy=timers.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/etc/systemd/dnf-automatic.timer new/dnf-4.2.19/etc/systemd/dnf-automatic.timer --- old/dnf-4.2.18/etc/systemd/dnf-automatic.timer 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/etc/systemd/dnf-automatic.timer 2020-02-24 15:09:08.000000000 +0100 @@ -10,4 +10,4 @@ Persistent=true [Install] -WantedBy=multi-user.target +WantedBy=timers.target diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/dnf-4.2.18/etc/systemd/dnf-makecache.timer new/dnf-4.2.19/etc/systemd/dnf-makecache.timer --- old/dnf-4.2.18/etc/systemd/dnf-makecache.timer 2020-01-15 10:51:14.000000000 +0100 +++ new/dnf-4.2.19/etc/systemd/dnf-makecache.timer 2020-02-24 15:09:08.000000000 +0100 @@ -11,4 +11,4 @@ Unit=dnf-makecache.service [Install] -WantedBy=multi-user.target +WantedBy=timers.target
