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