summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCoprDistGit <infra@openeuler.org>2025-02-14 07:16:05 +0000
committerCoprDistGit <infra@openeuler.org>2025-02-14 07:16:05 +0000
commit59eb76562e81f5ce539719e5ad0d817d702a8171 (patch)
tree6a853ed345c6a2facbee0b94805c695d3978750a
parent187a0e52c5079bca88ce44ae4aed8afe34f5c81c (diff)
automatic import of rpkgopeneuler22.03_LTS_SP4
-rw-r--r--.gitignore1
-rw-r--r--0001-Do-not-use-pytest-related-dependencies-temporarily.patch25
-rw-r--r--0002-Remove-pytest-coverage-execution.patch25
-rw-r--r--0004-fedpkg-local-does-not-show-rpmbuild-output.patch114
-rw-r--r--0005-Fixes-for-exploded-SRPM-layouts.patch227
-rw-r--r--0006-mockbuild-escape-rpm-command-under-mock.patch59
-rw-r--r--remove-koji-and-rpm-py-installer-from-requires.patch29
-rw-r--r--rpkg.rpmlintrc6
-rw-r--r--rpkg.spec139
-rw-r--r--sources1
10 files changed, 626 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
index e69de29..c35beaa 100644
--- a/.gitignore
+++ b/.gitignore
@@ -0,0 +1 @@
+/rpkg-1.65.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..70d12b0
--- /dev/null
+++ b/0001-Do-not-use-pytest-related-dependencies-temporarily.patch
@@ -0,0 +1,25 @@
+From 50caf547ff288d8146ea5e277ab7bfcf7e8b095c Mon Sep 17 00:00:00 2001
+From: Dominik Rumian <drumian@redhat.com>
+Date: Tue, 24 Aug 2021 16:24:47 +0200
+Subject: [PATCH] [PATCH] Do not use pytest-related dependencies temporarily
+
+Signed-off-by: Dominik Rumian <drumian@redhat.com>
+---
+ setup.py | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/setup.py b/setup.py
+index 9c6d881..557cf5f 100755
+--- a/setup.py
++++ b/setup.py
+@@ -49,7 +49,6 @@ setup(
+ license="GPLv2+",
+ url="https://pagure.io/rpkg",
+ packages=find_packages(),
+- setup_requires=['setuptools_scm', 'pytest-runner'],
+ install_requires=install_requires,
+ tests_require=tests_require,
+ dependency_links=dep_links,
+--
+2.31.1
+
diff --git a/0002-Remove-pytest-coverage-execution.patch b/0002-Remove-pytest-coverage-execution.patch
new file mode 100644
index 0000000..fbc9cb7
--- /dev/null
+++ b/0002-Remove-pytest-coverage-execution.patch
@@ -0,0 +1,25 @@
+From 8bf7c3b1336738ed5938f679fc4d450c3f8f0a62 Mon Sep 17 00:00:00 2001
+From: Ondrej Nosek <onosek@redhat.com>
+Date: Wed, 7 Sep 2022 00:11:56 +0200
+Subject: [PATCH] Remove pytest coverage execution
+
+Signed-off-by: Ondrej Nosek <onosek@redhat.com>
+---
+ setup.cfg | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/setup.cfg b/setup.cfg
+index 5e29c2f..4fe73fa 100644
+--- a/setup.cfg
++++ b/setup.cfg
+@@ -5,7 +5,6 @@ test = pytest
+ max-line-length = 100
+
+ [tool:pytest]
+-addopts = --cov=pyrpkg
+ testpaths = tests
+
+ [egg_info]
+--
+2.37.2
+
diff --git a/0004-fedpkg-local-does-not-show-rpmbuild-output.patch b/0004-fedpkg-local-does-not-show-rpmbuild-output.patch
new file mode 100644
index 0000000..30f3e8e
--- /dev/null
+++ b/0004-fedpkg-local-does-not-show-rpmbuild-output.patch
@@ -0,0 +1,114 @@
+From fef9715d4acb690dff1cc9f08545721d69bf208d Mon Sep 17 00:00:00 2001
+From: Ondrej Nosek <onosek@redhat.com>
+Date: Wed, 7 Sep 2022 19:53:05 +0200
+Subject: [PATCH] `fedpkg local` does not show rpmbuild output
+
+subprocess.communicate() method didn't allow a direct pipe output
+to the shell and therefore wasn't shown to the user. Switched to
+check_call method.
+Additionally, the correct exit code is returned when the first part
+of the command fails.
+
+Resolves: rhbz#2124809
+JIRA: RHELCMP-9960
+
+Signed-off-by: Ondrej Nosek <onosek@redhat.com>
+---
+ pyrpkg/__init__.py | 12 +++++-------
+ tests/test_cli.py | 26 ++++++++++++++------------
+ 2 files changed, 19 insertions(+), 19 deletions(-)
+
+diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py
+index a672dd2..1b6a0c4 100644
+--- a/pyrpkg/__init__.py
++++ b/pyrpkg/__init__.py
+@@ -2818,14 +2818,12 @@ class Commands(object):
+ stdout=subprocess.PIPE,
+ stderr=subprocess.STDOUT
+ )
+- tee = subprocess.Popen(
++ subprocess.check_call(
+ ("tee", logfile),
+- stdin=rpmbuild.stdout,
+- stdout=subprocess.PIPE)
+- rpmbuild.stdout.close()
+- tee.communicate()
+-
+- except subprocess.SubprocessError:
++ stdin=rpmbuild.stdout)
++ rpmbuild.communicate() # without this, 'returncode' is None (=unfinished process)
++ sys.exit(rpmbuild.returncode)
++ except subprocess.CalledProcessError:
+ raise rpkgError(debug_cmd)
+ finally:
+ self._cleanup_tmp_dir(tmpdir)
+diff --git a/tests/test_cli.py b/tests/test_cli.py
+index 254bfac..97ae0ce 100644
+--- a/tests/test_cli.py
++++ b/tests/test_cli.py
+@@ -846,10 +846,12 @@ class TestLocal(CliTestCase):
+
+ create_repo_per_test = False
+
++ @patch('sys.exit')
++ @patch('pyrpkg.subprocess.check_call')
+ @patch('subprocess.Popen')
+ @patch('pyrpkg.Commands.rel')
+ @patch('pyrpkg.Commands.ver')
+- def test_local(self, ver, rel, popen):
++ def test_local(self, ver, rel, popen, check_call, system_exit):
+ cli_cmd = ['rpkg', '--path', self.cloned_repo_path, '--release', 'rhel-6', 'local']
+
+ rel.__str__ = Mock()
+@@ -868,20 +870,21 @@ class TestLocal(CliTestCase):
+ popen.assert_has_calls([
+ # at the beginning of this list, there are other calls from load_nameverrel
+ call(rpmbuild, stdout=-1, stderr=-2),
+- # I can't match this call - stdin=Mock has it's dynamic id. Therefore any_oreder=True
+- # call(tee, stdin=Mock(), stdout=-1), # check call [-3] separately
+- call().stdout.close(),
+ call().communicate(),
+- ], any_order=True)
++ ], any_order=False)
+
+- tee_call_arg = popen.mock_calls[-3]
++ tee_call_arg = check_call.mock_calls[0]
+ if 'args' in dir(tee_call_arg): # doesn't work in <=py36
+ self.assertEqual(tee, tee_call_arg.args[0])
+
++ system_exit.assert_called_once()
++
++ @patch('sys.exit')
++ @patch('pyrpkg.subprocess.check_call')
+ @patch('subprocess.Popen')
+ @patch('pyrpkg.Commands.rel')
+ @patch('pyrpkg.Commands.ver')
+- def test_local_with_options(self, ver, rel, popen):
++ def test_local_with_options(self, ver, rel, popen, check_call, system_exit):
+ builddir = os.path.join(self.cloned_repo_path, 'this-builddir')
+ buildrootdir = os.path.join(self.cloned_repo_path, 'this-buildrootdir')
+
+@@ -913,16 +916,15 @@ class TestLocal(CliTestCase):
+ popen.assert_has_calls([
+ # at the beginning of this list, there are other calls from load_nameverrel
+ call(rpmbuild, stdout=-1, stderr=-2),
+- # I can't match this call - stdin=Mock has it's dynamic id. Therefore any_oreder=True
+- # call(tee, stdin=Mock(), stdout=-1), # check call [-3] separately
+- call().stdout.close(),
+ call().communicate(),
+- ], any_order=True)
++ ], any_order=False)
+
+- tee_call_arg = popen.mock_calls[-3]
++ tee_call_arg = check_call.mock_calls[0]
+ if 'args' in dir(tee_call_arg): # doesn't work in <=py36
+ self.assertEqual(tee, tee_call_arg.args[0])
+
++ system_exit.assert_called_once()
++
+
+ class TestVerifyFiles(CliTestCase):
+
+--
+2.37.2
+
diff --git a/0005-Fixes-for-exploded-SRPM-layouts.patch b/0005-Fixes-for-exploded-SRPM-layouts.patch
new file mode 100644
index 0000000..f2b57b3
--- /dev/null
+++ b/0005-Fixes-for-exploded-SRPM-layouts.patch
@@ -0,0 +1,227 @@
+From fc4dc6882c802e9a8b7ece3101033cb662928adf Mon Sep 17 00:00:00 2001
+From: Troy Dawson <tdawson@redhat.com>
+Date: Fri, 23 Sep 2022 14:38:34 -0700
+Subject: [PATCH 1/2] Fixes for exploded SRPM layouts
+
+sources_filename incorrectly set when using SRPMLayout.
+
+Fixes: #633
+JIRA: RHELCMP-9992
+Merges: https://pagure.io/rpkg/pull-request/634
+
+Signed-off-by: Troy Dawson <tdawson@redhat.com>
+---
+ pyrpkg/__init__.py | 21 +++++++++++----------
+ pyrpkg/cli.py | 2 +-
+ pyrpkg/sources.py | 30 +++++++++++++++++++++++++-----
+ tests/test_cli.py | 2 +-
+ tests/test_sources.py | 33 +++++++++++++++++++++++++++++++++
+ 5 files changed, 71 insertions(+), 17 deletions(-)
+
+diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py
+index 1b6a0c4..a40fa5a 100644
+--- a/pyrpkg/__init__.py
++++ b/pyrpkg/__init__.py
+@@ -1153,7 +1153,8 @@ class Commands(object):
+ def sources_filename(self):
+ if self.layout is None:
+ return os.path.join(self.path, 'sources')
+- return os.path.join(self.path, self.layout.sources_file_template)
++ return os.path.join(
++ self.path, self.layout.sources_file_template.replace("{0.repo_name}", self.repo_name))
+
+ @property
+ def osbs_config_filename(self):
+@@ -2163,9 +2164,9 @@ class Commands(object):
+ self.log.info("sources file doesn't exist. Source files download skipped.")
+ return
+
+- # Default to putting the files where the repository is
++ # Default to putting the files in the layout sourcedir
+ if not outdir:
+- outdir = self.path
++ outdir = self.layout.sourcedir
+
+ sourcesf = SourcesFile(self.sources_filename, self.source_entry_type)
+
+@@ -2578,7 +2579,7 @@ class Commands(object):
+ cmd.append('--nocheck')
+ if self.quiet:
+ cmd.append('--quiet')
+- cmd.extend(['-bc', os.path.join(self.path, self.spec)])
++ cmd.extend(['-bc', os.path.join(self.layout.specdir, self.spec)])
+ # Run the command
+ self._run_command(cmd)
+
+@@ -2657,7 +2658,7 @@ class Commands(object):
+ if buildrootdir:
+ cmd.extend(["--define", "_buildrootdir {0}".format(
+ os.path.abspath(buildrootdir))])
+- cmd.extend(['-bi', os.path.join(self.path, self.spec)])
++ cmd.extend(['-bi', os.path.join(self.layout.specdir, self.spec)])
+ # Run the command
+ self._run_command(cmd)
+ return
+@@ -2798,7 +2799,7 @@ class Commands(object):
+ if not hashtype == 'sha256':
+ cmd.extend(["--define", "_source_filedigest_algorithm %s" % hashtype,
+ "--define", "_binary_filedigest_algorithm %s" % hashtype])
+- specpath = os.path.join(self.path, self.spec)
++ specpath = os.path.join(self.layout.specdir, self.spec)
+ tmpdir = None
+ try:
+ if not self.uses_rpmautospec or not rpmautospec_process_distgit:
+@@ -3180,7 +3181,7 @@ class Commands(object):
+ if buildrootdir:
+ cmd.extend(["--define", "_buildrootdir {0}".format(
+ os.path.abspath(buildrootdir))])
+- cmd.extend(['--nodeps', '-bp', os.path.join(self.path, self.spec)])
++ cmd.extend(['--nodeps', '-bp', os.path.join(self.layout.specdir, self.spec)])
+ # Run the command
+ self._run_command(cmd)
+
+@@ -3238,7 +3239,7 @@ class Commands(object):
+ if not hashtype == 'sha256':
+ cmd.extend(["--define", "_source_filedigest_algorithm %s" % hashtype,
+ "--define", "_binary_filedigest_algorithm %s" % hashtype])
+- specpath = os.path.join(self.path, self.spec)
++ specpath = os.path.join(self.layout.specdir, self.spec)
+ tmpdir = None
+ try:
+ if not self.uses_rpmautospec or not rpmautospec_process_distgit:
+@@ -3262,7 +3263,7 @@ class Commands(object):
+ # Create a list for unused patches
+ unused = []
+ # Get the content of spec into memory for fast searching
+- with open(os.path.join(self.path, self.spec), 'r') as f:
++ with open(os.path.join(self.layout.specdir, self.spec), 'r') as f:
+ data = f.read()
+ if six.PY2:
+ try:
+@@ -3340,7 +3341,7 @@ class Commands(object):
+ if buildrootdir:
+ cmd.extend(["--define", "_buildrootdir {0}".format(
+ os.path.abspath(buildrootdir))])
+- cmd.extend(['-bl', os.path.join(self.path, self.spec)])
++ cmd.extend(['-bl', os.path.join(self.layout.specdir, self.spec)])
+ # Run the command
+ self._run_command(cmd)
+
+diff --git a/pyrpkg/cli.py b/pyrpkg/cli.py
+index 9694f14..b0a16fb 100644
+--- a/pyrpkg/cli.py
++++ b/pyrpkg/cli.py
+@@ -1484,7 +1484,7 @@ class cliClient(object):
+ 'sources', help='Download source files',
+ description='Download source files')
+ sources_parser.add_argument(
+- '--outdir', default=os.curdir,
++ '--outdir',
+ help='Directory to download files into (defaults to pwd)')
+ sources_parser.set_defaults(command=self.sources)
+
+diff --git a/pyrpkg/sources.py b/pyrpkg/sources.py
+index 858461d..cdd5275 100644
+--- a/pyrpkg/sources.py
++++ b/pyrpkg/sources.py
+@@ -67,15 +67,35 @@ class SourcesFile(object):
+ return self.entry_type(m.group('hashtype'), m.group('file'),
+ m.group('hash'))
+
+- # Try falling back on the old format
++ # Try falling back on the old Fedora format
+ try:
+ hash, file = stripped.split(' ', 1)
+
+ except ValueError:
+- raise MalformedLineError(
+- 'sources has invalid content: {0}\n'
+- 'Please note that sources file must not be modified manually.'
+- .format(stripped))
++ # Try old Centos Format
++ try:
++ hash, file_path = stripped.split(' ', 1)
++ if len(hash) == 128:
++ hashtype = 'sha512'
++ elif len(hash) == 64:
++ hashtype = 'sha256'
++ elif len(hash) == 40:
++ hashtype = 'sha1'
++ elif len(hash) == 32:
++ hashtype = 'md5'
++ else:
++ raise MalformedLineError(
++ 'sources has invalid content: {0}\n'
++ 'Please note that sources file must not be modified manually.'
++ .format(stripped))
++ file = os.path.split(file_path)[1]
++ return self.entry_type(hashtype, file, hash)
++
++ except ValueError:
++ raise MalformedLineError(
++ 'sources has invalid content: {0}\n'
++ 'Please note that sources file must not be modified manually.'
++ .format(stripped))
+
+ return self.entry_type('md5', file, hash)
+
+diff --git a/tests/test_cli.py b/tests/test_cli.py
+index 97ae0ce..dd1399a 100644
+--- a/tests/test_cli.py
++++ b/tests/test_cli.py
+@@ -1579,7 +1579,7 @@ class TestSources(LookasideCacheMock, CliTestCase):
+ # NOTE: without --outdir, whatever to run sources command in package
+ # repository, sources file is downloaded into current working
+ # directory. Is this a bug, or need to improve?
+- self.assertTrue(os.path.exists('readme.patch'))
++ self.assertTrue(os.path.exists(os.path.join(self.cloned_repo_path, 'readme.patch')))
+
+ def test_sources_to_outdir(self):
+ cli_cmd = ['rpkg', '--path', self.cloned_repo_path,
+diff --git a/tests/test_sources.py b/tests/test_sources.py
+index cfacc51..f041373 100644
+--- a/tests/test_sources.py
++++ b/tests/test_sources.py
+@@ -66,6 +66,39 @@ class SourcesFileTestCase(unittest.TestCase):
+ self.assertEqual(entry.file, 'afile')
+ self.assertEqual(str(entry), newline)
+
++ def test_parse_old_style_centos_line(self):
++ s = sources.SourcesFile(self.sourcesfile, 'old')
++
++ my_hash = 'abababab01010101010101010101010101010101'
++ my_file = 'SUBDIR/afile'
++
++ line = '{0} {1}\n'.format(my_hash, my_file)
++ newline = '{0} {1}\n'.format(my_hash, 'afile')
++ entry = s.parse_line(line)
++
++ self.assertTrue(isinstance(entry, sources.SourceFileEntry))
++ self.assertEqual(entry.hashtype, 'sha1')
++ self.assertEqual(entry.hash, my_hash)
++ self.assertEqual(entry.file, 'afile')
++ self.assertEqual(str(entry), newline)
++
++ def test_migrate_old_style_centos_line(self):
++ s = sources.SourcesFile(self.sourcesfile, 'bsd')
++
++ my_hash = 128 * 'x'
++ my_file = 'SUBDIR/afile'
++
++ line = '{0} {1}\n'.format(my_hash, my_file)
++ newline = '{0} {1}\n'.format(my_hash, 'afile')
++ newline = 'SHA512 (afile) = {0}\n'.format(my_hash)
++ entry = s.parse_line(line)
++
++ self.assertTrue(isinstance(entry, sources.SourceFileEntry))
++ self.assertEqual(entry.hashtype, 'sha512')
++ self.assertEqual(entry.hash, my_hash)
++ self.assertEqual(entry.file, 'afile')
++ self.assertEqual(str(entry), newline)
++
+ def test_parse_entry_line(self):
+ s = sources.SourcesFile(self.sourcesfile, 'bsd')
+
+--
+2.37.3
+
diff --git a/0006-mockbuild-escape-rpm-command-under-mock.patch b/0006-mockbuild-escape-rpm-command-under-mock.patch
new file mode 100644
index 0000000..e0d97e9
--- /dev/null
+++ b/0006-mockbuild-escape-rpm-command-under-mock.patch
@@ -0,0 +1,59 @@
+From 7cefc5fe35a514637b1b0b68e044f0de0d188e22 Mon Sep 17 00:00:00 2001
+From: Ondrej Nosek <onosek@redhat.com>
+Date: Wed, 5 Oct 2022 03:45:22 +0200
+Subject: [PATCH 2/2] mockbuild: escape rpm command under mock
+
+Arguments of the 'rpm' part after 'mock --shell' needs to be escaped.
+Example:
+
+ mock -r xxx --chroot ... --shell rpm --define '_sourcedir xxx' ...
+
+JIRA: RHELCMP-10150
+Resolves: rhbz#2130349
+
+Signed-off-by: Ondrej Nosek <onosek@redhat.com>
+---
+ pyrpkg/__init__.py | 8 ++++++--
+ 1 file changed, 6 insertions(+), 2 deletions(-)
+
+diff --git a/pyrpkg/__init__.py b/pyrpkg/__init__.py
+index a40fa5a..1595344 100644
+--- a/pyrpkg/__init__.py
++++ b/pyrpkg/__init__.py
+@@ -22,6 +22,7 @@ import os
+ import posixpath
+ import random
+ import re
++import shlex
+ import shutil
+ import subprocess
+ import sys
+@@ -43,13 +44,14 @@ from six.moves.urllib.parse import urljoin
+
+ from pyrpkg import layout
+ from pyrpkg.errors import (AlreadyUploadedError, HashtypeMixingError,
+- UnknownTargetError, rpkgAuthError, rpkgError, NoSourcesError)
++ NoSourcesError, UnknownTargetError, rpkgAuthError,
++ rpkgError)
+ from pyrpkg.lookaside import CGILookasideCache
+ from pyrpkg.sources import SourcesFile
+ from pyrpkg.spec import SpecFile
+ from pyrpkg.utils import (cached_property, extract_srpm, find_me,
+ is_file_tracked, is_lookaside_eligible_file,
+- spec_file_processed_by_rpmautospec, log_result)
++ log_result, spec_file_processed_by_rpmautospec)
+
+ from .gitignore import GitIgnore
+
+@@ -813,6 +815,8 @@ class Commands(object):
+ # listing for each subpackage. We only care about the first.
+ rpm_cmd.extend(["-q", "--qf", "??%{NAME} %{EPOCH} %{VERSION} %{RELEASE}??",
+ "--specfile", "%s" % os.path.join(tmp_root, self.spec)])
++ # escape whole 'rpm' command because it will be executed under mock command
++ rpm_cmd = [shlex.quote(item) for item in rpm_cmd]
+ main_cmd = cmd + ['--shell'] + rpm_cmd \
+ + ['> ' + os.path.join(tmp_root, 'output')]
+
+--
+2.37.3
+
diff --git a/remove-koji-and-rpm-py-installer-from-requires.patch b/remove-koji-and-rpm-py-installer-from-requires.patch
new file mode 100644
index 0000000..90adee0
--- /dev/null
+++ b/remove-koji-and-rpm-py-installer-from-requires.patch
@@ -0,0 +1,29 @@
+From ec0c8b368fd560b319c6603f35dda803fe4b2e99 Mon Sep 17 00:00:00 2001
+From: Dominik Rumian <drumian@redhat.com>
+Date: Tue, 24 Aug 2021 12:51:17 +0200
+Subject: [PATCH] [PATCH] remove koji and rpm-py-installer from requires
+
+Signed-off-by: Dominik Rumian <drumian@redhat.com>
+---
+ setup.py | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/setup.py b/setup.py
+index 9c6d881..8c92aae 100755
+--- a/setup.py
++++ b/setup.py
+@@ -34,6 +34,11 @@ install_requires, dep_links = read_requirements(pypi_txt)
+ tests_require, test_dep_links = read_requirements(test_pypi_txt)
+ dep_links += test_dep_links
+
++install_requires = [
++ item for item in install_requires
++ if not item.startswith('koji') and not item.startswith('rpm-py-installer')
++]
++
+ readme_rst = os.path.join(setup_py_path, 'README.rst')
+ with open(readme_rst, 'r') as readme:
+ long_description = readme.read().rstrip()
+--
+2.31.1
+
diff --git a/rpkg.rpmlintrc b/rpkg.rpmlintrc
new file mode 100644
index 0000000..e97a469
--- /dev/null
+++ b/rpkg.rpmlintrc
@@ -0,0 +1,6 @@
+from Config import *
+
+addFilter('/usr/share/rpkg/examples/cli/')
+addFilter("no-signature")
+addFilter("no-group-tag")
+addFilter("non-executable-script")
diff --git a/rpkg.spec b/rpkg.spec
new file mode 100644
index 0000000..65ae79d
--- /dev/null
+++ b/rpkg.spec
@@ -0,0 +1,139 @@
+Name: rpkg
+Version: 1.65
+Release: 1
+
+Summary: Python library for interacting with rpm+git
+License: GPLv2+ and LGPLv2
+URL: https://pagure.io/rpkg
+BuildArch: noarch
+Source0: https://pagure.io/releases/rpkg/%{name}-%{version}.tar.gz
+Source1: rpkg.rpmlintrc
+
+# This is intended for Python 3 only, hence also no Python version in the name.
+%global __pytest /usr/bin/pytest%(test %{python3_pkgversion} == 3 || echo -%{python3_version})
+%global pytest %{expand:\\\
+ CFLAGS="${CFLAGS:-${RPM_OPT_FLAGS}}" LDFLAGS="${LDFLAGS:-${RPM_LD_FLAGS}}"\\\
+ PATH="%{buildroot}%{_bindir}:$PATH"\\\
+ PYTHONPATH="${PYTHONPATH:-%{buildroot}%{python3_sitearch}:%{buildroot}%{python3_sitelib}}"\\\
+ PYTHONDONTWRITEBYTECODE=1\\\
+ %{?__pytest_addopts:PYTEST_ADDOPTS="${PYTEST_ADDOPTS:-} %{__pytest_addopts}"}\\\
+ %__pytest}
+
+# Fix for bug 1579367
+# Due to https://pagure.io/koji/issue/912, python[23]-koji package does not
+# have egginfo.
+# rpm-py-installer is required as a proxy to install RPM python binding
+# library, so rpm is the actual requirement that must be present in the
+# requires.txt. But, rpkg has to work in all active Fedora and EPEL releases,
+# 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-Do-not-use-pytest-related-dependencies-temporarily.patch
+Patch2: 0002-Remove-pytest-coverage-execution.patch
+Patch4: 0004-fedpkg-local-does-not-show-rpmbuild-output.patch
+Patch5: 0005-Fixes-for-exploded-SRPM-layouts.patch
+Patch6: 0006-mockbuild-escape-rpm-command-under-mock.patch
+
+%description
+Python library for interacting with rpm+git
+
+%package -n python3-%{name}
+Summary: %{summary}
+
+BuildRequires: python3-devel
+BuildRequires: python3-GitPython
+BuildRequires: python3-koji >= 1.24
+BuildRequires: python3-libmodulemd
+BuildRequires: python3-argcomplete
+BuildRequires: python3-CCColUtils
+BuildRequires: python3-openidc-client
+BuildRequires: python3-pycurl
+BuildRequires: python3-six >= 1.9.0
+BuildRequires: python3-requests
+BuildRequires: python3-setuptools
+BuildRequires: python3-pytest
+BuildRequires: python3-PyYAML
+BuildRequires: rpmdevtools
+BuildRequires: git-core
+
+Requires: mock
+Requires: openEuler-rpm-config
+Requires: rpm-build
+Requires: rpmlint
+Requires: rpmdevtools
+
+Requires: python3-argcomplete
+Requires: python3-GitPython >= 0.2.0
+Requires: python3-CCColUtils
+Requires: python3-koji >= 1.24
+Requires: python3-libmodulemd
+Requires: python3-rpmautospec
+Requires: python3-rpm
+Requires: python3-pycurl
+Requires: python3-six >= 1.9.0
+Requires: python3-PyYAML
+
+Requires: %{name}-common = %{version}-%{release}
+
+
+%description -n python3-%{name}
+A python library for managing RPM package sources in a git repository.
+
+%package common
+Summary: Common files for %{name}
+
+# Files were moved from python2-rpkg in that version
+Conflicts: python2-rpkg < 1.52-2
+Conflicts: pyrpkg < 1.52-2
+
+%description common
+Common files for python2-%{name} and python3-%{name}.
+
+
+%prep
+%autosetup -p1
+
+# Removes section from setup.py that is relevant only for pip and
+# is not compatible with in RHEL-6 tools
+sed -i -n '/extras_require/,/}/!p' setup.py
+
+%build
+%py3_build
+
+
+%install
+%py3_install
+
+# Create configuration directory to holding downstream clients config files
+# that are built on top of rpkg
+%{__install} -d $RPM_BUILD_ROOT%{_sysconfdir}/rpkg
+
+example_cli_dir=$RPM_BUILD_ROOT%{_datadir}/%{name}/examples/cli
+%{__install} -d $example_cli_dir
+
+# Install example CLI to rpkg own data directory
+%{__install} -d ${example_cli_dir}%{_bindir}
+%{__install} -d ${example_cli_dir}%{_sysconfdir}/bash_completion.d
+%{__install} -d ${example_cli_dir}%{_sysconfdir}/rpkg
+
+%{__install} -p -m 0644 bin/rpkg ${example_cli_dir}%{_bindir}
+%{__install} -p -m 0644 etc/bash_completion.d/rpkg.bash ${example_cli_dir}%{_sysconfdir}/bash_completion.d
+%{__install} -p -m 0644 etc/rpkg/rpkg.conf ${example_cli_dir}%{_sysconfdir}/rpkg
+
+# need to run check as non-root
+%check
+%pytest
+
+%files -n python3-%{name}
+%doc README.rst CHANGELOG.rst
+%license COPYING COPYING-koji LGPL
+%{python3_sitelib}/pyrpkg
+%{python3_sitelib}/%{name}-%{version}-py*.egg-info
+
+%files common
+%{_datadir}/%{name}
+%{_sysconfdir}/rpkg
+
+%changelog
+* Fri Mar 24 2023 lichaoran <pkwarcraft@hotmail.com> - 1.65-1
+- Initial package
diff --git a/sources b/sources
new file mode 100644
index 0000000..077e667
--- /dev/null
+++ b/sources
@@ -0,0 +1 @@
+c863a3a59686ee280eb686ede22b5747 rpkg-1.65.tar.gz