From 118a378eb00bf83a0bb71c3380581fbf7ac48699 Mon Sep 17 00:00:00 2001 From: Ondřej Nosek Date: Sep 08 2020 23:38:46 +0000 Subject: New release 1.61 Signed-off-by: Ondřej Nosek --- diff --git a/.gitignore b/.gitignore index 0071ae2..504ced8 100644 --- a/.gitignore +++ b/.gitignore @@ -56,3 +56,4 @@ /rpkg-1.58.tar.gz /rpkg-1.59.tar.gz /rpkg-1.60.tar.gz +/rpkg-1.61.tar.gz diff --git a/0001-Do-not-use-pytest-related-dependencies-temporarily.patch b/0001-Do-not-use-pytest-related-dependencies-temporarily.patch new file mode 100644 index 0000000..aa12d44 --- /dev/null +++ b/0001-Do-not-use-pytest-related-dependencies-temporarily.patch @@ -0,0 +1,25 @@ +From a1127c74e6280b891028b0662316c8653511f0bd Mon Sep 17 00:00:00 2001 +From: Ondrej Nosek +Date: Wed, 9 Sep 2020 01:30:54 +0200 +Subject: [PATCH] Do not use pytest-related dependencies temporarily + +Signed-off-by: Ondrej Nosek +--- + setup.py | 1 - + 1 file changed, 1 deletion(-) + +diff --git a/setup.py b/setup.py +index f18ff4f..7681578 100755 +--- a/setup.py ++++ b/setup.py +@@ -59,7 +59,6 @@ setup( + license="GPLv2+", + url="https://pagure.io/rpkg", + packages=find_packages(), +- setup_requires=['setuptools_scm', 'pytest-runner'], + install_requires=install_requires, + extras_require={ + ':python_version=="2.6"': [ +-- +2.26.2 + diff --git a/0001-Repair-downloading-sources-into-external-directory.patch b/0001-Repair-downloading-sources-into-external-directory.patch deleted file mode 100644 index c1b1511..0000000 --- a/0001-Repair-downloading-sources-into-external-directory.patch +++ /dev/null @@ -1,31 +0,0 @@ -From ae1135dfbca05ddcd88bbcc962baf589dba143e1 Mon Sep 17 00:00:00 2001 -From: Ondrej Nosek -Date: Tue, 24 Mar 2020 01:23:53 +0100 -Subject: [PATCH] Repair downloading sources into external directory - -Signed-off-by: Ondrej Nosek ---- - pyrpkg/utils.py | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/pyrpkg/utils.py b/pyrpkg/utils.py -index e6339db..d1b79b9 100644 ---- a/pyrpkg/utils.py -+++ b/pyrpkg/utils.py -@@ -185,8 +185,11 @@ def is_file_tracked(file_path, repo_path): - # create a repo object from our path - try: - repo = git.Repo(repo_path) -- except (git.InvalidGitRepositoryError, git.NoSuchPathError): -- raise RuntimeError("%s is not a valid repo" % repo_path) -+ except git.InvalidGitRepositoryError: -+ # repo_path is not a valid repo - input file is not tracked -+ return False -+ except git.NoSuchPathError: -+ raise RuntimeError("%s is not a valid path" % repo_path) - - if relative_file_path in repo.untracked_files: - return False --- -2.21.1 - diff --git a/0002-Repair-compatible-formatting-for-Python-2.6.patch b/0002-Repair-compatible-formatting-for-Python-2.6.patch deleted file mode 100644 index 9fcc464..0000000 --- a/0002-Repair-compatible-formatting-for-Python-2.6.patch +++ /dev/null @@ -1,93 +0,0 @@ -From abe0b0a9b650b1d55c2482d10ad8898f0efc00ea Mon Sep 17 00:00:00 2001 -From: Ondrej Nosek -Date: Tue, 24 Mar 2020 02:05:19 +0100 -Subject: [PATCH] Repair compatible formatting for Python 2.6 - -Signed-off-by: Ondrej Nosek ---- - pyrpkg/__init__.py | 12 ++++++------ - pyrpkg/utils.py | 8 ++++---- - 2 files changed, 10 insertions(+), 10 deletions(-) - -diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py -index 50f3302..791b66b 100644 ---- a/pyrpkg/__init__.py -+++ b/pyrpkg/__init__.py -@@ -1358,14 +1358,14 @@ class Commands(object): - target_dir = tempfile.mkdtemp(suffix="extract-srpm", prefix="rpkg") - try: - try: -- self.log.debug("Extracting srpm '{}', destination '{}'".format( -+ self.log.debug("Extracting srpm '{0}', destination '{1}'".format( - srpm, target_dir - )) - # method 'is_lookaside_eligible_file' will access extracted - # files to detect its encoding (binary or not) - _, _ = extract_srpm(srpm, target_dir) - except Exception as e: -- self.log.error("Extraction of srpm has failed {}".format(e)) -+ self.log.error("Extraction of srpm has failed {0}".format(e)) - raise - - # Cycle through the srpm content and decide where to upload files -@@ -1633,8 +1633,8 @@ class Commands(object): - namespace = repo.split("/")[0] if "/" in repo else "rpms" - # Has current namespace its own clone config? - selected_clone_config = None -- if hasattr(self, "clone_config_{}".format(namespace)): -- selected_clone_config = getattr(self, "clone_config_{}".format(namespace)) -+ if hasattr(self, "clone_config_{0}".format(namespace)): -+ selected_clone_config = getattr(self, "clone_config_{0}".format(namespace)) - - # Valid configuration is non-empty string - if selected_clone_config: -@@ -1875,10 +1875,10 @@ class Commands(object): - os.remove(file) - - try: -- self.log.debug("Extracting srpm '{}'".format(srpm)) -+ self.log.debug("Extracting srpm '{0}'".format(srpm)) - output, err = extract_srpm(srpm) - except Exception as e: -- self.log.error("Extraction of srpm has failed {}".format(e)) -+ self.log.error("Extraction of srpm has failed {0}".format(e)) - raise - if output: - self.log.debug(output) -diff --git a/pyrpkg/utils.py b/pyrpkg/utils.py -index d1b79b9..1a50a3e 100644 ---- a/pyrpkg/utils.py -+++ b/pyrpkg/utils.py -@@ -251,9 +251,9 @@ def extract_srpm(srpm_path, target_dir=None): - directory if not specified - """ - if not os.path.isfile(srpm_path): -- raise IOError("Input file doesn't exist: {}".format(srpm_path)) -+ raise IOError("Input file doesn't exist: {0}".format(srpm_path)) - if target_dir and not os.path.isdir(target_dir): -- raise IOError("Target directory doesn't exist: {}".format(target_dir)) -+ raise IOError("Target directory doesn't exist: {0}".format(target_dir)) - - # rpm2cpio | cpio -iud --quiet - cmd = ['rpm2cpio', srpm_path] -@@ -272,7 +272,7 @@ def is_lookaside_eligible_file(file_name, dir_path=None): - """ - file_path = os.path.join(dir_path or "", file_name) - if not os.path.isfile(file_path): -- raise IOError("Input file doesn't exist: {}".format(file_path)) -+ raise IOError("Input file doesn't exist: {0}".format(file_path)) - - p = subprocess.Popen( - # parameter '-b' causes brief output - without filename in the output -@@ -284,7 +284,7 @@ def is_lookaside_eligible_file(file_name, dir_path=None): - ) - output, errors = p.communicate() - if errors: -- raise RuntimeError("Mime encoding detection of the file '{}' has failed: {}".format( -+ raise RuntimeError("Mime encoding detection of the file '{0}' has failed: {1}".format( - file_path, - errors - )) --- -2.21.1 - diff --git a/0003-Switch-from-krb_login-to-gssapi_login.patch b/0003-Switch-from-krb_login-to-gssapi_login.patch deleted file mode 100644 index 4799880..0000000 --- a/0003-Switch-from-krb_login-to-gssapi_login.patch +++ /dev/null @@ -1,95 +0,0 @@ -From 9df7f1b6741aa1ad08232f31e140d614da869e07 Mon Sep 17 00:00:00 2001 -From: Ondrej Nosek -Date: Tue, 19 May 2020 00:10:01 +0200 -Subject: [PATCH 1/2] Switch from krb_login to gssapi_login - -Replaces deprecated method krb_login. - -JIRA: RHELCMP-567 -Resolves: rhbz#1830430 -Fixes: #498 - -Signed-off-by: Ondrej Nosek ---- - pyrpkg/__init__.py | 4 +--- - tests/test_commands.py | 16 ++++++++-------- - 2 files changed, 9 insertions(+), 11 deletions(-) - -diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py -index 7da3de7..5d5d55d 100644 ---- a/pyrpkg/__init__.py -+++ b/pyrpkg/__init__.py -@@ -301,7 +301,6 @@ class Commands(object): - 'topurl': 'http://localhost/kojiroot', - 'use_fast_upload': None, - 'weburl': 'http://localhost/koji', -- 'krb_rdns': None, - } - - # Process the configs in order, global, user, then any option passed -@@ -323,7 +322,6 @@ class Commands(object): - 'offline_retry_interval': config.getint, - 'retry_interval': config.getint, - 'timeout': config.getint, -- 'krb_rdns': config.getboolean, - } - - if config.has_section(build_client_name): -@@ -376,7 +374,7 @@ class Commands(object): - - if self._load_krb_user(): - try: -- session.krb_login(proxyuser=self.runas) -+ session.gssapi_login(proxyuser=self.runas) - except Exception as e: - self.log.error('Kerberos authentication fails: %s', e) - else: -diff --git a/tests/test_commands.py b/tests/test_commands.py -index 40e64ce..d07508c 100644 ---- a/tests/test_commands.py -+++ b/tests/test_commands.py -@@ -672,33 +672,33 @@ class TestLoginKojiSession(CommandTestCase): - self.session.login.assert_called_once() - - @patch('pyrpkg.Commands._load_krb_user', return_value=False) -- def test_krb_login_fails_if_no_valid_credential(self, _load_krb_user): -+ def test_gssapi_login_fails_if_no_valid_credential(self, _load_krb_user): - self.koji_config['authtype'] = 'kerberos' - self.cmd.realms = ['FEDORAPROJECT.ORG'] - - self.cmd.login_koji_session(self.koji_config, self.session) - -- self.session.krb_login.assert_not_called() -+ self.session.gssapi_login.assert_not_called() - self.assertEqual(2, self.cmd.log.warning.call_count) - - @patch('pyrpkg.Commands._load_krb_user', return_value=True) -- def test_krb_login_fails(self, _load_krb_user): -+ def test_gssapi_login_fails(self, _load_krb_user): - self.koji_config['authtype'] = 'kerberos' -- # Simulate ClientSession.krb_login fails and error is raised. -- self.session.krb_login.side_effect = Exception -+ # Simulate ClientSession.gssapi_login fails and error is raised. -+ self.session.gssapi_login.side_effect = Exception - - self.cmd.login_koji_session(self.koji_config, self.session) - -- self.session.krb_login.assert_called_once_with(proxyuser=None) -+ self.session.gssapi_login.assert_called_once_with(proxyuser=None) - self.cmd.log.error.assert_called_once() - - @patch('pyrpkg.Commands._load_krb_user', return_value=True) -- def test_successful_krb_login(self, _load_krb_user): -+ def test_successful_gssapi_login(self, _load_krb_user): - self.koji_config['authtype'] = 'kerberos' - - self.cmd.login_koji_session(self.koji_config, self.session) - -- self.session.krb_login.assert_called_once_with(proxyuser=None) -+ self.session.gssapi_login.assert_called_once_with(proxyuser=None) - - - class TestConstructBuildURL(CommandTestCase): --- -2.21.3 - diff --git a/0004-added-a-extendable-layout-module-to-deal-with-differ.patch b/0004-added-a-extendable-layout-module-to-deal-with-differ.patch deleted file mode 100644 index 088702a..0000000 --- a/0004-added-a-extendable-layout-module-to-deal-with-differ.patch +++ /dev/null @@ -1,630 +0,0 @@ -From a95bad2ed57e500a9f9c1ec50d1c5cdacffca5f4 Mon Sep 17 00:00:00 2001 -From: odra <2183506+odra@users.noreply.github.com> -Date: Mon, 20 Jul 2020 15:41:31 -0300 -Subject: [PATCH] added a extendable layout module to deal with different - package layouts within the CLI - -Signed-off-by: lrossett ---- - pyrpkg/__init__.py | 31 ++++--- - pyrpkg/errors.py | 5 + - pyrpkg/layout/__init__.py | 30 ++++++ - pyrpkg/layout/base.py | 93 +++++++++++++++++++ - pyrpkg/layout/layouts.py | 80 ++++++++++++++++ - .../fixtures/layouts/dead-module/dead.module | 0 - .../fixtures/layouts/dead-module/foobar.spec | 0 - .../layouts/dead-package/dead.package | 0 - .../fixtures/layouts/dead-package/foobar.spec | 0 - tests/fixtures/layouts/dist-git/foobar.spec | 0 - tests/fixtures/layouts/dist-git/foobar.txt | 0 - tests/fixtures/layouts/dist-git/sources | 0 - tests/fixtures/layouts/specless/.gitkeep | 0 - .../layouts/srpm-dead-module/.foobar.metadata | 0 - .../SOURCES/foobar-firstcommit.patch | 0 - .../srpm-dead-module/SPECS/foobar.spec | 0 - .../layouts/srpm-dead-module/dead.module | 0 - .../srpm-dead-package/.foobar.metadata | 0 - .../SOURCES/foobar-firstcommit.patch | 0 - .../srpm-dead-package/SPECS/foobar.spec | 0 - .../layouts/srpm-dead-package/dead.package | 0 - .../srpm-dead-package/srpm/.foobar.metadata | 0 - .../srpm/SOURCES/foobar-firstcommit.patch | 0 - .../srpm-dead-package/srpm/SPECS/foobar.spec | 0 - .../layouts/srpm-specless/.foobar.metadata | 0 - .../layouts/srpm-specless/SPECS/.gitkeep | 0 - tests/fixtures/layouts/srpm/.foobar.metadata | 0 - .../srpm/SOURCES/foobar-firstcommit.patch | 0 - tests/fixtures/layouts/srpm/SPECS/foobar.spec | 0 - tests/test_cli.py | 22 +++-- - tests/test_layout_distgit.py | 50 ++++++++++ - tests/test_layout_srpm.py | 49 ++++++++++ - 32 files changed, 340 insertions(+), 20 deletions(-) - create mode 100644 pyrpkg/layout/__init__.py - create mode 100644 pyrpkg/layout/base.py - create mode 100644 pyrpkg/layout/layouts.py - create mode 100644 tests/fixtures/layouts/dead-module/dead.module - create mode 100644 tests/fixtures/layouts/dead-module/foobar.spec - create mode 100644 tests/fixtures/layouts/dead-package/dead.package - create mode 100644 tests/fixtures/layouts/dead-package/foobar.spec - create mode 100644 tests/fixtures/layouts/dist-git/foobar.spec - create mode 100644 tests/fixtures/layouts/dist-git/foobar.txt - create mode 100644 tests/fixtures/layouts/dist-git/sources - create mode 100644 tests/fixtures/layouts/specless/.gitkeep - create mode 100644 tests/fixtures/layouts/srpm-dead-module/.foobar.metadata - create mode 100644 tests/fixtures/layouts/srpm-dead-module/SOURCES/foobar-firstcommit.patch - create mode 100644 tests/fixtures/layouts/srpm-dead-module/SPECS/foobar.spec - create mode 100644 tests/fixtures/layouts/srpm-dead-module/dead.module - create mode 100644 tests/fixtures/layouts/srpm-dead-package/.foobar.metadata - create mode 100644 tests/fixtures/layouts/srpm-dead-package/SOURCES/foobar-firstcommit.patch - create mode 100644 tests/fixtures/layouts/srpm-dead-package/SPECS/foobar.spec - create mode 100644 tests/fixtures/layouts/srpm-dead-package/dead.package - create mode 100644 tests/fixtures/layouts/srpm-dead-package/srpm/.foobar.metadata - create mode 100644 tests/fixtures/layouts/srpm-dead-package/srpm/SOURCES/foobar-firstcommit.patch - create mode 100644 tests/fixtures/layouts/srpm-dead-package/srpm/SPECS/foobar.spec - create mode 100644 tests/fixtures/layouts/srpm-specless/.foobar.metadata - create mode 100644 tests/fixtures/layouts/srpm-specless/SPECS/.gitkeep - create mode 100644 tests/fixtures/layouts/srpm/.foobar.metadata - create mode 100644 tests/fixtures/layouts/srpm/SOURCES/foobar-firstcommit.patch - create mode 100644 tests/fixtures/layouts/srpm/SPECS/foobar.spec - create mode 100644 tests/test_layout_distgit.py - create mode 100644 tests/test_layout_srpm.py - -diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py -index 6a24033..1252251 100644 ---- a/pyrpkg/__init__.py -+++ b/pyrpkg/__init__.py -@@ -49,6 +49,7 @@ from pyrpkg.sources import SourcesFile - from pyrpkg.utils import (cached_property, extract_srpm, find_me, - is_file_tracked, is_lookaside_eligible_file, - log_result) -+from pyrpkg import layout - - from .gitignore import GitIgnore - -@@ -212,6 +213,8 @@ class Commands(object): - self.block_retire_ns = ['rpms'] - # Git excludes patterns - self.git_excludes = git_excludes or [] -+ # Layout setup -+ self.layout = layout.build(self.path) - - # Define properties here - # Properties allow us to "lazy load" various attributes, which also means -@@ -759,14 +762,16 @@ class Commands(object): - raise rpkgError('Could not find the base OS ver from branch name' - ' %s. Consider using --release option' % - self.branch_merge) -+ if self.layout is None: -+ raise rpkgError('Unexpected error while loading the package.') - self._distvar, self._distval = osver.split('-') - self._distval = self._distval.replace('.', '_') - self._disttag = 'el%s' % self._distval -- self._rpmdefines = ["--define '_sourcedir %s'" % self.path, -- "--define '_specdir %s'" % self.path, -- "--define '_builddir %s'" % self.path, -- "--define '_srcrpmdir %s'" % self.path, -- "--define '_rpmdir %s'" % self.path, -+ self._rpmdefines = ["--define '_sourcedir %s'" % self.layout.sourcedir, -+ "--define '_specdir %s'" % self.layout.specdir, -+ "--define '_builddir %s'" % self.layout.builddir, -+ "--define '_srcrpmdir %s'" % self.layout.srcrpmdir, -+ "--define '_rpmdir %s'" % self.layout.rpmdir, - "--define 'dist .%s'" % self._disttag, - "--define '%s %s'" % (self._distvar, - self._distval.split('_')[0]), -@@ -784,11 +789,14 @@ class Commands(object): - def load_spec(self): - """This sets the spec attribute""" - -+ if self.layout is None: -+ raise rpkgError('Spec file is not available') -+ - if self.is_retired(): - raise rpkgError('This package or module is retired. The action has stopped.') - - # Get a list of files in the path we're looking at -- files = os.listdir(self.path) -+ files = os.listdir(self.layout.specdir) - # Search the files for the first one that ends with ".spec" - for f in files: - if f.endswith('.spec') and not f.startswith('.'): -@@ -1015,7 +1023,9 @@ class Commands(object): - - @property - def sources_filename(self): -- return os.path.join(self.path, 'sources') -+ if self.layout is None: -+ return os.path.join(self.path, 'sources') -+ return os.path.join(self.path, self.layout.sources_file_template) - - @property - def osbs_config_filename(self): -@@ -3188,12 +3198,7 @@ class Commands(object): - The state is indicated by present of files 'dead.package' - or 'dead.module'. - """ -- marker = 'dead.package' -- if os.path.isfile(os.path.join(self.path, marker)): -- return marker -- marker = 'dead.module' -- if os.path.isfile(os.path.join(self.path, marker)): -- return marker -+ return self.layout.is_retired() - - def retire(self, message): - """Delete all tracked files and commit a new dead.package file for rpms -diff --git a/pyrpkg/errors.py b/pyrpkg/errors.py -index 1378bf2..49b71d4 100644 ---- a/pyrpkg/errors.py -+++ b/pyrpkg/errors.py -@@ -62,3 +62,8 @@ class UploadError(rpkgError): - - def __unicode__(self): - return six.text_type(self.message) -+ -+ -+class LayoutError(rpkgError): -+ """Raised when something went wrong while parsing/loading a layout""" -+ pass -diff --git a/pyrpkg/layout/__init__.py b/pyrpkg/layout/__init__.py -new file mode 100644 -index 0000000..bdb2a79 ---- /dev/null -+++ b/pyrpkg/layout/__init__.py -@@ -0,0 +1,30 @@ -+# Copyright (c) 2015 - Red Hat Inc. -+# -+# This program is free software; you can redistribute it and/or modify it -+# under the terms of the GNU General Public License as published by the -+# Free Software Foundation; either version 2 of the License, or (at your -+# option) any later version. See http://www.gnu.org/copyleft/gpl.html for -+# the full text of the license. -+ -+"""package layout management""" -+ -+ -+from pyrpkg.errors import LayoutError -+from .base import MetaLayout -+from .layouts import DistGitLayout, SRPMLayout # noqa -+ -+ -+def build(path): -+ """ -+ Tries to create a layout instance based on MetaLayout._layouts -+ and will return an instance in the first successfull attempt to -+ create a new object from the MetaLayout._layouts list. -+ -+ Returns None if no layouts can be created. -+ """ -+ for layout in MetaLayout._layouts: -+ try: -+ return layout.from_path(path) -+ except LayoutError: -+ continue -+ return None -diff --git a/pyrpkg/layout/base.py b/pyrpkg/layout/base.py -new file mode 100644 -index 0000000..db30540 ---- /dev/null -+++ b/pyrpkg/layout/base.py -@@ -0,0 +1,93 @@ -+# Copyright (c) 2015 - Red Hat Inc. -+# -+# This program is free software; you can redistribute it and/or modify it -+# under the terms of the GNU General Public License as published by the -+# Free Software Foundation; either version 2 of the License, or (at your -+# option) any later version. See http://www.gnu.org/copyleft/gpl.html for -+# the full text of the license. -+ -+"""base and meta package layout classes""" -+ -+ -+import os -+import abc -+from abc import abstractmethod, ABCMeta -+ -+import six -+ -+from pyrpkg.errors import LayoutError -+ -+ -+if six.PY2: -+ ABC = abc.ABCMeta('ABC', (object,), {'__slots__': ()}) -+else: -+ ABC = abc.ABC -+ -+ -+class MetaLayout(type): -+ """ -+ Layout meta class that keeps track of all layout subclasses. -+ -+ Classes are appended in the _layouts property in order of code execution. -+ """ -+ def __init__(cls, name, bases, dct): -+ """ -+ This method registers a subclass in a class property (_layouts) -+ so those can be used as valid layout classes. -+ """ -+ if not hasattr(cls, '_layouts'): -+ MetaLayout._layouts = [] -+ if cls not in cls._layouts and cls.__name__ != 'BaseLayout': -+ MetaLayout._layouts.append(cls) -+ super(MetaLayout, cls).__init__(name, bases, dct) -+ -+ -+class ABCMetaLayout(MetaLayout, ABCMeta): -+ """ -+ A mixin metaclass to enable usage of both Metalayout and ABC meta classes as a single metaclass. -+ """ -+ pass -+ -+ -+@six.add_metaclass(ABCMetaLayout) -+class BaseLayout(ABC): -+ """ -+ The abstract class to be inherited from when implemeting specific layouts. -+ -+ Every subclass will be registered in the MetaLayout class. -+ -+ Inherited classes will be registered in order or code execution. -+ """ -+ root_dir = None -+ sourcedir = None -+ specdir = None -+ builddir = None -+ rpmdir = None -+ srcrpmdir = None -+ sources_file_template = None -+ -+ @classmethod -+ @abstractmethod -+ def from_path(cls, path): -+ """ -+ Class constructor based on a package path. -+ -+ This method's implementation is madatory and -+ should return an instance of the object class. -+ -+ It should return None if it can't read the path -+ or if the dir path contains an invalid layout. -+ """ -+ if not os.path.exists(path): -+ raise LayoutError('package path does not exist') -+ -+ def is_retired(self): -+ """ -+ Checks whether package or module is already retired. -+ The state is indicated by present of files 'dead.package' -+ or 'dead.module'. -+ """ -+ for fname in ['dead.package', 'dead.module']: -+ if os.path.exists('%s/%s' % (self.root_dir, fname)): -+ return fname -+ return None -diff --git a/pyrpkg/layout/layouts.py b/pyrpkg/layout/layouts.py -new file mode 100644 -index 0000000..96143b9 ---- /dev/null -+++ b/pyrpkg/layout/layouts.py -@@ -0,0 +1,80 @@ -+# Copyright (c) 2015 - Red Hat Inc. -+# -+# This program is free software; you can redistribute it and/or modify it -+# under the terms of the GNU General Public License as published by the -+# Free Software Foundation; either version 2 of the License, or (at your -+# option) any later version. See http://www.gnu.org/copyleft/gpl.html for -+# the full text of the license. -+ -+"""package layout implementation""" -+ -+ -+import os -+ -+from .base import BaseLayout -+from pyrpkg.errors import LayoutError -+ -+ -+class DistGitLayout(BaseLayout): -+ """ -+ This class represents a dist-git package layout. -+ """ -+ def __init__(self, root_dir=None, sources_file_template='sources'): -+ """ -+ Default class constructor to create a new object instance. -+ """ -+ self.root_dir = root_dir -+ self.sourcedir = root_dir -+ self.specdir = root_dir -+ self.builddir = root_dir -+ self.rpmdir = root_dir -+ self.srcrpmdir = root_dir -+ self.sources_file_template = sources_file_template -+ -+ @classmethod -+ def from_path(cls, path): -+ """ -+ Creates a new object instance from a valid path in the file system. -+ -+ Returns none if path or package structure is invalid. -+ """ -+ super(DistGitLayout, cls).from_path(path) -+ -+ if len([f for f in os.listdir(path) if f.endswith('.spec')]) == 0: -+ raise LayoutError('spec file not found.') -+ sources = 'sources' if os.path.exists('%s/sources' % path) else None -+ return cls(root_dir=path, sources_file_template=sources) -+ -+ -+class SRPMLayout(BaseLayout): -+ """ -+ This class represents an exposed source RPM package layout. -+ """ -+ def __init__(self, root_dir=None, sources_file_template='.{0.repo_name}.metadata'): -+ """ -+ Default class constructor to create a new object instance. -+ """ -+ self.root_dir = root_dir -+ self.sourcedir = os.path.join(root_dir, 'SOURCES') -+ self.specdir = os.path.join(root_dir, 'SPECS') -+ self.builddir = os.path.join(root_dir, 'BUILD') -+ self.rpmdir = os.path.join(root_dir, 'RPMS') -+ self.srcrpmdir = os.path.join(root_dir, 'SRPMS') -+ self.sources_file_template = sources_file_template -+ -+ @classmethod -+ def from_path(cls, path): -+ """ -+ Creates a new object instance from a valid path in the file system. -+ -+ Returns none if path or package structure is invalid. -+ """ -+ super(SRPMLayout, cls).from_path(path) -+ -+ if not os.path.exists(os.path.join(path, 'SPECS')): -+ raise LayoutError('SPECS dir not found.') -+ if len([f for f in os.listdir(os.path.join(path, 'SPECS')) if f.endswith('.spec')]) == 0: -+ raise LayoutError('spec file not found.') -+ if len([f for f in os.listdir(path) if f.endswith('.metadata')]) == 0: -+ raise LayoutError('metadata file not found.') -+ return cls(root_dir=path) -diff --git a/tests/fixtures/layouts/dead-module/dead.module b/tests/fixtures/layouts/dead-module/dead.module -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/dead-module/foobar.spec b/tests/fixtures/layouts/dead-module/foobar.spec -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/dead-package/dead.package b/tests/fixtures/layouts/dead-package/dead.package -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/dead-package/foobar.spec b/tests/fixtures/layouts/dead-package/foobar.spec -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/dist-git/foobar.spec b/tests/fixtures/layouts/dist-git/foobar.spec -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/dist-git/foobar.txt b/tests/fixtures/layouts/dist-git/foobar.txt -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/dist-git/sources b/tests/fixtures/layouts/dist-git/sources -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/specless/.gitkeep b/tests/fixtures/layouts/specless/.gitkeep -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm-dead-module/.foobar.metadata b/tests/fixtures/layouts/srpm-dead-module/.foobar.metadata -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm-dead-module/SOURCES/foobar-firstcommit.patch b/tests/fixtures/layouts/srpm-dead-module/SOURCES/foobar-firstcommit.patch -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm-dead-module/SPECS/foobar.spec b/tests/fixtures/layouts/srpm-dead-module/SPECS/foobar.spec -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm-dead-module/dead.module b/tests/fixtures/layouts/srpm-dead-module/dead.module -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm-dead-package/.foobar.metadata b/tests/fixtures/layouts/srpm-dead-package/.foobar.metadata -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm-dead-package/SOURCES/foobar-firstcommit.patch b/tests/fixtures/layouts/srpm-dead-package/SOURCES/foobar-firstcommit.patch -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm-dead-package/SPECS/foobar.spec b/tests/fixtures/layouts/srpm-dead-package/SPECS/foobar.spec -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm-dead-package/dead.package b/tests/fixtures/layouts/srpm-dead-package/dead.package -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm-dead-package/srpm/.foobar.metadata b/tests/fixtures/layouts/srpm-dead-package/srpm/.foobar.metadata -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm-dead-package/srpm/SOURCES/foobar-firstcommit.patch b/tests/fixtures/layouts/srpm-dead-package/srpm/SOURCES/foobar-firstcommit.patch -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm-dead-package/srpm/SPECS/foobar.spec b/tests/fixtures/layouts/srpm-dead-package/srpm/SPECS/foobar.spec -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm-specless/.foobar.metadata b/tests/fixtures/layouts/srpm-specless/.foobar.metadata -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm-specless/SPECS/.gitkeep b/tests/fixtures/layouts/srpm-specless/SPECS/.gitkeep -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm/.foobar.metadata b/tests/fixtures/layouts/srpm/.foobar.metadata -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm/SOURCES/foobar-firstcommit.patch b/tests/fixtures/layouts/srpm/SOURCES/foobar-firstcommit.patch -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/fixtures/layouts/srpm/SPECS/foobar.spec b/tests/fixtures/layouts/srpm/SPECS/foobar.spec -new file mode 100644 -index 0000000..e69de29 -diff --git a/tests/test_cli.py b/tests/test_cli.py -index a8b34f4..eb9c79e 100644 ---- a/tests/test_cli.py -+++ b/tests/test_cli.py -@@ -19,7 +19,7 @@ from six.moves import StringIO, configparser, http_client - import koji_cli.lib - import pyrpkg.cli - import utils --from pyrpkg import Commands, Modulemd, rpkgError -+from pyrpkg import Commands, Modulemd, rpkgError, layout - from utils import CommandTestCase, FakeThreadPool - - try: -@@ -64,6 +64,11 @@ def mock_get_rpm_package_name(self, rpm_file): - return(os.path.basename(rpm_file)[:-len('.src.rpm')]) - - -+class MockLayout(layout.DistGitLayout): -+ def is_retired(self): -+ return None -+ -+ - class CliTestCase(CommandTestCase): - - def new_cli(self, cfg=None): -@@ -1561,11 +1566,13 @@ class TestMockbuild(CliTestCase): - @patch('os.path.exists', return_value=False) - def test_use_mock_config_got_from_koji( - self, exists, config_dir_other, config_dir_basic): -- config_dir_basic.return_value = '/path/to/config-dir' -+ mock_layout = layout.DistGitLayout(root_dir=self.cloned_repo_path) -+ with patch('pyrpkg.layout.build', return_value=mock_layout): -+ config_dir_basic.return_value = '/path/to/config-dir' - -- cli_cmd = ['rpkg', '--path', self.cloned_repo_path, -- '--release', 'rhel-7', 'mockbuild'] -- self.mockbuild(cli_cmd) -+ cli_cmd = ['rpkg', '--path', self.cloned_repo_path, -+ '--release', 'rhel-7', 'mockbuild'] -+ self.mockbuild(cli_cmd) - - args, kwargs = self.mock_run_command.call_args - cmd_to_execute = args[0] -@@ -3449,8 +3456,9 @@ class TestBuildPackage(FakeKojiCreds, CliTestCase): - @patch('pyrpkg.Commands.nvr', new_callable=PropertyMock) - @patch('pyrpkg.Commands._run_command') - def test_option_srpm_by_generate_srpm_from_repo(self, _run_command, nvr): -- nvr.return_value = 'docpkg-0.1-1.fc28' -- self.assert_option_srpm_use() -+ with patch('pyrpkg.layout.build', return_value=MockLayout(root_dir=self.cloned_repo_path)): -+ nvr.return_value = 'docpkg-0.1-1.fc28' -+ self.assert_option_srpm_use() - - args, kwargs = _run_command.call_args - self.assertEqual({'shell': True}, kwargs) -diff --git a/tests/test_layout_distgit.py b/tests/test_layout_distgit.py -new file mode 100644 -index 0000000..a4c4944 ---- /dev/null -+++ b/tests/test_layout_distgit.py -@@ -0,0 +1,50 @@ -+import os -+import unittest -+ -+from pyrpkg.layout import layouts -+from pyrpkg import errors -+ -+ -+fixtures_dir = os.path.join(os.path.dirname(__file__), 'fixtures') -+ -+ -+class DistGitLayoutTestCase(unittest.TestCase): -+ def setUp(self): -+ self.workdir = os.path.join(fixtures_dir, 'layouts/dist-git') -+ self.layout = layouts.DistGitLayout.from_path(self.workdir) -+ -+ def test_layout_data(self): -+ self.assertEqual(self.layout.sourcedir, self.workdir) -+ self.assertEqual(self.layout.specdir, self.workdir) -+ self.assertEqual(self.layout.specdir, self.workdir) -+ self.assertEqual(self.layout.root_dir, self.workdir) -+ self.assertEqual(self.layout.builddir, self.workdir) -+ self.assertEqual(self.layout.rpmdir, self.workdir) -+ self.assertEqual(self.layout.srcrpmdir, self.workdir) -+ self.assertEqual(self.layout.sources_file_template, 'sources') -+ -+ def test_layout_retired(self): -+ self.assertEqual(None, self.layout.is_retired()) -+ -+ -+class DistGitLayoutErrorsTestCase(unittest.TestCase): -+ def setUp(self): -+ self.workdir = os.path.join(fixtures_dir, 'layouts') -+ -+ def test_path_error(self): -+ with self.assertRaises(errors.LayoutError) as e: -+ layouts.DistGitLayout.from_path(os.path.join(self.workdir, 'notfound')) -+ self.assertEqual('package path does not exist', e.exception.args[0]) -+ -+ def test_specless_error(self): -+ with self.assertRaises(errors.LayoutError) as e: -+ layouts.DistGitLayout.from_path(os.path.join(self.workdir, 'specless')) -+ self.assertEqual('spec file not found.', e.exception.args[0]) -+ -+ def test_dead_module_error(self): -+ layout = layouts.DistGitLayout.from_path(os.path.join(self.workdir, 'dead-module')) -+ self.assertEqual('dead.module', layout.is_retired()) -+ -+ def test_dead_package_error(self): -+ layout = layouts.DistGitLayout.from_path(os.path.join(self.workdir, 'dead-package')) -+ self.assertEqual('dead.package', layout.is_retired()) -diff --git a/tests/test_layout_srpm.py b/tests/test_layout_srpm.py -new file mode 100644 -index 0000000..562406f ---- /dev/null -+++ b/tests/test_layout_srpm.py -@@ -0,0 +1,49 @@ -+import os -+import unittest -+ -+from pyrpkg.layout import layouts -+from pyrpkg import errors -+ -+ -+fixtures_dir = os.path.join(os.path.dirname(__file__), 'fixtures') -+ -+ -+class SRPMLayoutTestCase(unittest.TestCase): -+ def setUp(self): -+ self.workdir = os.path.join(fixtures_dir, 'layouts/srpm') -+ self.layout = layouts.SRPMLayout.from_path(self.workdir) -+ -+ def test_layout_data(self): -+ self.assertEqual(self.layout.sourcedir, os.path.join(self.workdir, 'SOURCES')) -+ self.assertEqual(self.layout.specdir, os.path.join(self.workdir, 'SPECS')) -+ self.assertEqual(self.layout.root_dir, self.workdir) -+ self.assertEqual(self.layout.builddir, os.path.join(self.workdir, 'BUILD')) -+ self.assertEqual(self.layout.rpmdir, os.path.join(self.workdir, 'RPMS')) -+ self.assertEqual(self.layout.srcrpmdir, os.path.join(self.workdir, 'SRPMS')) -+ self.assertEqual(self.layout.sources_file_template, '.{0.repo_name}.metadata') -+ -+ def test_layout_retired(self): -+ self.assertEqual(None, self.layout.is_retired()) -+ -+ -+class SRPMLayoutErrorsTestCase(unittest.TestCase): -+ def setUp(self): -+ self.workdir = os.path.join(fixtures_dir, 'layouts') -+ -+ def test_path_error(self): -+ with self.assertRaises(errors.LayoutError) as e: -+ layouts.SRPMLayout.from_path(os.path.join(self.workdir, 'notfound')) -+ self.assertEqual('package path does not exist', e.exception.args[0]) -+ -+ def test_specless_error(self): -+ with self.assertRaises(errors.LayoutError) as e: -+ layouts.SRPMLayout.from_path(os.path.join(self.workdir, 'srpm-specless')) -+ self.assertEqual('spec file not found.', e.exception.args[0]) -+ -+ def test_dead_module_error(self): -+ layout = layouts.SRPMLayout.from_path(os.path.join(self.workdir, 'srpm-dead-module')) -+ self.assertEqual('dead.module', layout.is_retired()) -+ -+ def test_dead_package_error(self): -+ layout = layouts.SRPMLayout.from_path(os.path.join(self.workdir, 'srpm-dead-package')) -+ self.assertEqual('dead.package', layout.is_retired()) --- -2.26.2 - diff --git a/0005-clog-tests-workaround.patch b/0005-clog-tests-workaround.patch deleted file mode 100644 index c80adcb..0000000 --- a/0005-clog-tests-workaround.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 76eccea730446a44e11a4d85146666220763cbff Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ond=C5=99ej=20Nosek?= -Date: Wed, 5 Aug 2020 01:08:25 +0000 -Subject: [PATCH] Re-enable clog tests -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -Applied workaround described here: -https://github.com/rpm-software-management/rpm/issues/1301 - -Signed-off-by: Ondřej Nosek ---- - pyrpkg/__init__.py | 5 +++++ - tests/test_cli.py | 6 ------ - 2 files changed, 5 insertions(+), 6 deletions(-) - -diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py -index 6a24033..ad53257 100644 ---- a/pyrpkg/__init__.py -+++ b/pyrpkg/__init__.py -@@ -2328,7 +2328,12 @@ class Commands(object): - """Write the latest spec changelog entry to a clog file""" - - spec_file = os.path.join(self.path, self.spec) -+ # TODO: remove when fixed -+ # Command contains workaround (undefines _changelog_trimtime) described at: -+ # https://github.com/rpm-software-management/rpm/issues/1301 -+ # It caused, that older changelog records were not displayed. - cmd = ['rpm'] + self.rpmdefines + ['-q', '--qf', '"%{CHANGELOGTEXT}\n"', -+ '--undefine', '"_changelog_trimtime"', - '--specfile', '"%s"' % spec_file] - proc = subprocess.Popen(' '.join(cmd), shell=True, - stdout=subprocess.PIPE, stderr=subprocess.PIPE, diff --git a/0006-Skip-sources-file-when-it-is-missing.patch b/0006-Skip-sources-file-when-it-is-missing.patch deleted file mode 100644 index 0e7cde9..0000000 --- a/0006-Skip-sources-file-when-it-is-missing.patch +++ /dev/null @@ -1,34 +0,0 @@ -From 3af55c08f4563b4404c509abf5402e30c9c58bda Mon Sep 17 00:00:00 2001 -From: =?UTF-8?q?Ond=C5=99ej=20Nosek?= -Date: Wed, 12 Aug 2020 00:42:25 +0000 -Subject: [PATCH] Skip 'sources' file when it is missing -MIME-Version: 1.0 -Content-Type: text/plain; charset=UTF-8 -Content-Transfer-Encoding: 8bit - -JIRA: RHELCMP-1968 -Resolves: rhbz#1867440 -Resolves: rhbz#1869848 - -Signed-off-by: Ondřej Nosek ---- - pyrpkg/layout/layouts.py | 3 +-- - 1 file changed, 1 insertion(+), 2 deletions(-) - -diff --git a/pyrpkg/layout/layouts.py b/pyrpkg/layout/layouts.py -index 7324708..fe91b8c 100644 ---- a/pyrpkg/layout/layouts.py -+++ b/pyrpkg/layout/layouts.py -@@ -42,8 +42,7 @@ class DistGitLayout(BaseLayout): - - if len([f for f in os.listdir(path) if f.endswith('.spec')]) == 0: - raise LayoutError('spec file not found.') -- sources = 'sources' if os.path.exists('%s/sources' % path) else None -- return cls(root_dir=path, sources_file_template=sources) -+ return cls(root_dir=path) - - - class SRPMLayout(BaseLayout): --- -2.26.2 - diff --git a/rpkg.spec b/rpkg.spec index a4767ac..7d19406 100644 --- a/rpkg.spec +++ b/rpkg.spec @@ -1,6 +1,6 @@ Name: rpkg -Version: 1.60 -Release: 8%{?dist} +Version: 1.61 +Release: 1%{?dist} Summary: Python library for interacting with rpm+git License: GPLv2+ and LGPLv2 @@ -17,12 +17,7 @@ Source0: https://pagure.io/releases/rpkg/%{name}-%{version}.tar.gz # and there is only old rpm-python package in EL6 and 7, so just simply to # remove rpm-py-installer for now. Patch0: remove-koji-and-rpm-py-installer-from-requires.patch -Patch1: 0001-Repair-downloading-sources-into-external-directory.patch -Patch2: 0002-Repair-compatible-formatting-for-Python-2.6.patch -Patch3: 0003-Switch-from-krb_login-to-gssapi_login.patch -Patch4: 0004-added-a-extendable-layout-module-to-deal-with-differ.patch -Patch5: 0005-clog-tests-workaround.patch -Patch6: 0006-Skip-sources-file-when-it-is-missing.patch +Patch1: 0001-Do-not-use-pytest-related-dependencies-temporarily.patch %if 0%{?fedora} || 0%{?rhel} > 7 # Disable python2 build by default @@ -274,6 +269,29 @@ nosetests tests %changelog +* Mon Sep 07 2020 Ondřej Nosek - 1.61-1 +- Pytest update and MANIFEST.in prune (onosek) +- Re-enable clog tests (onosek) +- Skip directories inside of imported srpm file - rhbz#1866297 (onosek) +- Skip 'sources' file when it is missing - rhbz#1867440 (onosek) +- New layout for retired packages - rhbz#1867822 (onosek) +- added a extendable layout module to deal with different package layouts + within the CLI (2183506+odra) +- Add (onosek) +- Pytest replaces nosetests - #501 (onosek) +- Disable some test for 'clog' functionality (onosek) +- Suggest a way to track remote branch - update (onosek) +- Suggest a way to track remote branch in the error log (cqi) +- Remove deprecated support for kojiconfig (onosek) +- Switch from krb_login to gssapi_login - rhbz#1830430 (onosek) +- Disable test method's docstring in nosetests list (onosek) +- Check repo name for correct format (onosek) +- Unittests for passing additional arguments (onosek) +- Passing additional arguments to underlaying commands - #432 (onosek) +- Updated supported plaforms in documentation (onosek) +- Repair compatible formatting for Python 2.6 (onosek) +- Repair downloading sources into external directory (onosek) + * Mon Aug 31 2020 Ondřej Nosek - 1.60-8 - Patch: Skip 'sources' file when it is missing diff --git a/sources b/sources index 39966a2..d0ff436 100644 --- a/sources +++ b/sources @@ -1 +1 @@ -SHA512 (rpkg-1.60.tar.gz) = 7055653943b897e8223e2d352e691d6c7d2ce82c926e3cfefbaea3c6fc8f71284e3e894f51a083e3f6e13a71445ea8383f188c01e5ee19fb14432244d9df11f6 +SHA512 (rpkg-1.61.tar.gz) = e9016eca5bf5a9c5ae3c9e13ffffd53549a9db6beb1028aa5011e0222f56aa45de0ca233b956ebf756cdde78fa409b29806fde88e67b38edaae755a085b3bfe2