mluscon pushed to dnf-plugins-core (f21). "New release 0.1.5-2"
notifications at fedoraproject.org
notifications at fedoraproject.org
Tue Apr 14 13:38:20 UTC 2015
>From f8822547d30496278afdb2eaa2adf7c41f6d8ef9 Mon Sep 17 00:00:00 2001
From: Michal Luscon <mluscon at redhat.com>
Date: Tue, 14 Apr 2015 14:57:35 +0200
Subject: New release 0.1.5-2
diff --git a/.gitignore b/.gitignore
index ffaf1ce..6e98b30 100644
--- a/.gitignore
+++ b/.gitignore
@@ -5,3 +5,4 @@
/dnf-plugins-core-d8e8044.tar.xz
/dnf-plugins-core-c8940d0.tar.xz
/dnf-plugins-core-351e094.tar.xz
+/dnf-plugins-core-0.1.5.tar.gz
diff --git a/dnf-plugins-core-0.1.5-1-to-dnf-plugins-core-0.1.5-2.patch b/dnf-plugins-core-0.1.5-1-to-dnf-plugins-core-0.1.5-2.patch
new file mode 100644
index 0000000..de5d18a
--- /dev/null
+++ b/dnf-plugins-core-0.1.5-1-to-dnf-plugins-core-0.1.5-2.patch
@@ -0,0 +1,2115 @@
+diff --git a/AUTHORS b/AUTHORS
+index 88003d1..c8ce939 100644
+--- a/AUTHORS
++++ b/AUTHORS
+@@ -1,6 +1,7 @@
+ Ales Kozumplik <ales at redhat.com>
+ Igor Gnatenko <i.gnatenko.brain at gmail.com>
+ Jan Silhan <jsilhan at redhat.com>
++Michal Mraka <michael.mraka at redhat.com>
+ Miroslav Suchý <msuchy at redhat.com>
+ Parag Nemade <pnemade at redhat.com>
+ Petr Špaček <pspacek at redhat.com>
+diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
+new file mode 100644
+index 0000000..b9e0a38
+--- /dev/null
++++ b/dnf-plugins-core.spec
+@@ -0,0 +1,329 @@
++%{?!dnf_version: %global dnf_version 0.6.4}
++
++Name: dnf-plugins-core
++Version: 0.1.5
++Release: 2%{?dist}
++Summary: Core Plugins for DNF
++Group: System Environment/Base
++License: GPLv2+
++URL: https://github.com/rpm-software-management/dnf-plugins-core
++
++# source archive is created by running package/archive from a git checkout
++Source0: dnf-plugins-core-%{version}.tar.gz
++
++BuildArch: noarch
++BuildRequires: cmake
++BuildRequires: dnf = %{dnf_version}
++BuildRequires: gettext
++BuildRequires: pykickstart
++BuildRequires: python-nose
++BuildRequires: python-sphinx
++BuildRequires: python2-devel
++Requires: dnf = %{dnf_version}
++Requires: pykickstart
++Requires: python-requests
++
++%description
++Core Plugins for DNF. This package enhance DNF with builddep, config-manager,
++copr, debuginfo-install, download, kickstart, needs-restarting, repoquery and
++reposync commands. Additionally provides generate_completion_cache, noroot and
++protected_packages passive plugins.
++
++%package -n python3-dnf-plugins-core
++Summary: Core Plugins for DNF
++Group: System Environment/Base
++BuildRequires: python3-devel
++BuildRequires: python3-dnf = %{dnf_version}
++BuildRequires: python3-nose
++BuildRequires: python3-sphinx
++Requires: python3-dnf = %{dnf_version}
++
++%description -n python3-dnf-plugins-core
++Core Plugins for DNF, Python 3 version. This package enhance DNF with builddep,
++config-manager, copr, debuginfo-install, download, kickstart, needs-restarting,
++repoquery and reposync commands. Additionally provides generate_completion_cache,
++noroot and protected_packages passive plugins.
++
++%prep
++%setup -q -n dnf-plugins-core-%{version}
++rm -rf py3
++mkdir ../py3
++cp -a . ../py3/
++mv ../py3 ./
++
++%build
++%cmake .
++make %{?_smp_mflags}
++make doc-man
++pushd py3
++%cmake -DPYTHON_DESIRED:str=3 .
++make %{?_smp_mflags}
++make doc-man
++popd
++
++%install
++make install DESTDIR=$RPM_BUILD_ROOT
++%find_lang %{name}
++pushd py3
++make install DESTDIR=$RPM_BUILD_ROOT
++popd
++
++%check
++PYTHONPATH=./plugins /usr/bin/nosetests-2.* -s tests/
++PYTHONPATH=./plugins /usr/bin/nosetests-3.* -s tests/
++
++%files -f %{name}.lang
++%doc AUTHORS COPYING README.rst
++%dir %{_sysconfdir}/dnf/protected.d
++%ghost %{_var}/cache/dnf/packages.db
++%{python_sitelib}/dnf-plugins/*
++%{python_sitelib}/dnfpluginscore/
++%{_mandir}/man8/dnf.plugin.*
++
++%files -n python3-dnf-plugins-core -f %{name}.lang
++%doc AUTHORS COPYING README.rst
++%dir %{_sysconfdir}/dnf/protected.d
++%ghost %{_var}/cache/dnf/packages.db
++%exclude %{python3_sitelib}/dnf-plugins/__pycache__/
++%{python3_sitelib}/dnf-plugins/*
++%{python3_sitelib}/dnf-plugins/__pycache__/*
++%{python3_sitelib}/dnfpluginscore/
++%{_mandir}/man8/dnf.plugin.*
++
++%changelog
++* Mon Apr 13 2015 Michal Luscon <mluscon at redhat.com> 0.1.5-2
++- prepare repo for tito build system (Michal Luscon)
++- migrate raw_input() to Python3 (RhBug:1208399) (Miroslav Suchý)
++- create --destdir if not exist (Michael Mraka)
++- repoquery: Added -s/--source switch, test case and documentation for querying source rpm name (Parag Nemade)
++- repoquery: Added documentation and test case for file switch (Parag Nemade)
++- debuginfo-install: support cases where src.rpm name != binary package name (Petr Spacek)
++- use dnfpluginscore.lib.urlopen() (RhBug:1193047) (Miroslav Suchý)
++- implemented functionality of yum-config-manager (Michael Mraka)
++- repoquery: Added --file switch to show who owns the given file (RhBug:1196952) (Parag Nemade)
++- debuginfo-install: accept packages names specified as NEVRA (RhBug:1171046) (Petr Spacek)
++- repoquery: accept package names specified as NEVRA (RhBug:1179366) (Petr Spacek)
++- download: fix typo in 'No source rpm definded' (Petr Spacek)
++- download: accept package names ending with .src too (Petr Spacek)
++- cosmetic: download: pylint fixes (Jan Silhan)
++- download: Do not disable user-enabled repos (thanks Spacekpe) (Jan Silhan)
++- let pylint ignore unused variables starting with _ (Michael Mraka)
++- updated copyright (Michael Mraka)
++- fixed pylint warning Redefining name from outer scope (Michael Mraka)
++- fixed pylint warning Invalid constant name (Michael Mraka)
++- fixed pylint warnings Line too long (Michael Mraka)
++- pylint fix for Wrong continued indentation (Michael Mraka)
++- updated copyright (Michael Mraka)
++- pylint fix for Specify string format arguments as logging function parameters (Michael Mraka)
++- pylint fix for Method could be a function (Michael Mraka)
++- pylint fix for __init__ method from base class is not called (Michael Mraka)
++- pylint fix for Attribute defined outside __init__ (Michael Mraka)
++- updated copyright (Michael Mraka)
++- pylint fix for __init__ method from base class is not called (Michael Mraka)
++- pylint fix for Wrong continued indentation (Michael Mraka)
++- updated copyright (Michael Mraka)
++- pylint fix for Method could be a function (Michael Mraka)
++- pylint fix for __init__ method from base class is not called (Michael Mraka)
++- updated copyright (Michael Mraka)
++- pylint fix for Unused import (Michael Mraka)
++- pylint fix for __init__ method from base class is not called (Michael Mraka)
++- updated copyright (Michael Mraka)
++- pylint fix for Unused import (Michael Mraka)
++- Add README to tests/ directory (Petr Spacek)
++- AUTHORS: updated (Jan Silhan)
++- download: fix package download on Python 3 (Petr Spacek)
++
++* Thu Feb 5 2015 Jan Silhan <jsilhan at redhat.com> - 0.1.5-1
++- updated package url (Michael Mraka)
++- also dnf_version could be specified on rpmbuild commandline (Michael Mraka)
++- simple script to build test package (Michael Mraka)
++- let gitrev be specified on rpmbuild commandline (Michael Mraka)
++- assign default GITREV value (Michael Mraka)
++- standard way to find out latest commit (Michael Mraka)
++- debuginfo-install: fix handling of subpackages with non-zero epoch (Petr Spacek)
++- debuginfo-install: Make laywers happier by assigning copyright to Red Hat (Petr Spacek)
++- debuginfo-install: remove dead code uncovered by variable renaming (Petr Spacek)
++- debuginfo-install: clearly separate source and debug package names (Petr Spacek)
++- debuginfo-install: use descriptive parameter name in _is_available() (Petr Spacek)
++- repoquery: add -l option to list files contained in the package (Petr Spacek)
++- 1187773 - replace undefined variable (Miroslav Suchý)
++- download: fixed unicode location error (RhBug:1178239) (Jan Silhan)
++- builddep recognizes nosrc.rpm pkgs (RhBug:1166126) (Jan Silhan)
++- builddep: added nosignatures flag to rpm transaction set (Jan Silhan)
++- builddep: more verbose output of non-matching packages (RhBug:1155211) (Jan Silhan)
++- package: archive script is the same as in dnf (Jan Silhan)
++- spec: exclude __pycache__ dir (Igor Gnatenko)
++
++* Fri Dec 5 2014 Jan Silhan <jsilhan at redhat.com> - 0.1.4-1
++- revert of commit 80ae3f4 (Jan Silhan)
++- transifex update (Jan Silhan)
++- spec: binded to current dnf version (Jan Silhan)
++- generate_completion_cache: use sqlite instead of text files (Igor Gnatenko)
++- logging: renamed log file (Related:RhBug:1074715) (Jan Silhan)
++- Add reposync. (RhBug:1139738) (Ales Kozumplik)
++- download: fix traceback if rpm package has no defined sourcerpm (RhBug: 1144003) (Tim Lauridsen)
++- lint: ignore warnings of a test accessing protected attribute. (Ales Kozumplik)
++- repoquery lint: logger is not used. (Ales Kozumplik)
++- repoquery: support querying of weak deps. (Ales Kozumplik)
++- needs_restarting: fix typo (Miroslav Suchý)
++- copr: migrate copr plugin form urlgrabber to python-request (Miroslav Suchý)
++- Add needs-restarting command. (Ales Kozumplik)
++
++* Thu Sep 4 2014 Jan Silhan <jsilhan at redhat.com> - 0.1.3-1
++- repoquery: output times in UTC. (Ales Kozumplik)
++- repoquery: missing help messages. (Ales Kozumplik)
++- repoquery: add --info. (RhBug:1135984) (Ales Kozumplik)
++- add Jan to AUTHORS. (Ales Kozumplik)
++- spec: extended package description with plugin names and commands (Related:RhBug:1132335) (Jan Silhan)
++- copr: check for 'ok' in 'output' for json data (RhBug:1134378) (Igor Gnatenko)
++- README: changed references to new repo location (Jan Silhan)
++- transifex update (Jan Silhan)
++- copr: convert key to unicode before guessing lenght (Miroslav Suchý)
++- Add pnemade to AUTHORS (Ales Kozumplik)
++- debuginfo-install: Use logger as module level variable and not instance attribute since dnf-0.6.0 release (RhBug:1130559) (Parag Nemade)
++- copr: Use logger as module level variable and not instance attribute since dnf-0.6.0 release (RhBug:1130559) (Parag Nemade)
++- copr: implement help command (Igor Gnatenko)
++- debuginfo-install: fix indenting (Igor Gnatenko)
++- debuginfo-install: use srpm basename for debuginfo (Igor Gnatenko)
++
++* Mon Jul 28 2014 Aleš Kozumplík <ales at redhat.com> - 0.1.2-1
++- BashCompletionCache: error strings are unicoded (RhBug:1118809) (Jan Silhan)
++- transifex update (Jan Silhan)
++- debuginfo-install: remove some pylint warnings (Igor Gnatenko)
++- debuginfo-install: fix installing when installed version not found in repos, optimize performance (RhBug: 1108321) (Ig
++- fix: copr plugin message for repo without builds (RhBug:1116389) (Adam Samalik)
++- logging: remove messages about initialization. (Ales Kozumplik)
++
++* Thu Jul 3 2014 Aleš Kozumplík <ales at redhat.com> - 0.1.1-2
++- packaging: add protected_packages.py to the package. (Ales Kozumplik)
++
++* Thu Jul 3 2014 Aleš Kozumplík <ales at redhat.com> - 0.1.1-1
++- protected_packages: prevent removal of the running kernel. (RhBug:1049310) (Ales Kozumplik)
++- packaging: create and own /etc/dnf/protected.d. (Ales Kozumplik)
++- doc: add documentation for protected_packages. (Ales Kozumplik)
++- doc: rename: generate-completion-cache -> generate_completion_cache. (Ales Kozumplik)
++- add protected_packages (RhBug:1111855) (Ales Kozumplik)
++- build: add python-requests to requires (RHBZ: 1104088) (Miroslav Suchý)
++- doc: typo: fix double 'plugin' in release notes. (Ales Kozumplik)
++
++* Wed Jun 4 2014 Aleš Kozumplík <ales at redhat.com> - 0.1.0-1
++- pylint: fix all pylint builddep problems. (Ales Kozumplik)
++- builddep: better error reporting on deps that actually don't exist. (Ales Kozumplik)
++- builddep: load available repos. (RhBug:1103906) (Ales Kozumplik)
++- tests: stop argparse from printing to stdout when tests run. (Ales Kozumplik)
++- packaging: all the manual pages with a glob. (Ales Kozumplik)
++- fix: packaging problem with query.py. (Ales Kozumplik)
++- doc: add reference documentation for repoquery. (Ales Kozumplik)
++- repoquery: support --provides, --requires etc. (Ales Kozumplik)
++- repoquery: make the CLI more compatible with Yum's repoquery. (Ales Kozumplik)
++- repoquery: some cleanups in the plugin and the tests. (Ales Kozumplik)
++- rename: query->repoquery. (RhBug:1045078) (Ales Kozumplik)
++- add pylint script for dnf-core-plugins. (Ales Kozumplik)
++- tests: repoquery: fix unit tests. (Ales Kozumplik)
++- add query tool (Tim Lauridsen)
++
++* Wed May 28 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.8-1
++- build: add sphinx to build requires. (Ales Kozumplik)
++- doc: packaging: add license block to each .rst. (Ales Kozumplik)
++- tests: stray print() in test_download.py. (Ales Kozumplik)
++- doc: put each synopsis on new line (Miroslav Suchý)
++- doc: cosmetic: project name in the documentation. (Ales Kozumplik)
++- doc: cleanups, form, style. (Ales Kozumplik)
++- doc: add documentation and man pages (Tim Lauridsen)
++- copr: remove repofile if failed to enable repo (Igor Gnatenko)
++- copr: honor -y and --assumeno (Miroslav Suchý)
++- py3: absolute imports and unicode literals everywhere. (Ales Kozumplik)
++- debuginfo-install: doesn't install latest pkgs (RhBug: 1096507) (Igor Gnatenko)
++- debuginfo-install: fix description (Igor Gnatenko)
++- debuginfo-install: fix logger debug messages (Igor Gnatenko)
++- build: install the download plugin (Tim Lauridsen)
++- download: update the download plugin with --source, --destdir & --resolve options (Tim Lauridsen)
++- Add a special ArgumentParser to parsing plugin cmd arguments and options (Tim Lauridsen)
++- tests: add __init__.py to make tests a module and use abs imports (Tim Lauridsen)
++- build: simplify plugins/CMakeLists.txt. (Ales Kozumplik)
++- dnf.cli.commands.err_mini_usage() changed name. (Ales Kozumplik)
++- kickstart: do not include kickstart errors into own messages. (Radek Holy)
++
++* Wed Apr 23 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.7-1
++- build: gettext is also needed as a buildreq (Tim Lauridsen)
++- copr: use usage & summary class attributes, to work with dnf 0.5.0 use shared lib dnfpluginscore for translation wrapp
++- build: add cmake as buildreq (Tim Lauridsen)
++- generate-completion-cache: fix shared lib name (Tim Lauridsen)
++- make .spec use gitrev in the source file add helper script for building source archive (Tim Lauridsen)
++- Added transifex config (Tim Lauridsen)
++- tests: use cli logger in kickstart test (Tim Lauridsen)
++- Added translation .pot file Added da translation files so we have something to build & install (Tim Lauridsen)
++- Added CMake files Added CMake build to .spec & and added translation files handling (Tim Lauridsen)
++- make plugins use shared lib added translation wrappers added missing usage & summary PEP8 fixes (Tim Lauridsen)
++- added shared dnfpluginscore lib (Tim Lauridsen)
++- copr: C:139, 0: Unnecessary parens after 'print' keyword (superfluous-parens) (Miroslav Suchý)
++- copr: W: 23, 0: Unused import gettext (unused-import) (Miroslav Suchý)
++- copr: C: 33, 0: No space allowed before : (Miroslav Suchý)
++- copr: some python3 migration (Miroslav Suchý)
++- copr: get rid of dnf i18n imports (Miroslav Suchý)
++- remove dnf.yum.i18n imports. (Ales Kozumplik)
++- copr: Fix the playground upgrade command. (Tadej Janež)
++- copr: implement search function (Igor Gnatenko)
++- better format output (Miroslav Suchý)
++- implement playground plugin (Miroslav Suchý)
++- move removing of repo into method (Miroslav Suchý)
++- check root only for actions which really need root (Miroslav Suchý)
++- move repo downloading into separate method (Miroslav Suchý)
++- define copr url as class attribute (Miroslav Suchý)
++- better wording of warning (Miroslav Suchý)
++- move question to function argument (Miroslav Suchý)
++- move guessing chroot into function (Miroslav Suchý)
++- copr: use common lib use Command.usage & summary cleanup imports & PEP8 fixes (Tim Lauridsen)
++- builddep: added usage & summary & fix some PEP8 issues (Tim Lauridsen)
++- kickstart: use new public Command.usage & Command.summary api (Tim Lauridsen)
++- fix resource leak in builddep.py. (Ales Kozumplik)
++- refactor: command plugins use demands mechanism. (Ales Kozumplik)
++- noroot: move to the new 'demands' mechanism to check the need of root. (Ales Kozumplik)
++- tests: fix locale independence. (Radek Holy)
++- [copr] correctly specify chroot when it should be guessed (Miroslav Suchý)
++
++* Mon Mar 17 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.6-1
++- clenaup: remove commented out code (Miroslav Suchý)
++- copr: list: print description (Igor Gnatenko)
++- builddep: rpm error messages sink. (Ales Kozumplik)
++- builddep: improve error handling on an command argument (RhBug:1074436) (Ales Kozumplik)
++- copr: handling case when no argument is passed on cli (Miroslav Suchý)
++- copr: delete excess argument (Igor Gnatenko)
++- add copr plugin (Miroslav Suchý)
++- debuginfo-install: check for root with dnf api (Igor Gnatenko)
++- packaging: fix bogus dates. (Ales Kozumplik)
++
++* Wed Feb 26 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.5-2
++- packaging: add debuginfo-install.py (Ales Kozumplik)
++
++* Wed Feb 26 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.5-1
++- packaging: add builddep.py to the RPM. (Ales Kozumplik)
++
++* Tue Feb 25 2014 Radek Holý <rholy at redhat.com> - 0.0.4-1
++- refactor: use Base.install instead of installPkgs in kickstart plugin. (Radek Holy)
++- refactor: move kickstart arguments parsing to standalone method. (Radek Holy)
++- tests: test effects instead of mock calls. (Radek Holy)
++- Add debuginfo-install plugin. (RhBug:1045770) (Igor Gnatenko)
++- builddep: needs to be run under root. (RhBug:1065851) (Ales Kozumplik)
++
++* Thu Feb 6 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.3-1
++- tests: import mock through support so its simpler for the test cases. (Ales Kozumplik)
++- packaging: fix typos in the spec. (Ales Kozumplik)
++- [completion_cache] Cache installed packages, update the cache less frequently (Elad Alfassa)
++- Add bash completion to dnf (Elad Alfassa)
++- packaging: missing buildrequire (Ales Kozumplik)
++
++* Mon Jan 13 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.2-1
++- First release.
++
++* Wed Jan 8 2014 Cristian Ciupitu <cristian.ciupitu at yahoo.com> - 0.0.1-4
++- Spec updates.
++
++* Tue Jan 7 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.1-3
++- Spec updates.
++
++* Mon Jan 6 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.1-2
++- Spec updates.
++
++* Fri Dec 20 2013 Aleš Kozumplík <ales at redhat.com> - 0.0.1-1
++- The initial package version.
+diff --git a/doc/conf.py b/doc/conf.py
+index f2741a4..f1976ae 100644
+--- a/doc/conf.py
++++ b/doc/conf.py
+@@ -56,7 +56,7 @@ copyright = u'2014, Red Hat, Licensed under GPLv2+'
+ # The short X.Y version.
+
+ def version_readout():
+- fn = os.path.join(_dirname, '../package/dnf-plugins-core.spec')
++ fn = os.path.join(_dirname, '../dnf-plugins-core.spec')
+ with open(fn) as f:
+ lines = f.readlines()
+ for line in lines:
+@@ -242,6 +242,8 @@ AUTHORS=[u'See AUTHORS in your Core DNF Plugins distribution']
+ man_pages = [
+ ('builddep', 'dnf.plugin.builddep', u'DNF builddep Plugin',
+ AUTHORS, 8),
++ ('config_manager', 'dnf.plugin.config_manager',
++ u'DNF config-manager Plugin', AUTHORS, 8),
+ ('copr', 'dnf.plugin.copr', u'DNF copr Plugin',
+ AUTHORS, 8),
+ ('debuginfo-install', 'dnf.plugin.debuginfo-install',
+diff --git a/doc/config_manager.rst b/doc/config_manager.rst
+new file mode 100644
+index 0000000..cdfbf2d
+--- /dev/null
++++ b/doc/config_manager.rst
+@@ -0,0 +1,79 @@
++..
++ Copyright (C) 2015 Red Hat, Inc.
++
++ This copyrighted material is made available to anyone wishing to use,
++ modify, copy, or redistribute it subject to the terms and conditions of
++ the GNU General Public License v.2, or (at your option) any later version.
++ This program is distributed in the hope that it will be useful, but WITHOUT
++ ANY WARRANTY expressed or implied, including the implied warranties of
++ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
++ Public License for more details. You should have received a copy of the
++ GNU General Public License along with this program; if not, write to the
++ Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
++ 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
++ source code or documentation are not subject to the GNU General Public
++ License and may only be used or replicated with the express permission of
++ Red Hat, Inc.
++
++==========================
++ DNF config-manager Plugin
++==========================
++
++Manage main DNF configuration options, toggle which
++repositories are enabled or disabled, and add new repositories.
++
++--------
++Synopsis
++--------
++
++``dnf config-manager [options] <repo>...``
++
++---------
++Arguments
++---------
++
++``<repo>``
++ Display / modify specified repository. If not specified display / modify main DNF configuration.
++
++-------
++Options
++-------
++
++``--help-cmd``
++ Show this help.
++
++``--add-repo=URL``
++ Add (and enable) the repo from the specified file or url.
++
++``--dump``
++ Print dump of current configuration values to stdout.
++
++``--set-disabled``
++ Disable the specified repos (automatically saves).
++
++``--set-enabled``
++ Enable the specified repos (automatically saves).
++
++``--save``
++ Save the current options (useful with --setopt).
++
++--------
++Examples
++--------
++``dnf config-manager --add-repo http://example.com/some/additional.repo``
++ Download additional.repo and store it in repodir.
++
++``dnf config-manager --add-repo http://example.com/different/repo``
++ Create new repo file with http://example.com/different/repo as baseurl and enable it.
++
++``dnf config-manager``
++ Display main DNF configuration.
++
++``dnf config-manager repo``
++ Display configuration of repo.
++
++``dnf config-manager --set-enabled repo``
++ Enable repo and make the change permanent.
++
++``dnf config-manager --setopt proxy=http://proxy.example.com:3128/ repo1 repo2 --save``
++ Update proxy setting in repo1 and repo2 and make the change permanent.
+diff --git a/doc/download.rst b/doc/download.rst
+index d4653d8..9a24b42 100644
+--- a/doc/download.rst
++++ b/doc/download.rst
+@@ -42,7 +42,7 @@ Options
+ Show this help.
+
+ ``--source``
+- Download the source rpm.
++ Download the source rpm. Enables source repositories of all enabled binary repositories.
+
+ ``--destdir``
+ Download directory, default is the current directory (the directory must exist).
+diff --git a/doc/index.rst b/doc/index.rst
+index e1ee869..3c5b459 100644
+--- a/doc/index.rst
++++ b/doc/index.rst
+@@ -26,6 +26,7 @@ This documents core plugins of DNF:
+
+ release_notes
+ builddep
++ config_manager
+ copr
+ debuginfo-install
+ download
+diff --git a/doc/repoquery.rst b/doc/repoquery.rst
+index 99a8eb7..e14f3ba 100644
+--- a/doc/repoquery.rst
++++ b/doc/repoquery.rst
+@@ -25,7 +25,7 @@ Query package information from Yum repositories.
+ Synopsis
+ --------
+
+-``dnf repoquery [<select-options>] [<query-options>] [<pkg-name>]``
++``dnf repoquery [<select-options>] [<query-options>] [<pkg-spec>]``
+ ``dnf repoquery --querytags``
+
+ -----------
+@@ -38,11 +38,18 @@ Description
+ Select Options
+ --------------
+
+-Together with ``<pkg-name>``, control what packages are displayed in the output. If ``<pkg-name>`` is given, the set of resulting packages is limited to the ones with a matching name (globbing supported), else all packages are considered.
++Together with ``<pkg-spec>``, control what packages are displayed in the output. If ``<pkg-spec>`` is given, the set of resulting packages matching the specification. All packages are considered if no ``<pkg-spec>`` is specified.
++
++``<pkg-spec>``
++ Package specification like: name[-[epoch:]version[-release]][.arch]. See
++ http://dnf.readthedocs.org/en/latest/command_ref.html#specifying-packages
+
+ ``--arch <arch>``
+ Limit the resulting set only to packages of arch ``<arch>``.
+
++``-f <file>``, ``--file <file>``
++ Limit the resulting set only to package that owns ``<file>``.
++
+ ``--repoid <id>``
+ Limit the resulting set only to packages from repo identified by ``<id>``.
+
+@@ -71,6 +78,9 @@ The following are mutually exclusive, i.e. at most one can be specified. If no q
+ ``-l, --list``
+ Show list of files in the package.
+
++``-s, --source``
++ Show package source RPM name.
++
+ ``--obsoletes``
+ Display capabilities that the package obsoletes. Same as ``--qf "%{obsoletes}``.
+
+@@ -96,6 +106,14 @@ Display requires of all ligttpd packages::
+
+ dnf repoquery --requires lighttpd
+
++Display source rpm of ligttpd package::
++
++ dnf repoquery --source lighttpd
++
++Display package name that owns the given file::
++
++ dnf repoquery --file /etc/lighttpd/lighttpd.conf
++
+ Display name, architecture and the containing repository of all lighttpd packages::
+
+ dnf repoquery --queryformat '%{name}.%{arch} : %{reponame}' lighttpd
+diff --git a/package/archive b/package/archive
+deleted file mode 100755
+index 16f652e..0000000
+--- a/package/archive
++++ /dev/null
+@@ -1,11 +0,0 @@
+-#! /bin/bash
+-
+-GITREV=${1:-$(git rev-parse --short HEAD)}
+-# shorten to 7 characters
+-GITREV=${GITREV:0:7}
+-
+-echo $GITREV
+-
+-TARGET_DIR=$HOME/rpmbuild/SOURCES
+-mkdir -p $TARGET_DIR
+-git archive ${GITREV} --prefix=dnf-plugins-core/ | xz > $TARGET_DIR/dnf-plugins-core-${GITREV}.tar.xz
+diff --git a/package/build-test-rpm b/package/build-test-rpm
+deleted file mode 100755
+index 2241c8c..0000000
+--- a/package/build-test-rpm
++++ /dev/null
+@@ -1,9 +0,0 @@
+-#!/bin/bash
+-
+-DIR=$(dirname "$0")
+-GITREV=${1:-$(git rev-parse --short HEAD)}
+-# shorten long SHA1 from user to 7 characters
+-GITREV=${GITREV:0:7}
+-
+-$DIR/archive "$GITREV"
+-rpmbuild -ba --define "gitrev $GITREV" $DIR/*.spec
+diff --git a/package/dnf-plugins-core.spec b/package/dnf-plugins-core.spec
+deleted file mode 100644
+index ac288a7..0000000
+--- a/package/dnf-plugins-core.spec
++++ /dev/null
+@@ -1,268 +0,0 @@
+-%{!?gitrev: %global gitrev c8940d0}
+-%{?!dnf_version: %global dnf_version 0.6.3}
+-
+-Name: dnf-plugins-core
+-Version: 0.1.5
+-Release: 1%{?dist}
+-Summary: Core Plugins for DNF
+-Group: System Environment/Base
+-License: GPLv2+
+-URL: https://github.com/rpm-software-management/dnf-plugins-core
+-
+-# source archive is created by running package/archive from a git checkout
+-Source0: dnf-plugins-core-%{gitrev}.tar.xz
+-
+-BuildArch: noarch
+-BuildRequires: cmake
+-BuildRequires: dnf = %{dnf_version}
+-BuildRequires: gettext
+-BuildRequires: pykickstart
+-BuildRequires: python-nose
+-BuildRequires: python-sphinx
+-BuildRequires: python2-devel
+-Requires: dnf = %{dnf_version}
+-Requires: pykickstart
+-Requires: python-requests
+-
+-%description
+-Core Plugins for DNF. This package enhance DNF with builddep, copr,
+-debuginfo-install, download, kickstart, needs-restarting, repoquery and
+-reposync commands. Additionally provides generate_completion_cache, noroot and
+-protected_packages passive plugins.
+-
+-%package -n python3-dnf-plugins-core
+-Summary: Core Plugins for DNF
+-Group: System Environment/Base
+-BuildRequires: python3-devel
+-BuildRequires: python3-dnf = %{dnf_version}
+-BuildRequires: python3-nose
+-BuildRequires: python3-sphinx
+-Requires: python3-dnf = %{dnf_version}
+-
+-%description -n python3-dnf-plugins-core
+-Core Plugins for DNF, Python 3 version. This package enhance DNF with builddep, copr,
+-debuginfo-install, download, kickstart, needs-restarting, repoquery and
+-reposync commands. Additionally provides generate_completion_cache, noroot and
+-protected_packages passive plugins.
+-
+-%prep
+-%setup -q -n dnf-plugins-core
+-rm -rf py3
+-mkdir ../py3
+-cp -a . ../py3/
+-mv ../py3 ./
+-
+-%build
+-%cmake .
+-make %{?_smp_mflags}
+-make doc-man
+-pushd py3
+-%cmake -DPYTHON_DESIRED:str=3 .
+-make %{?_smp_mflags}
+-make doc-man
+-popd
+-
+-%install
+-make install DESTDIR=$RPM_BUILD_ROOT
+-%find_lang %{name}
+-pushd py3
+-make install DESTDIR=$RPM_BUILD_ROOT
+-popd
+-
+-%check
+-PYTHONPATH=./plugins /usr/bin/nosetests-2.* -s tests/
+-PYTHONPATH=./plugins /usr/bin/nosetests-3.* -s tests/
+-
+-%files -f %{name}.lang
+-%doc AUTHORS COPYING README.rst
+-%dir %{_sysconfdir}/dnf/protected.d
+-%ghost %{_var}/cache/dnf/packages.db
+-%{python_sitelib}/dnf-plugins/*
+-%{python_sitelib}/dnfpluginscore/
+-%{_mandir}/man8/dnf.plugin.*
+-
+-%files -n python3-dnf-plugins-core -f %{name}.lang
+-%doc AUTHORS COPYING README.rst
+-%dir %{_sysconfdir}/dnf/protected.d
+-%ghost %{_var}/cache/dnf/packages.db
+-%exclude %{python3_sitelib}/dnf-plugins/__pycache__/
+-%{python3_sitelib}/dnf-plugins/*
+-%{python3_sitelib}/dnf-plugins/__pycache__/*
+-%{python3_sitelib}/dnfpluginscore/
+-%{_mandir}/man8/dnf.plugin.*
+-
+-%changelog
+-
+-* Fri Dec 5 2014 Jan Silhan <jsilhan at redhat.com> - 0.1.4-1
+-- revert of commit 80ae3f4 (Jan Silhan)
+-- transifex update (Jan Silhan)
+-- spec: binded to current dnf version (Jan Silhan)
+-- generate_completion_cache: use sqlite instead of text files (Igor Gnatenko)
+-- logging: renamed log file (Related:RhBug:1074715) (Jan Silhan)
+-- Add reposync. (RhBug:1139738) (Ales Kozumplik)
+-- download: fix traceback if rpm package has no defined sourcerpm (RhBug: 1144003) (Tim Lauridsen)
+-- lint: ignore warnings of a test accessing protected attribute. (Ales Kozumplik)
+-- repoquery lint: logger is not used. (Ales Kozumplik)
+-- repoquery: support querying of weak deps. (Ales Kozumplik)
+-- needs_restarting: fix typo (Miroslav Suchý)
+-- copr: migrate copr plugin form urlgrabber to python-request (Miroslav Suchý)
+-- Add needs-restarting command. (Ales Kozumplik)
+-
+-* Thu Sep 4 2014 Jan Silhan <jsilhan at redhat.com> - 0.1.3-1
+-- repoquery: output times in UTC. (Ales Kozumplik)
+-- repoquery: missing help messages. (Ales Kozumplik)
+-- repoquery: add --info. (RhBug:1135984) (Ales Kozumplik)
+-- add Jan to AUTHORS. (Ales Kozumplik)
+-- spec: extended package description with plugin names and commands (Related:RhBug:1132335) (Jan Silhan)
+-- copr: check for 'ok' in 'output' for json data (RhBug:1134378) (Igor Gnatenko)
+-- README: changed references to new repo location (Jan Silhan)
+-- transifex update (Jan Silhan)
+-- copr: convert key to unicode before guessing lenght (Miroslav Suchý)
+-- Add pnemade to AUTHORS (Ales Kozumplik)
+-- debuginfo-install: Use logger as module level variable and not instance attribute since dnf-0.6.0 release (RhBug:1130559) (Parag Nemade)
+-- copr: Use logger as module level variable and not instance attribute since dnf-0.6.0 release (RhBug:1130559) (Parag Nemade)
+-- copr: implement help command (Igor Gnatenko)
+-- debuginfo-install: fix indenting (Igor Gnatenko)
+-- debuginfo-install: use srpm basename for debuginfo (Igor Gnatenko)
+-
+-* Mon Jul 28 2014 Aleš Kozumplík <ales at redhat.com> - 0.1.2-1
+-- BashCompletionCache: error strings are unicoded (RhBug:1118809) (Jan Silhan)
+-- transifex update (Jan Silhan)
+-- debuginfo-install: remove some pylint warnings (Igor Gnatenko)
+-- debuginfo-install: fix installing when installed version not found in repos, optimize performance (RhBug: 1108321) (Ig
+-- fix: copr plugin message for repo without builds (RhBug:1116389) (Adam Samalik)
+-- logging: remove messages about initialization. (Ales Kozumplik)
+-
+-* Thu Jul 3 2014 Aleš Kozumplík <ales at redhat.com> - 0.1.1-2
+-- packaging: add protected_packages.py to the package. (Ales Kozumplik)
+-
+-* Thu Jul 3 2014 Aleš Kozumplík <ales at redhat.com> - 0.1.1-1
+-- protected_packages: prevent removal of the running kernel. (RhBug:1049310) (Ales Kozumplik)
+-- packaging: create and own /etc/dnf/protected.d. (Ales Kozumplik)
+-- doc: add documentation for protected_packages. (Ales Kozumplik)
+-- doc: rename: generate-completion-cache -> generate_completion_cache. (Ales Kozumplik)
+-- add protected_packages (RhBug:1111855) (Ales Kozumplik)
+-- build: add python-requests to requires (RHBZ: 1104088) (Miroslav Suchý)
+-- doc: typo: fix double 'plugin' in release notes. (Ales Kozumplik)
+-
+-* Wed Jun 4 2014 Aleš Kozumplík <ales at redhat.com> - 0.1.0-1
+-- pylint: fix all pylint builddep problems. (Ales Kozumplik)
+-- builddep: better error reporting on deps that actually don't exist. (Ales Kozumplik)
+-- builddep: load available repos. (RhBug:1103906) (Ales Kozumplik)
+-- tests: stop argparse from printing to stdout when tests run. (Ales Kozumplik)
+-- packaging: all the manual pages with a glob. (Ales Kozumplik)
+-- fix: packaging problem with query.py. (Ales Kozumplik)
+-- doc: add reference documentation for repoquery. (Ales Kozumplik)
+-- repoquery: support --provides, --requires etc. (Ales Kozumplik)
+-- repoquery: make the CLI more compatible with Yum's repoquery. (Ales Kozumplik)
+-- repoquery: some cleanups in the plugin and the tests. (Ales Kozumplik)
+-- rename: query->repoquery. (RhBug:1045078) (Ales Kozumplik)
+-- add pylint script for dnf-core-plugins. (Ales Kozumplik)
+-- tests: repoquery: fix unit tests. (Ales Kozumplik)
+-- add query tool (Tim Lauridsen)
+-
+-* Wed May 28 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.8-1
+-- build: add sphinx to build requires. (Ales Kozumplik)
+-- doc: packaging: add license block to each .rst. (Ales Kozumplik)
+-- tests: stray print() in test_download.py. (Ales Kozumplik)
+-- doc: put each synopsis on new line (Miroslav Suchý)
+-- doc: cosmetic: project name in the documentation. (Ales Kozumplik)
+-- doc: cleanups, form, style. (Ales Kozumplik)
+-- doc: add documentation and man pages (Tim Lauridsen)
+-- copr: remove repofile if failed to enable repo (Igor Gnatenko)
+-- copr: honor -y and --assumeno (Miroslav Suchý)
+-- py3: absolute imports and unicode literals everywhere. (Ales Kozumplik)
+-- debuginfo-install: doesn't install latest pkgs (RhBug: 1096507) (Igor Gnatenko)
+-- debuginfo-install: fix description (Igor Gnatenko)
+-- debuginfo-install: fix logger debug messages (Igor Gnatenko)
+-- build: install the download plugin (Tim Lauridsen)
+-- download: update the download plugin with --source, --destdir & --resolve options (Tim Lauridsen)
+-- Add a special ArgumentParser to parsing plugin cmd arguments and options (Tim Lauridsen)
+-- tests: add __init__.py to make tests a module and use abs imports (Tim Lauridsen)
+-- build: simplify plugins/CMakeLists.txt. (Ales Kozumplik)
+-- dnf.cli.commands.err_mini_usage() changed name. (Ales Kozumplik)
+-- kickstart: do not include kickstart errors into own messages. (Radek Holy)
+-
+-* Wed Apr 23 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.7-1
+-- build: gettext is also needed as a buildreq (Tim Lauridsen)
+-- copr: use usage & summary class attributes, to work with dnf 0.5.0 use shared lib dnfpluginscore for translation wrapp
+-- build: add cmake as buildreq (Tim Lauridsen)
+-- generate-completion-cache: fix shared lib name (Tim Lauridsen)
+-- make .spec use gitrev in the source file add helper script for building source archive (Tim Lauridsen)
+-- Added transifex config (Tim Lauridsen)
+-- tests: use cli logger in kickstart test (Tim Lauridsen)
+-- Added translation .pot file Added da translation files so we have something to build & install (Tim Lauridsen)
+-- Added CMake files Added CMake build to .spec & and added translation files handling (Tim Lauridsen)
+-- make plugins use shared lib added translation wrappers added missing usage & summary PEP8 fixes (Tim Lauridsen)
+-- added shared dnfpluginscore lib (Tim Lauridsen)
+-- copr: C:139, 0: Unnecessary parens after 'print' keyword (superfluous-parens) (Miroslav Suchý)
+-- copr: W: 23, 0: Unused import gettext (unused-import) (Miroslav Suchý)
+-- copr: C: 33, 0: No space allowed before : (Miroslav Suchý)
+-- copr: some python3 migration (Miroslav Suchý)
+-- copr: get rid of dnf i18n imports (Miroslav Suchý)
+-- remove dnf.yum.i18n imports. (Ales Kozumplik)
+-- copr: Fix the playground upgrade command. (Tadej Janež)
+-- copr: implement search function (Igor Gnatenko)
+-- better format output (Miroslav Suchý)
+-- implement playground plugin (Miroslav Suchý)
+-- move removing of repo into method (Miroslav Suchý)
+-- check root only for actions which really need root (Miroslav Suchý)
+-- move repo downloading into separate method (Miroslav Suchý)
+-- define copr url as class attribute (Miroslav Suchý)
+-- better wording of warning (Miroslav Suchý)
+-- move question to function argument (Miroslav Suchý)
+-- move guessing chroot into function (Miroslav Suchý)
+-- copr: use common lib use Command.usage & summary cleanup imports & PEP8 fixes (Tim Lauridsen)
+-- builddep: added usage & summary & fix some PEP8 issues (Tim Lauridsen)
+-- kickstart: use new public Command.usage & Command.summary api (Tim Lauridsen)
+-- fix resource leak in builddep.py. (Ales Kozumplik)
+-- refactor: command plugins use demands mechanism. (Ales Kozumplik)
+-- noroot: move to the new 'demands' mechanism to check the need of root. (Ales Kozumplik)
+-- tests: fix locale independence. (Radek Holy)
+-- [copr] correctly specify chroot when it should be guessed (Miroslav Suchý)
+-
+-* Mon Mar 17 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.6-1
+-- clenaup: remove commented out code (Miroslav Suchý)
+-- copr: list: print description (Igor Gnatenko)
+-- builddep: rpm error messages sink. (Ales Kozumplik)
+-- builddep: improve error handling on an command argument (RhBug:1074436) (Ales Kozumplik)
+-- copr: handling case when no argument is passed on cli (Miroslav Suchý)
+-- copr: delete excess argument (Igor Gnatenko)
+-- add copr plugin (Miroslav Suchý)
+-- debuginfo-install: check for root with dnf api (Igor Gnatenko)
+-- packaging: fix bogus dates. (Ales Kozumplik)
+-
+-* Wed Feb 26 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.5-2
+-- packaging: add debuginfo-install.py (Ales Kozumplik)
+-
+-* Wed Feb 26 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.5-1
+-- packaging: add builddep.py to the RPM. (Ales Kozumplik)
+-
+-* Tue Feb 25 2014 Radek Holý <rholy at redhat.com> - 0.0.4-1
+-- refactor: use Base.install instead of installPkgs in kickstart plugin. (Radek Holy)
+-- refactor: move kickstart arguments parsing to standalone method. (Radek Holy)
+-- tests: test effects instead of mock calls. (Radek Holy)
+-- Add debuginfo-install plugin. (RhBug:1045770) (Igor Gnatenko)
+-- builddep: needs to be run under root. (RhBug:1065851) (Ales Kozumplik)
+-
+-* Thu Feb 6 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.3-1
+-- tests: import mock through support so its simpler for the test cases. (Ales Kozumplik)
+-- packaging: fix typos in the spec. (Ales Kozumplik)
+-- [completion_cache] Cache installed packages, update the cache less frequently (Elad Alfassa)
+-- Add bash completion to dnf (Elad Alfassa)
+-- packaging: missing buildrequire (Ales Kozumplik)
+-
+-* Mon Jan 13 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.2-1
+-- First release.
+-
+-* Wed Jan 8 2014 Cristian Ciupitu <cristian.ciupitu at yahoo.com> - 0.0.1-4
+-- Spec updates.
+-
+-* Tue Jan 7 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.1-3
+-- Spec updates.
+-
+-* Mon Jan 6 2014 Aleš Kozumplík <ales at redhat.com> - 0.0.1-2
+-- Spec updates.
+-
+-* Fri Dec 20 2013 Aleš Kozumplík <ales at redhat.com> - 0.0.1-1
+-- The initial package version.
+diff --git a/plugins/CMakeLists.txt b/plugins/CMakeLists.txt
+index a21777b..1f40737 100644
+--- a/plugins/CMakeLists.txt
++++ b/plugins/CMakeLists.txt
+@@ -1,5 +1,6 @@
+ INSTALL (FILES builddep.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
+ INSTALL (FILES debuginfo-install.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
++INSTALL (FILES config_manager.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
+ INSTALL (FILES copr.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
+ INSTALL (FILES download.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
+ INSTALL (FILES generate_completion_cache.py DESTINATION ${PYTHON_INSTALL_DIR}/dnf-plugins)
+diff --git a/plugins/config_manager.py b/plugins/config_manager.py
+new file mode 100644
+index 0000000..812e34a
+--- /dev/null
++++ b/plugins/config_manager.py
+@@ -0,0 +1,255 @@
++#
++# Copyright (C) 2015 Red Hat, Inc.
++#
++# This copyrighted material is made available to anyone wishing to use,
++# modify, copy, or redistribute it subject to the terms and conditions of
++# the GNU General Public License v.2, or (at your option) any later version.
++# This program is distributed in the hope that it will be useful, but WITHOUT
++# ANY WARRANTY expressed or implied, including the implied warranties of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
++# Public License for more details. You should have received a copy of the
++# GNU General Public License along with this program; if not, write to the
++# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
++# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
++# source code or documentation are not subject to the GNU General Public
++# License and may only be used or replicated with the express permission of
++# Red Hat, Inc.
++#
++
++from __future__ import absolute_import
++from __future__ import unicode_literals
++from dnfpluginscore import _, logger
++
++import dnf
++import dnf.cli
++import dnf.pycomp
++import dnfpluginscore
++import dnfpluginscore.lib
++import os
++import re
++import shutil
++
++
++class ConfigManager(dnf.Plugin):
++
++ name = 'config-manager'
++
++ def __init__(self, base, cli):
++ super(ConfigManager, self).__init__(base, cli)
++ self.base = base
++ self.cli = cli
++ if self.cli is not None:
++ self.cli.register_command(ConfigManagerCommand)
++
++
++class ConfigManagerCommand(dnf.cli.Command):
++
++ aliases = ['config-manager']
++ summary = _('manage dnf configuration options and repositories')
++ usage = '[%s] [%s]' % (_('OPTIONS'), _('KEYWORDS'))
++
++ def __init__(self, cli):
++ super(ConfigManagerCommand, self).__init__(cli)
++ self.opts = None
++ self.parser = None
++
++ def configure(self, args):
++ # setup sack and populate it with enabled repos
++ demands = self.cli.demands
++ demands.available_repos = True
++
++ self.parser = dnfpluginscore.ArgumentParser(self.aliases[0])
++ self.parser.add_argument(
++ 'repo', nargs='*',
++ help=_('repo to modify'))
++ self.parser.add_argument(
++ '--save', default=False, action='store_true',
++ help=_('save the current options (useful with --setopt)'))
++ self.parser.add_argument(
++ '--set-enabled', default=False, action='store_true',
++ help=_('enable the specified repos (automatically saves)'))
++ self.parser.add_argument(
++ '--set-disabled', default=False, action='store_true',
++ help=_('disable the specified repos (automatically saves)'))
++ self.parser.add_argument(
++ '--add-repo', default=[], action='append', metavar='URL',
++ help=_('add (and enable) the repo from the specified file or url'))
++ self.parser.add_argument(
++ '--dump', default=False, action='store_true',
++ help=_('print current configuration values to stdout'))
++
++ self.opts = self.parser.parse_args(args)
++
++ if self.opts.help_cmd:
++ print(self.parser.format_help())
++ return
++
++ if (self.opts.save or self.opts.set_enabled or
++ self.opts.set_disabled or self.opts.add_repo):
++ demands.root_user = True
++
++
++ def run(self, _args):
++ """Execute the util action here."""
++
++ if self.opts.help_cmd:
++ return
++ if self.opts.set_enabled and self.opts.set_disabled:
++ logger.error(
++ _("Error: Trying to enable and disable repos at the same time."))
++ self.opts.set_enabled = self.opts.set_disabled = False
++ if self.opts.set_enabled and not self.opts.repo:
++ logger.error(_("Error: Trying to enable already enabled repos."))
++ self.opts.set_enabled = False
++
++ if self.opts.add_repo:
++ self.add_repo()
++ else:
++ self.modify_repo()
++
++ def modify_repo(self):
++ """ process --set-enabled, --set-disabled and --setopt options """
++
++ sbc = self.base.conf
++ modify = []
++ if hasattr(self.cli, 'main_setopts') and self.cli.main_setopts:
++ modify = self.cli.main_setopts.items
++ if not self.opts.repo or 'main' in self.opts.repo:
++ if self.opts.dump:
++ print(self.base.output.fmtSection('main'))
++ print(self.base.conf.dump())
++ if self.opts.save and modify:
++ # modify [main] in dnf.conf
++ dnfpluginscore.lib.write_raw_configfile(dnf.const.CONF_FILENAME,
++ 'main', sbc.substitutions,
++ sbc.cfg.options,
++ sbc.iteritems,
++ sbc.optionobj,
++ modify)
++
++ if self.opts.set_enabled or self.opts.set_disabled:
++ self.opts.save = True
++ modify.append('enabled')
++
++ if self.opts.repo:
++ matched = []
++ for name in self.opts.repo:
++ matched.extend(self.base.repos.get_matching(name))
++ else:
++ matched = self.base.repos.iter_enabled()
++
++ if not matched:
++ raise dnf.exceptions.Error(_("No matching repo to modify: %s.")
++ % ', '.join(self.opts.repo))
++ for repo in sorted(matched):
++ if self.opts.dump:
++ print(self.base.output.fmtSection('repo: ' + repo.id))
++ if self.opts.set_enabled and not repo.enabled:
++ repo.enable()
++ elif self.opts.set_disabled and repo.enabled:
++ repo.disable()
++ if self.opts.dump:
++ print(repo.dump())
++ repo_modify = modify[:]
++ if (hasattr(self.cli, 'repo_setopts')
++ and repo.id in self.cli.repo_setopts):
++ repo_modify.extend(self.cli.repo_setopts[repo.id].items)
++ if self.opts.save and modify:
++ dnfpluginscore.lib.write_raw_configfile(repo.repofile,
++ repo.id,
++ sbc.substitutions,
++ repo.cfg.options,
++ repo.iteritems,
++ repo.optionobj,
++ repo_modify)
++
++ def add_repo(self):
++ """ process --add-repo option """
++
++ # put repo file into first reposdir which exists or create it
++ myrepodir = None
++ for rdir in self.base.conf.reposdir:
++ if os.path.exists(rdir):
++ myrepodir = rdir
++ break
++
++ if not myrepodir:
++ myrepodir = self.base.conf.reposdir[0]
++ dnf.util.ensure_dir(myrepodir)
++
++ for url in self.opts.add_repo:
++ if dnf.pycomp.urlparse.urlparse(url).scheme == '':
++ url = 'file://' + os.path.abspath(url)
++ logger.info(_('Adding repo from: %s'), url)
++ if url.endswith('.repo'):
++ # .repo file - download, put into reposdir and enable it
++ destname = os.path.basename(url)
++ destname = os.path.join(myrepodir, destname)
++ try:
++ f = dnfpluginscore.lib.urlopen(self, None, url, 'w+')
++ shutil.copy2(f.name, destname)
++ f.close()
++ except IOError as e:
++ logger.error(e)
++ continue
++ else:
++ # just url to repo, create .repo file on our own
++ repoid = sanitize_url_to_fs(url)
++ reponame = 'created by dnf config-manager from %s' % url
++ destname = os.path.join(myrepodir, "%s.repo" % repoid)
++ content = "[%s]\nname=%s\nbaseurl=%s\nenabled=1\n" % \
++ (repoid, reponame, url)
++ if not save_to_file(destname, content):
++ continue
++
++
++def save_to_file(filename, content):
++ try:
++ with open(filename, 'w+') as fd:
++ dnf.pycomp.write_to_file(fd, content)
++ except (IOError, OSError) as e:
++ logger.error(_('Could not save repo to repofile %s: %s'),
++ filename, e)
++ return False
++ return True
++
++# Regular expressions to sanitise cache filenames
++RE_SCHEME = re.compile(r'^\w+:/*(\w+:|www\.)?')
++RE_SLASH = re.compile(r'[?/:&#|]+')
++RE_BEGIN = re.compile(r'^[,.]*')
++RE_FINAL = re.compile(r'[,.]*$')
++
++def sanitize_url_to_fs(url):
++ """Return a filename suitable for the filesystem
++
++ Strips dangerous and common characters to create a filename we
++ can use to store the cache in.
++ """
++
++ try:
++ if RE_SCHEME.match(url):
++ if dnf.pycomp.PY3:
++ url = url.encode('idna').decode('utf-8')
++ else:
++ if isinstance(url, str):
++ url = url.decode('utf-8').encode('idna')
++ else:
++ url = url.encode('idna')
++ if isinstance(url, unicode):
++ url = url.encode('utf-8')
++ except (UnicodeDecodeError, UnicodeEncodeError, UnicodeError, TypeError):
++ pass
++ url = RE_SCHEME.sub("", url)
++ url = RE_SLASH.sub("_", url)
++ url = RE_BEGIN.sub("", url)
++ url = RE_FINAL.sub("", url)
++
++ # limit length of url
++ if len(url) > 250:
++ parts = url[:185].split('_')
++ lastindex = 185-len(parts[-1])
++ csum = dnf.yum.misc.Checksums(['sha256'])
++ csum.update(url[lastindex:])
++ url = url[:lastindex] + '_' + csum.hexdigest()
++
++ return url
+diff --git a/plugins/copr.py b/plugins/copr.py
+index 3a91ce6..8295855 100644
+--- a/plugins/copr.py
++++ b/plugins/copr.py
+@@ -1,6 +1,6 @@
+ # supplies the 'copr' command.
+ #
+-# Copyright (C) 2014 Red Hat, Inc.
++# Copyright (C) 2014-2015 Red Hat, Inc.
+ #
+ # This copyrighted material is made available to anyone wishing to use,
+ # modify, copy, or redistribute it subject to the terms and conditions of
+@@ -20,6 +20,7 @@
+ from __future__ import print_function
+ from dnfpluginscore import _, logger
+ from dnf.i18n import ucd
++import dnfpluginscore.lib
+
+ import dnf
+ import glob
+@@ -30,9 +31,14 @@ import requests
+ import urllib
+
+
+-yes = set([_('yes'), _('y')])
+-no = set([_('no'), _('n'), ''])
++YES = set([_('yes'), _('y')])
++NO = set([_('no'), _('n'), ''])
+
++# compatibility with Py2 and Py3 - rename raw_input() to input() on Py2
++try:
++ input = raw_input
++except NameError:
++ pass
+
+ class Copr(dnf.Plugin):
+ """DNF plugin supplying the 'copr' command."""
+@@ -118,8 +124,7 @@ Do you want to continue? [y/N]: """)
+ #http://copr.fedoraproject.org/api/coprs/ignatenkobrain/
+ api_path = "/api/coprs/{}/".format(project_name)
+
+- opener = urllib.FancyURLopener({})
+- res = opener.open(self.copr_url + api_path)
++ res = dnfpluginscore.lib.urlopen(self, None, self.copr_url + api_path, 'w+')
+ try:
+ json_parse = json.loads(res.read())
+ except ValueError:
+@@ -132,7 +137,7 @@ Do you want to continue? [y/N]: """)
+ i = 0
+ while i < len(json_parse["repos"]):
+ msg = "{0}/{1} : ".format(project_name,
+- json_parse["repos"][i]["name"])
++ json_parse["repos"][i]["name"])
+ desc = json_parse["repos"][i]["description"]
+ if not desc:
+ desc = _("No description given")
+@@ -143,18 +148,19 @@ Do you want to continue? [y/N]: """)
+ #http://copr.fedoraproject.org/api/coprs/search/tests/
+ api_path = "/api/coprs/search/{}/".format(project_name)
+
+- opener = urllib.FancyURLopener({})
+- res = opener.open(self.copr_url + api_path)
++ res = dnfpluginscore.lib.urlopen(self, None, self.copr_url + api_path, 'w+')
+ try:
+ json_parse = json.loads(res.read())
+ except ValueError:
+- raise dnf.exceptions.Error(_("Can't parse search for '{}'.").format(project_name))
++ raise dnf.exceptions.Error(_("Can't parse search for '{}'."
++ ).format(project_name))
+ self._check_json_output(json_parse)
+ section_text = _("Matched: {}").format(project_name)
+ self._print_match_section(section_text)
+ i = 0
+ while i < len(json_parse["repos"]):
+- msg = "{0}/{1} : ".format(json_parse["repos"][i]["username"], json_parse["repos"][i]["coprname"])
++ msg = "{0}/{1} : ".format(json_parse["repos"][i]["username"],
++ json_parse["repos"][i]["coprname"])
+ desc = json_parse["repos"][i]["description"]
+ if not desc:
+ desc = _("No description given.")
+@@ -175,12 +181,12 @@ Do you want to continue? [y/N]: """)
+ elif self.base.conf.assumeno and not self.base.conf.assumeyes:
+ raise dnf.exceptions.Error(_('Safe and good answer. Exiting.'))
+
+- answer = raw_input(question).lower()
++ answer = input(question).lower()
+ answer = _(answer)
+- while not ((answer in yes) or (answer in no)):
+- answer = raw_input(question).lower()
++ while not ((answer in YES) or (answer in NO)):
++ answer = input(question).lower()
+ answer = _(answer)
+- if answer in yes:
++ if answer in YES:
+ return
+ else:
+ raise dnf.exceptions.Error(_('Safe and good answer. Exiting.'))
+@@ -256,9 +262,9 @@ Do you want to continue? [y/N]: """)
+ return output
+
+ @classmethod
+- def _check_json_output(cls, json):
+- if json["output"] != "ok":
+- raise dnf.exceptions.Error("{}".format(json["error"]))
++ def _check_json_output(cls, json_obj):
++ if json_obj["output"] != "ok":
++ raise dnf.exceptions.Error("{}".format(json_obj["error"]))
+
+
+ class Playground(dnf.Plugin):
+@@ -294,7 +300,7 @@ Do you want to continue? [y/N]: """)
+ raise dnf.cli.CliError(_("Unknown response from server."))
+ for repo in output["repos"]:
+ project_name = "{0}/{1}".format(repo["username"],
+- repo["coprname"])
++ repo["coprname"])
+ repo_filename = "/etc/yum.repos.d/_playground_{}.repo" \
+ .format(project_name.replace("/", "-"))
+ try:
+@@ -304,7 +310,8 @@ Do you want to continue? [y/N]: """)
+ self.copr_url, project_name, chroot)
+ req = requests.get(api_url)
+ output2 = self._get_data(req)
+- if output2 and ("output" in output2) and (output2["output"] == "ok"):
++ if (output2 and ("output" in output2)
++ and (output2["output"] == "ok")):
+ self._download_repo(project_name, repo_filename, chroot)
+ except dnf.exceptions.Error:
+ # likely 404 and that repo does not exist
+diff --git a/plugins/debuginfo-install.py b/plugins/debuginfo-install.py
+index 194b24c..4783ed2 100644
+--- a/plugins/debuginfo-install.py
++++ b/plugins/debuginfo-install.py
+@@ -23,6 +23,7 @@ from dnfpluginscore import _, logger
+
+ import dnf
+ import dnf.cli
++import dnf.subject
+
+
+ class DebuginfoInstall(dnf.Plugin):
+@@ -44,8 +45,8 @@ class DebuginfoInstallCommand(dnf.cli.Command):
+ summary = _('install debuginfo packages')
+ usage = "[PACKAGE...]"
+
+- done = []
+- rejected = []
++ srcdone = []
++ reqdone = []
+ packages = None
+ packages_available = None
+ packages_installed = None
+@@ -62,12 +63,11 @@ class DebuginfoInstallCommand(dnf.cli.Command):
+ self.packages = self.base.sack.query()
+ self.packages_available = self.packages.available()
+ self.packages_installed = self.packages.installed()
+- for pkg in args:
+- pkgs = self.packages_installed.filter(name=pkg)
+- if not pkgs:
+- pkgs = self.packages_available.filter(name=pkg)
+- for pkg in pkgs:
+- self._di_install(pkg, None)
++
++ for pkgspec in args:
++ for pkg in dnf.subject.Subject(pkgspec).get_best_query(
++ self.cli.base.sack):
++ self._di_install(pkg)
+
+ @staticmethod
+ def _pkgname_src(package):
+@@ -84,86 +84,53 @@ class DebuginfoInstallCommand(dnf.cli.Command):
+ assert "-debuginfo" not in srcname
+ return "{}-debuginfo".format(srcname)
+
+- def _is_available(self, package, match_evra):
++ def _dbg_available(self, package, match_evra):
+ dbgname = self._pkgname_dbg(package)
+ if match_evra:
+- avail = self.packages_available.filter(
++ return self.packages_available.filter(
+ name="{}".format(dbgname),
+ epoch=int(package.epoch),
+ version=str(package.version),
+ release=str(package.release),
+ arch=str(package.arch))
+ else:
+- avail = self.packages_available.filter(
++ return self.packages_available.filter(
+ name="{}".format(dbgname),
+ arch=str(package.arch))
+- if len(avail) != 0:
+- srcname = self._pkgname_src(package)
+- if match_evra:
+- return self.packages_available.filter(
+- name="{}".format(srcname),
+- epoch=int(package.epoch),
+- version=str(package.version),
+- release=str(package.release),
+- arch=str(package.arch))
+- else:
+- return self.packages_available.filter(
+- name="{}".format(srcname),
+- arch=str(package.arch))
+- else:
+- return False
+
+- def _di_install(self, package, require):
++ def _di_install(self, package):
+ srcname = self._pkgname_src(package)
+ dbgname = self._pkgname_dbg(package)
+- if srcname in self.done \
+- or require in self.done \
+- or package in self.rejected:
+- return
+- if self._is_available(package, True):
+- self.done.append(srcname)
+- if require:
+- self.done.append(require)
+- di = "{0}-{1}:{2}-{3}.{4}".format(
+- dbgname,
+- package.epoch,
+- package.version,
+- package.release,
+- package.arch)
+- self.base.install(di)
+- else:
+- if self._is_available(package, False):
++ if not srcname in self.srcdone:
++ if self._dbg_available(package, True):
++ di = "{0}-{1}:{2}-{3}.{4}".format(
++ dbgname,
++ package.epoch,
++ package.version,
++ package.release,
++ package.arch)
++ self.base.install(di)
++ elif self._dbg_available(package, False):
+ di = "{0}.{1}".format(dbgname, package.arch)
+ self.base.install(di)
+- self.done.append(srcname)
+- if require:
+- self.done.append(require)
+- else:
+- pass
++ self.srcdone.append(srcname)
++
++ if package.name in self.reqdone:
++ return
++ self.reqdone.append(package.name)
+ for req in package.requires:
+ if str(req).startswith("rpmlib("):
+ continue
+- elif str(req) in self.done:
++ elif str(req) in self.reqdone:
+ continue
+ elif str(req).find(".so") != -1:
+ provides = self.packages_available.filter(provides=req)
+ for p in provides:
+- if str(p.name) in self.done or p in self.rejected:
++ if p.name in self.reqdone:
+ continue
+ pkgs = self.packages_installed.filter(name=p.name)
+- if len(pkgs) != 0:
+- pkgs_avail = self._is_available(pkgs[0], True)
+- if not pkgs_avail:
+- for x in pkgs:
+- logger.debug(
+-_("Can't find debuginfo package for: {0}-{1}:{2}-{3}.{4}").format(
+- x.name, x.epoch, x.version, x.release, x.arch))
+- self.rejected.append(x)
+- pkgs = []
+- else:
+- pkgs = pkgs_avail
+- for pkg in pkgs:
+- self._di_install(pkg, str(req))
++ for dep in pkgs:
++ self._di_install(dep)
+
+ def _enable_debug_repos(self):
+ repos = {}
+diff --git a/plugins/dnfpluginscore/lib.py b/plugins/dnfpluginscore/lib.py
+new file mode 100644
+index 0000000..144d126
+--- /dev/null
++++ b/plugins/dnfpluginscore/lib.py
+@@ -0,0 +1,121 @@
++#
++# Copyright (C) 2015 Red Hat, Inc.
++#
++# This copyrighted material is made available to anyone wishing to use,
++# modify, copy, or redistribute it subject to the terms and conditions of
++# the GNU General Public License v.2, or (at your option) any later version.
++# This program is distributed in the hope that it will be useful, but WITHOUT
++# ANY WARRANTY expressed or implied, including the implied warranties of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
++# Public License for more details. You should have received a copy of the
++# GNU General Public License along with this program; if not, write to the
++# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
++# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
++# source code or documentation are not subject to the GNU General Public
++# License and may only be used or replicated with the express permission of
++# Red Hat, Inc.
++#
++
++from dnf.pycomp import PY3
++
++import dnf
++import iniparse
++import librepo
++import tempfile
++
++
++def current_value(plugin, repo, option):
++ """
++ Returns current value of the option
++ (set in .repo or dnf.conf or on commandline).
++ """
++ if (repo is not None and
++ hasattr(repo, option) and getattr(repo, option) is not None):
++ return getattr(repo, option)
++ conf = plugin.base.conf
++ if (hasattr(conf, option) and getattr(conf, option) is not None):
++ return getattr(conf, option)
++ return None
++
++
++def urlopen(plugin, repo, url, mode='w+b', **kwargs):
++ """ modified dnf.util.urlopen() which respects proxy setting
++ even for non-repo downloads
++ """
++ conf = plugin.base.conf
++
++ def non_repo_handle():
++ handle = librepo.Handle()
++ handle.useragent = dnf.const.USER_AGENT
++ # see dnf.repo.Repo._handle_new_remote() how to pass
++ handle.maxspeed = conf.throttle if type(conf.throttle) is int \
++ else int(conf.bandwidth * conf.throttle)
++ handle.proxy = conf.proxy
++ handle.proxyuserpwd = dnf.repo._user_pass_str(conf.proxy_username,
++ conf.proxy_password)
++ handle.sslverifypeer = handle.sslverifyhost = conf.sslverify
++ return handle
++
++ if PY3 and 'b' not in mode:
++ kwargs.setdefault('encoding', 'utf-8')
++ fo = tempfile.NamedTemporaryFile(mode, **kwargs)
++ if repo:
++ handle = repo.get_handle()
++ else:
++ handle = non_repo_handle()
++ try:
++ librepo.download_url(url, fo.fileno(), handle)
++ except librepo.LibrepoException as e:
++ raise IOError(e.args[1])
++ fo.seek(0)
++ return fo
++
++
++def write_raw_configfile(filename, section_id, substitutions,
++ cfgoptions, items, optionobj,
++ modify=None):
++ """
++ Code adopted from yum-config-manager writeRawRepoFile().
++ filename - name of config file (.conf or .repo)
++ section_id - id of modified section (e.g. main, fedora, updates)
++ substitutions - instance of base.conf.substitutions
++ cfgoptions - options parsed from conf file (e.g. base.conf.cfg.options)
++ items - current global or repo settings (e.g. base.conf.iteritems)
++ optionobj - option parse object (e.g. base.conf.optionobj)
++ modify - list of modified options
++ """
++ ini = iniparse.INIConfig(open(filename))
++
++ osection_id = section_id
++ # b/c repoids can have $values in them we need to map both ways to figure
++ # out which one is which
++ if section_id not in ini:
++ for sect in ini:
++ if dnf.conf.parser.substitute(sect, substitutions) == section_id:
++ section_id = sect
++
++ # Updated the ConfigParser with the changed values
++ cfgopts = cfgoptions(osection_id)
++ for name, value in items():
++ if value is None: # Proxy
++ continue
++
++ if modify is not None and name not in modify:
++ continue
++
++ option = optionobj(name)
++ ovalue = option.tostring(value)
++ # If the value is the same, but just interpreted ... when we don't want
++ # to keep the interpreted values.
++ if (name in ini[section_id] and
++ ovalue == dnf.conf.parser.substitute(ini[section_id][name],
++ substitutions)):
++ ovalue = ini[section_id][name]
++
++ if name not in cfgopts and option.default == value:
++ continue
++
++ ini[section_id][name] = ovalue
++ fp = open(filename, "w")
++ fp.write(str(ini))
++ fp.close()
+diff --git a/plugins/download.py b/plugins/download.py
+index cbb6e4e..7e8bf41 100644
+--- a/plugins/download.py
++++ b/plugins/download.py
+@@ -1,6 +1,6 @@
+ # download.py, supplies the 'download' command.
+ #
+-# Copyright (C) 2013-2014 Red Hat, Inc.
++# Copyright (C) 2013-2015 Red Hat, Inc.
+ #
+ # This copyrighted material is made available to anyone wishing to use,
+ # modify, copy, or redistribute it subject to the terms and conditions of
+@@ -27,7 +27,6 @@ import dnf.exceptions
+ import dnf.i18n
+ import dnf.subject
+ import dnfpluginscore
+-import functools
+ import hawkey
+ import itertools
+ import os
+@@ -39,6 +38,7 @@ class Download(dnf.Plugin):
+ name = 'download'
+
+ def __init__(self, base, cli):
++ super(Download, self).__init__(base, cli)
+ self.base = base
+ self.cli = cli
+ if self.cli is not None:
+@@ -51,6 +51,11 @@ class DownloadCommand(dnf.cli.Command):
+ summary = _('Download package to current directory')
+ usage = _('PACKAGE...')
+
++ def __init__(self, cli):
++ super(DownloadCommand, self).__init__(cli)
++ self.opts = None
++ self.parser = None
++
+ def configure(self, args):
+ # setup sack and populate it with enabled repos
+ demands = self.cli.demands
+@@ -64,13 +69,15 @@ class DownloadCommand(dnf.cli.Command):
+ # You must only add options not used by dnf already
+ self.parser = dnfpluginscore.ArgumentParser(self.aliases[0])
+ self.parser.add_argument('packages', nargs='+',
+- help=_('packages to download'))
++ help=_('packages to download'))
+ self.parser.add_argument("--source", action='store_true',
+- help=_('download the src.rpm instead'))
+- self.parser.add_argument('--destdir',
+- help=_('download path, default is current dir'))
+- self.parser.add_argument('--resolve', action='store_true',
+- help=_('resolve and download needed dependencies'))
++ help=_('download the src.rpm instead'))
++ self.parser.add_argument(
++ '--destdir',
++ help=_('download path, default is current dir'))
++ self.parser.add_argument(
++ '--resolve', action='store_true',
++ help=_('resolve and download needed dependencies'))
+
+ # parse the options/args
+ # list available options/args on errors & exit
+@@ -91,8 +98,7 @@ class DownloadCommand(dnf.cli.Command):
+ else:
+ dest = dnf.i18n.ucd(os.getcwd())
+
+- move = functools.partial(self._move_package, dest)
+- map(move, locations)
++ self._move_packages(dest, locations)
+
+ def _download_rpms(self, pkg_specs):
+ """Download packages to dnf cache."""
+@@ -137,7 +143,8 @@ class DownloadCommand(dnf.cli.Command):
+ logger.debug(_('Error in resolve'))
+ return []
+
+- def _get_source_packages(self, pkgs):
++ @staticmethod
++ def _get_source_packages(pkgs):
+ """Get list of source rpm names for a list of packages."""
+ source_pkgs = set()
+ for pkg in pkgs:
+@@ -145,31 +152,27 @@ class DownloadCommand(dnf.cli.Command):
+ source_pkgs.add(pkg.sourcerpm)
+ logger.debug(' --> Package : %s Source : %s',
+ str(pkg), pkg.sourcerpm)
++ elif pkg.arch == 'src':
++ source_pkgs.add("%s-%s.src.rpm" % (pkg.name, pkg.evr))
+ else:
+- logger.info(_("No source rpm definded for %s"), str(pkg))
++ logger.info(_("No source rpm defined for %s"), str(pkg))
+ return list(source_pkgs)
+
+ def _enable_source_repos(self):
+ """Enable source repositories for enabled binary repositories.
+
+- binary repositories will be disabled and the dnf sack will be reloaded
++ Don't disable the binary ones because they can contain SRPMs as well
++ (this applies to COPR and to user-managed repos).
++ The dnf sack will be reloaded.
+ """
+- repo_dict = {}
+- # find the source repos for the enabled binary repos
++ # enable the source repos
+ for repo in self.base.repos.iter_enabled():
+- source_repo = '%s-source' % repo.id
+- if source_repo in self.base.repos:
+- repo_dict[repo.id] = (repo, self.base.repos[source_repo])
+- else:
+- repo_dict[repo.id] = (repo, None)
+- # disable the binary & enable the source ones
+- for id_ in repo_dict:
+- repo, src_repo = repo_dict[id_]
+- repo.disable()
+- if src_repo:
+- logger.info(_('enabled %s repository') % src_repo.id)
+- src_repo.enable()
+- # reload the sack
++ source_repo_id = '%s-source' % repo.id
++ if source_repo_id in self.base.repos:
++ source_repo = self.base.repos[source_repo_id]
++ logger.info(_('enabled %s repository'), source_repo.id)
++ source_repo.enable()
++ # reload the sack
+ self.base.fill_sack()
+
+ def _get_query(self, pkg_spec):
+@@ -191,8 +194,12 @@ class DownloadCommand(dnf.cli.Command):
+ release=nevra.release, arch=nevra.arch)
+ return q
+
+- def _move_package(self, target, location):
++ @staticmethod
++ def _move_packages(target, locations):
+ """Move the downloaded package to target."""
+- shutil.copy(location, target)
+- os.unlink(location)
++ if not os.path.exists(target):
++ os.makedirs(target)
++ for pkg in locations:
++ shutil.copy(pkg, target)
++ os.unlink(pkg)
+ return target
+diff --git a/plugins/generate_completion_cache.py b/plugins/generate_completion_cache.py
+index 7fbb47a..b9df242 100644
+--- a/plugins/generate_completion_cache.py
++++ b/plugins/generate_completion_cache.py
+@@ -2,6 +2,7 @@
+ # generate_completion_cache.py - generate cache for dnf bash completion
+ # Copyright © 2013 Elad Alfassa <elad at fedoraproject.org>
+ # Copyright (C) 2014 Igor Gnatenko <i.gnatenko.brain at gmail.com>
++# Copyright (C) 2015 Red Hat, Inc.
+
+ # This copyrighted material is made available to anyone wishing to use,
+ # modify, copy, or redistribute it subject to the terms and conditions of
+@@ -28,6 +29,7 @@ class BashCompletionCache(dnf.Plugin):
+ name = 'generate_completion_cache'
+
+ def __init__(self, base, cli):
++ super(BashCompletionCache, self).__init__(base, cli)
+ self.base = base
+ self.cache_file = "/var/cache/dnf/packages.db"
+
+@@ -60,7 +62,7 @@ class BashCompletionCache(dnf.Plugin):
+ cur.execute("delete from available")
+ avail_pkgs = self.base.sack.query().available()
+ avail_pkgs_insert = [["{}.{}".format(x.name, x.arch)]
+- for x in avail_pkgs if x.arch != "src"]
++ for x in avail_pkgs if x.arch != "src"]
+ cur.executemany("insert or ignore into available values (?)",
+ avail_pkgs_insert)
+ conn.commit()
+@@ -80,7 +82,7 @@ class BashCompletionCache(dnf.Plugin):
+ cur.execute("delete from installed")
+ inst_pkgs = self.base.sack.query().installed()
+ inst_pkgs_insert = [["{}.{}".format(x.name, x.arch)]
+- for x in inst_pkgs if x.arch != "src"]
++ for x in inst_pkgs if x.arch != "src"]
+ cur.executemany("insert or ignore into installed values (?)",
+ inst_pkgs_insert)
+ conn.commit()
+diff --git a/plugins/ghost.py b/plugins/ghost.py
+index 1cff03c..ac60780 100644
+--- a/plugins/ghost.py
++++ b/plugins/ghost.py
+@@ -1,6 +1,6 @@
+ # ghost.py, it's a show about nothing.
+ #
+-# Copyright (C) 2013 Red Hat, Inc.
++# Copyright (C) 2013-2015 Red Hat, Inc.
+ #
+ # This copyrighted material is made available to anyone wishing to use,
+ # modify, copy, or redistribute it subject to the terms and conditions of
+@@ -29,6 +29,7 @@ class Ghost(dnf.Plugin):
+ name = 'ghost'
+
+ def __init__(self, base, cli):
++ super(Ghost, self).__init__(base, cli)
+ self.base = base
+ self.cli = cli
+ if cli is None:
+@@ -36,7 +37,8 @@ class Ghost(dnf.Plugin):
+ else:
+ self._out('loaded (with CLI)')
+
+- def _out(self, msg):
++ @staticmethod
++ def _out(msg):
+ logger.debug('Ghost plugin: %s', msg)
+
+ def config(self):
+diff --git a/plugins/noroot.py b/plugins/noroot.py
+index 014b226..f82b6a3 100644
+--- a/plugins/noroot.py
++++ b/plugins/noroot.py
+@@ -1,6 +1,6 @@
+ # noroot.py
+ #
+-# Copyright (C) 2013 Red Hat, Inc.
++# Copyright (C) 2013-2015 Red Hat, Inc.
+ #
+ # This copyrighted material is made available to anyone wishing to use,
+ # modify, copy, or redistribute it subject to the terms and conditions of
+@@ -19,7 +19,7 @@
+
+ from __future__ import absolute_import
+ from __future__ import unicode_literals
+-from dnfpluginscore import logger, _
++from dnfpluginscore import _
+
+ import dnf
+ import dnf.exceptions
+@@ -33,6 +33,7 @@ class Noroot(dnf.Plugin):
+ name = 'noroot'
+
+ def __init__(self, base, cli):
++ super(Noroot, self).__init__(base, cli)
+ self.base = base
+ self.cli = cli
+
+diff --git a/plugins/protected_packages.py b/plugins/protected_packages.py
+index b202011..a241eae 100644
+--- a/plugins/protected_packages.py
++++ b/plugins/protected_packages.py
+@@ -1,7 +1,7 @@
+ # protected_packages.py
+ # Prevent package removals that could leave the system broken.
+ #
+-# Copyright (C) 2014 Red Hat, Inc.
++# Copyright (C) 2014-2015 Red Hat, Inc.
+ #
+ # This copyrighted material is made available to anyone wishing to use,
+ # modify, copy, or redistribute it subject to the terms and conditions of
+@@ -20,7 +20,7 @@
+
+ from __future__ import absolute_import
+ from __future__ import unicode_literals
+-from dnfpluginscore import _, logger
++from dnfpluginscore import _
+
+ import dnf
+ import dnf.exceptions
+diff --git a/plugins/repoquery.py b/plugins/repoquery.py
+index c4ebccc..ddce24c 100644
+--- a/plugins/repoquery.py
++++ b/plugins/repoquery.py
+@@ -24,6 +24,7 @@ from dnfpluginscore import _
+ import dnf
+ import dnf.cli
+ import dnf.exceptions
++import dnf.subject
+ import dnfpluginscore
+ import functools
+ import hawkey
+@@ -62,6 +63,8 @@ def build_format_fn(opts):
+ return info_format
+ elif opts.queryfilelist:
+ return filelist_format
++ elif opts.querysourcerpm:
++ return sourcerpm_format
+ else:
+ return rpm2py_format(opts.queryformat).format
+
+@@ -72,6 +75,9 @@ def info_format(pkg):
+ def filelist_format(pkg):
+ return "\n".join(pkg.files)
+
++def sourcerpm_format(pkg):
++ return pkg.sourcerpm
++
+ def parse_arguments(args):
+ # Setup ArgumentParser to handle util
+ parser = dnfpluginscore.ArgumentParser(RepoQueryCommand.aliases[0])
+@@ -81,6 +87,8 @@ def parse_arguments(args):
+ help=_('show only results from this REPO'))
+ parser.add_argument('--arch', metavar='ARCH',
+ help=_('show only results from this ARCH'))
++ parser.add_argument('-f', '--file', metavar='FILE',
++ help=_('show only results that owns FILE'))
+ parser.add_argument('--whatprovides', metavar='REQ',
+ help=_('show only results there provides REQ'))
+ parser.add_argument('--whatrequires', metavar='REQ',
+@@ -96,6 +104,9 @@ def parse_arguments(args):
+ outform.add_argument('-l', "--list", dest='queryfilelist',
+ default=False, action='store_true',
+ help=_('show list of files in the package'))
++ outform.add_argument('-s', "--source", dest='querysourcerpm',
++ default=False, action='store_true',
++ help=_('show package source RPM name'))
+ outform.add_argument('--qf', "--queryformat", dest='queryformat',
+ default=QFORMAT_DEFAULT,
+ help=_('format for displaying found packages'))
+@@ -193,17 +204,19 @@ class RepoQueryCommand(dnf.cli.Command):
+ print(QUERY_TAGS)
+ return
+
+- q = self.base.sack.query().available()
+ if opts.key:
+- if set(opts.key) & set('*[?'): # is pattern ?
+- fdict = {'name__glob': opts.key}
+- else: # substring
+- fdict = {'name': opts.key}
+- q = q.filter(hawkey.ICASE, **fdict)
++ q = dnf.subject.Subject(opts.key, ignore_case=True).get_best_query(
++ self.base.sack, with_provides=False)
++ else:
++ q = self.base.sack.query()
++ # do not show packages from @System repo
++ q = q.available()
+ if opts.repoid:
+ q = q.filter(reponame=opts.repoid)
+ if opts.arch:
+ q = q.filter(arch=opts.arch)
++ if opts.file:
++ q = q.filter(file=opts.file)
+ if opts.whatprovides:
+ q = self.by_provides(self.base.sack, [opts.whatprovides], q)
+ if opts.whatrequires:
+diff --git a/rel-eng/README b/rel-eng/README
+new file mode 100644
+index 0000000..c103bdf
+--- /dev/null
++++ b/rel-eng/README
+@@ -0,0 +1,7 @@
++Release instructions:
++
++1. Tag: tito tag
++2. Test: tito build --rpm --offline
++3. Push: git push && git push $ORIGIN $TAG
++4. Release: tito release fedora-git
++
+diff --git a/rel-eng/packages/.readme b/rel-eng/packages/.readme
+new file mode 100644
+index 0000000..8999c8d
+--- /dev/null
++++ b/rel-eng/packages/.readme
+@@ -0,0 +1,3 @@
++the rel-eng/packages directory contains metadata files
++named after their packages. Each file has the latest tagged
++version and the project's relative directory.
+diff --git a/rel-eng/packages/dnf-plugins-core b/rel-eng/packages/dnf-plugins-core
+new file mode 100644
+index 0000000..d7b9e19
+--- /dev/null
++++ b/rel-eng/packages/dnf-plugins-core
+@@ -0,0 +1 @@
++0.1.5-2 ./
+diff --git a/rel-eng/releasers.conf b/rel-eng/releasers.conf
+new file mode 100644
+index 0000000..ffeb709
+--- /dev/null
++++ b/rel-eng/releasers.conf
+@@ -0,0 +1,3 @@
++[fedora-git]
++releaser = tito.release.FedoraGitReleaser
++branches = f21
+diff --git a/rel-eng/tito.props b/rel-eng/tito.props
+new file mode 100644
+index 0000000..c008eb3
+--- /dev/null
++++ b/rel-eng/tito.props
+@@ -0,0 +1,5 @@
++[buildconfig]
++builder = tito.builder.Builder
++tagger = tito.tagger.ReleaseTagger
++changelog_do_not_remove_cherrypick = 1
++changelog_format = %s (%a)
+diff --git a/scripts/lint b/scripts/lint
+index 8b4f630..5423164 100755
+--- a/scripts/lint
++++ b/scripts/lint
+@@ -21,8 +21,9 @@ disable "-d W0141" # used builtin 'map' function
+ disable "-d W0142" # used star magic
+
+ VAR_NAMES=--variable-rgx='[a-z_][a-z0-9_]*$'
++DUMMY_NAMES='--dummy-variables-rgx=_.*'
+ MISC=--max-line-length=82
+
+-pylint --rcfile=/dev/null --reports=n $DISABLED "$VAR_NAMES" $MISC $* \
++pylint --rcfile=/dev/null --reports=n $DISABLED "$VAR_NAMES" "$DUMMY_NAMES" $MISC $* \
+ "$TEMPLATE" \
+ | egrep -v -f $FALSE_POSITIVES
+diff --git a/tests/README b/tests/README
+new file mode 100644
+index 0000000..5672629
+--- /dev/null
++++ b/tests/README
+@@ -0,0 +1,8 @@
++To run tests from the source tree, run this
++(working directory = root of the source tree):
++
++export PYTHONPATH=./plugins
++nosetests tests/
++
++You can run tests under specific Python version using nosetests-2.7
++or nosetests-3.4.
+diff --git a/tests/test_config_manager.py b/tests/test_config_manager.py
+new file mode 100644
+index 0000000..64c581d
+--- /dev/null
++++ b/tests/test_config_manager.py
+@@ -0,0 +1,121 @@
++# Copyright (C) 2015 Red Hat, Inc.
++#
++# This copyrighted material is made available to anyone wishing to use,
++# modify, copy, or redistribute it subject to the terms and conditions of
++# the GNU General Public License v.2, or (at your option) any later version.
++# This program is distributed in the hope that it will be useful, but WITHOUT
++# ANY WARRANTY expressed or implied, including the implied warranties of
++# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
++# Public License for more details. You should have received a copy of the
++# GNU General Public License along with this program; if not, write to the
++# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
++# 02110-1301, USA. Any Red Hat trademarks that are incorporated in the
++# source code or documentation are not subject to the GNU General Public
++# License and may only be used or replicated with the express permission of
++# Red Hat, Inc.
++#
++
++from __future__ import absolute_import
++from __future__ import unicode_literals
++from tests.support import mock, RepoStub
++
++import config_manager
++import dnf
++import filecmp
++import iniparse
++import os
++import shutil
++import tempfile
++import unittest
++
++
++REPOLABEL = "testrepo"
++REPOCONTENT = """[testrepo]
++name=TestRepo
++baseurl=file:///tmp
++enabled=1
++"""
++
++class ConfigManagerBase(mock.MagicMock):
++ conf = dnf.conf.Conf()
++
++class ConfigManagerCommandTest(unittest.TestCase):
++
++ def setUp(self):
++ cli = dnf.cli.cli.Cli(ConfigManagerBase())
++ self.cmd = config_manager.ConfigManagerCommand(cli)
++ self.cmd.base.conf.reposdir = [tempfile.mkdtemp()]
++
++ self.addCleanup(shutil.rmtree, self.cmd.base.conf.reposdir[0])
++
++ def test_add_from_repofile(self):
++ tempfile_kwargs = {'mode': 'w', 'suffix': '.repo', 'delete': False}
++ if dnf.pycomp.PY3:
++ tempfile_kwargs['encoding'] = 'utf8'
++
++ repofile = tempfile.NamedTemporaryFile(**tempfile_kwargs)
++ dnf.pycomp.write_to_file(repofile, REPOCONTENT)
++ repofile.close()
++
++ args = ['--add-repo', repofile.name]
++ self.cmd.configure(args)
++ self.cmd.run(args)
++
++ installed_repofile = os.path.join(self.cmd.base.conf.reposdir[0],
++ os.path.basename(repofile.name))
++ with open(installed_repofile) as f:
++ added = f.read()
++
++ self.assertMultiLineEqual(REPOCONTENT, added)
++
++ def get_matching(x):
++ repo = dnf.repo.Repo(x, '/tmp')
++ repo.repofile = installed_repofile
++ repo.cfg = iniparse.compat.RawConfigParser()
++ repo.cfg.read(installed_repofile)
++ return [repo]
++ self.cmd.base.repos.get_matching = get_matching
++ self.cmd.base.output = dnf.cli.output.Output(self.cmd.base, self.cmd.base.conf)
++
++ self.subtest_disable(REPOLABEL, installed_repofile)
++ self.subtest_enable(REPOLABEL, installed_repofile)
++
++ os.unlink(repofile.name)
++
++ def test_add_from_repourl(self):
++ long_url = 'file:///tmp/%s' % ('/'.join([str(x) for x in range(1,100)]))
++ name = 'tmp_1_2_3_4_5_6_7_8_9_10_11_12_13_14_15_16_17_18_19_20_21' \
++ + '_22_23_24_25_26_27_28_29_30_31_32_33_34_35_36_37_38_39' \
++ + '_40_41_42_43_44_45_46_47_48_49_50_51_52_53_54_55_56_57' \
++ + '_58_59_60_61_62_63__b3085fd1c13941e151ce4afe9d8670774d' \
++ + 'c8e19395f2a785bc1d210eccc0869b'
++ repofile = name + '.repo'
++
++ repocontent = "[%s]\nname=created by dnf config-manager from %s\n" \
++ "baseurl=%s\nenabled=1\n" % (name, long_url, long_url)
++ args = ['--add-repo', long_url]
++ self.cmd.configure(args)
++ self.cmd.run(args)
++ with open(os.path.join(self.cmd.base.conf.reposdir[0], repofile)) as f:
++ added = f.read()
++
++ self.assertMultiLineEqual(repocontent, added)
++
++ def subtest_disable(self, label, fname):
++ args = ['--set-disabled', label]
++ self.cmd.configure(args)
++ self.cmd.run(args)
++
++ with open(fname) as f:
++ added = f.read()
++ disabled = REPOCONTENT.replace("enabled=1", "enabled=0")
++ self.assertMultiLineEqual(disabled, added)
++
++ def subtest_enable(self, label, fname):
++ args = ['--set-enabled', label]
++ self.cmd.configure(args)
++ self.cmd.run(args)
++
++ with open(fname) as f:
++ added = f.read()
++ self.assertMultiLineEqual(REPOCONTENT, added)
+diff --git a/tests/test_download.py b/tests/test_download.py
+index 4158171..7bee1b6 100644
+--- a/tests/test_download.py
++++ b/tests/test_download.py
+@@ -170,8 +170,8 @@ class DownloadlCommandTest(unittest.TestCase):
+ self.assertFalse(repos['foobar-source'].enabled)
+ self.cmd._enable_source_repos()
+ self.assertTrue(repos['foo-source'].enabled)
+- self.assertFalse(repos['foo'].enabled)
+- self.assertFalse(repos['bar'].enabled)
++ self.assertTrue(repos['foo'].enabled)
++ self.assertTrue(repos['bar'].enabled)
+ self.assertFalse(repos['foobar-source'].enabled)
+
+ def test_get_source_packages(self):
+diff --git a/tests/test_repoquery.py b/tests/test_repoquery.py
+index 771a583..bf32857 100644
+--- a/tests/test_repoquery.py
++++ b/tests/test_repoquery.py
+@@ -46,6 +46,8 @@ EXPECTED_FILELIST_FORMAT = """\
+ /var/foobar\
+ """
+
++EXPECTED_SOURCERPM_FORMAT = """\
++foo-1.0.1-1.f20.src.rpm"""
+
+ class PkgStub(object):
+ def __init__(self):
+@@ -81,6 +83,9 @@ class ArgParseTest(unittest.TestCase):
+ opts, _ = repoquery.parse_arguments(['--provides'])
+ self.assertEqual(opts.queryformat, '%{provides}')
+
++ def test_file(self):
++ opts, _ = repoquery.parse_arguments(['/var/foobar'])
++ self.assertIsNone(opts.file)
+
+ class InfoFormatTest(unittest.TestCase):
+ def test_info(self):
+@@ -94,6 +99,11 @@ class FilelistFormatTest(unittest.TestCase):
+ self.assertEqual(repoquery.filelist_format(pkg),
+ EXPECTED_FILELIST_FORMAT)
+
++class SourceRPMFormatTest(unittest.TestCase):
++ def test_info(self):
++ pkg = repoquery.PackageWrapper(PkgStub())
++ self.assertEqual(repoquery.sourcerpm_format(pkg),
++ EXPECTED_SOURCERPM_FORMAT)
+
+ class OutputTest(unittest.TestCase):
+ def test_output(self):
diff --git a/dnf-plugins-core.spec b/dnf-plugins-core.spec
index 6e40e07..69ae81a 100644
--- a/dnf-plugins-core.spec
+++ b/dnf-plugins-core.spec
@@ -1,32 +1,32 @@
-%{!?gitrev: %global gitrev 351e094}
-%{?!dnf_version: %global dnf_version 0.6.3}
+%{?!dnf_version: %global dnf_version 0.6.4}
Name: dnf-plugins-core
Version: 0.1.5
-Release: 1%{?dist}
+Release: 2%{?dist}
Summary: Core Plugins for DNF
Group: System Environment/Base
License: GPLv2+
URL: https://github.com/rpm-software-management/dnf-plugins-core
# source archive is created by running package/archive from a git checkout
-Source0: dnf-plugins-core-%{gitrev}.tar.xz
+Source0: dnf-plugins-core-%{version}.tar.gz
+Patch0: dnf-plugins-core-0.1.5-1-to-dnf-plugins-core-0.1.5-2.patch
BuildArch: noarch
BuildRequires: cmake
-BuildRequires: dnf >= %{dnf_version}
+BuildRequires: dnf = %{dnf_version}
BuildRequires: gettext
BuildRequires: pykickstart
BuildRequires: python-nose
BuildRequires: python-sphinx
BuildRequires: python2-devel
-Requires: dnf >= %{dnf_version}
+Requires: dnf = %{dnf_version}
Requires: pykickstart
Requires: python-requests
%description
-Core Plugins for DNF. This package enhance DNF with builddep, copr,
-debuginfo-install, download, kickstart, needs-restarting, repoquery and
+Core Plugins for DNF. This package enhance DNF with builddep, config-manager,
+copr, debuginfo-install, download, kickstart, needs-restarting, repoquery and
reposync commands. Additionally provides generate_completion_cache, noroot and
protected_packages passive plugins.
@@ -34,19 +34,20 @@ protected_packages passive plugins.
Summary: Core Plugins for DNF
Group: System Environment/Base
BuildRequires: python3-devel
-BuildRequires: python3-dnf >= %{dnf_version}
+BuildRequires: python3-dnf = %{dnf_version}
BuildRequires: python3-nose
BuildRequires: python3-sphinx
-Requires: python3-dnf >= %{dnf_version}
+Requires: python3-dnf = %{dnf_version}
%description -n python3-dnf-plugins-core
-Core Plugins for DNF, Python 3 version. This package enhance DNF with builddep, copr,
-debuginfo-install, download, kickstart, needs-restarting, repoquery and
-reposync commands. Additionally provides generate_completion_cache, noroot and
-protected_packages passive plugins.
+Core Plugins for DNF, Python 3 version. This package enhance DNF with builddep,
+config-manager, copr, debuginfo-install, download, kickstart, needs-restarting,
+repoquery and reposync commands. Additionally provides generate_completion_cache,
+noroot and protected_packages passive plugins.
%prep
-%setup -q -n dnf-plugins-core
+%setup -q -n dnf-plugins-core-%{version}
+%patch0 -p1
rm -rf py3
mkdir ../py3
cp -a . ../py3/
@@ -92,6 +93,47 @@ PYTHONPATH=./plugins /usr/bin/nosetests-3.* -s tests/
%{_mandir}/man8/dnf.plugin.*
%changelog
+* Mon Apr 13 2015 Michal Luscon <mluscon at redhat.com> 0.1.5-2
+- prepare repo for tito build system (Michal Luscon)
+- migrate raw_input() to Python3 (RhBug:1208399) (Miroslav Suchý)
+- create --destdir if not exist (Michael Mraka)
+- repoquery: Added -s/--source switch, test case and documentation for querying source rpm name (Parag Nemade)
+- repoquery: Added documentation and test case for file switch (Parag Nemade)
+- debuginfo-install: support cases where src.rpm name != binary package name (Petr Spacek)
+- use dnfpluginscore.lib.urlopen() (RhBug:1193047) (Miroslav Suchý)
+- implemented functionality of yum-config-manager (Michael Mraka)
+- repoquery: Added --file switch to show who owns the given file (RhBug:1196952) (Parag Nemade)
+- debuginfo-install: accept packages names specified as NEVRA (RhBug:1171046) (Petr Spacek)
+- repoquery: accept package names specified as NEVRA (RhBug:1179366) (Petr Spacek)
+- download: fix typo in 'No source rpm definded' (Petr Spacek)
+- download: accept package names ending with .src too (Petr Spacek)
+- cosmetic: download: pylint fixes (Jan Silhan)
+- download: Do not disable user-enabled repos (thanks Spacekpe) (Jan Silhan)
+- let pylint ignore unused variables starting with _ (Michael Mraka)
+- updated copyright (Michael Mraka)
+- fixed pylint warning Redefining name from outer scope (Michael Mraka)
+- fixed pylint warning Invalid constant name (Michael Mraka)
+- fixed pylint warnings Line too long (Michael Mraka)
+- pylint fix for Wrong continued indentation (Michael Mraka)
+- updated copyright (Michael Mraka)
+- pylint fix for Specify string format arguments as logging function parameters (Michael Mraka)
+- pylint fix for Method could be a function (Michael Mraka)
+- pylint fix for __init__ method from base class is not called (Michael Mraka)
+- pylint fix for Attribute defined outside __init__ (Michael Mraka)
+- updated copyright (Michael Mraka)
+- pylint fix for __init__ method from base class is not called (Michael Mraka)
+- pylint fix for Wrong continued indentation (Michael Mraka)
+- updated copyright (Michael Mraka)
+- pylint fix for Method could be a function (Michael Mraka)
+- pylint fix for __init__ method from base class is not called (Michael Mraka)
+- updated copyright (Michael Mraka)
+- pylint fix for Unused import (Michael Mraka)
+- pylint fix for __init__ method from base class is not called (Michael Mraka)
+- updated copyright (Michael Mraka)
+- pylint fix for Unused import (Michael Mraka)
+- Add README to tests/ directory (Petr Spacek)
+- AUTHORS: updated (Jan Silhan)
+- download: fix package download on Python 3 (Petr Spacek)
* Thu Feb 5 2015 Jan Silhan <jsilhan at redhat.com> - 0.1.5-1
- updated package url (Michael Mraka)
@@ -287,4 +329,3 @@ PYTHONPATH=./plugins /usr/bin/nosetests-3.* -s tests/
* Fri Dec 20 2013 Aleš Kozumplík <ales at redhat.com> - 0.0.1-1
- The initial package version.
-
diff --git a/sources b/sources
index 4e7f7e7..b13fb9a 100644
--- a/sources
+++ b/sources
@@ -1 +1 @@
-0259d83520542c14ef2eb9476c740421 dnf-plugins-core-351e094.tar.xz
+16c3091fbb1958744b3eba0aa66f4c3f ./dnf-plugins-core-0.1.5.tar.gz
--
cgit v0.10.2
http://pkgs.fedoraproject.org/cgit/dnf-plugins-core.git/commit/?h=f21&id=f8822547d30496278afdb2eaa2adf7c41f6d8ef9
More information about the scm-commits
mailing list