diff --git a/0002-rpmdevtools-git-83b35ac.patch b/0002-rpmdevtools-git-83b35ac.patch deleted file mode 100644 index ff616da..0000000 --- a/0002-rpmdevtools-git-83b35ac.patch +++ /dev/null @@ -1,531 +0,0 @@ -diff --git a/Makefile.am b/Makefile.am -index bb6f7c6..d55f397 100644 ---- a/Makefile.am -+++ b/Makefile.am -@@ -15,7 +15,7 @@ man8_MANS = rpmdev-rmdevelrpms.8 - dist_pkgsysconf_DATA = curlrc newspec.conf rmdevelrpms.conf \ - spectemplate-lib.spec spectemplate-minimal.spec \ - spectemplate-perl.spec spectemplate-php-pear.spec \ -- spectemplate-python.spec spectemplate-ruby.spec \ -+ spectemplate-python.spec spectemplate-pyproject.spec spectemplate-ruby.spec \ - spectemplate-ocaml.spec spectemplate-R.spec spectemplate-dummy.spec \ - template.init - -diff --git a/rpmdev-bumpspec b/rpmdev-bumpspec -index b8f4047..5a6a909 100755 ---- a/rpmdev-bumpspec -+++ b/rpmdev-bumpspec -@@ -27,8 +27,10 @@ import time - - try: - from rpmautospec import specfile_uses_rpmautospec -+ from rpmautospec.subcommands.release import calculate_release_number - except ImportError: - specfile_uses_rpmautospec = None -+ calculate_release_number = None - - __version__ = "1.0.13" - -@@ -378,19 +380,25 @@ the Free Software Foundation; either version 2 of the License, or - # Not actually a parser error, but... meh. - parser.error(e) - -- uses_rpmautospec = False -+ uses_rpmautospec_autorelease = uses_rpmautospec_autochangelog = False - if specfile_uses_rpmautospec: -- uses_rpmautospec = specfile_uses_rpmautospec( -+ uses_rpmautospec_autorelease = specfile_uses_rpmautospec( - specpath=s.filename, - check_autorelease=True, - check_autochangelog=False - ) -+ uses_rpmautospec_autochangelog = specfile_uses_rpmautospec( -+ specpath=s.filename, -+ check_autorelease=False, -+ check_autochangelog=True -+ ) - -- if uses_rpmautospec: -+ changed = False -+ if uses_rpmautospec_autorelease: - if opts.new: - print("RPMAutoSpec usage detected, only setting Version.") - changed = s.newVersion(opts.new, set_release=False) -- else: -+ elif uses_rpmautospec_autochangelog: - print("RPMAutoSpec usage detected, not changing the spec file.") - continue - else: -@@ -405,14 +413,12 @@ the Free Software Foundation; either version 2 of the License, or - - changed = True - -- # If we didn't change anything, no need to write and modify the -- # changelog. - if changed: -+ # Write out changed version or release if changed. - s.writeFile(aspec) -- else: -- continue - -- if uses_rpmautospec: -+ if uses_rpmautospec_autochangelog: -+ print("RPMAutospec %autochangelog is used, no need to add %changelog entry.") - continue - - if not s.checkChangelogPresence(): -@@ -422,6 +428,10 @@ the Free Software Foundation; either version 2 of the License, or - # Get EVR for changelog entry. - cmd = ("rpm", "-q", "--specfile", "--define", "dist %{nil}", - "--qf=%|epoch?{%{epoch}:}:{}|%{version}-%{release}\n", aspec) -+ if not opts.new and calculate_release_number and uses_rpmautospec_autorelease: -+ # Rpmautospec doesn’t see a change yet so the calculated number will be one too low. -+ release_number = calculate_release_number(aspec) + 1 -+ cmd += ("--define", "_rpmautospec_release_number {}".format(release_number)) - popen = subprocess.Popen(cmd, stdout=subprocess.PIPE) - evr = popen.communicate()[0].split(b"\n")[0] - if sys.version_info[0] > 2: -diff --git a/rpmdev-spectool b/rpmdev-spectool -index 1d57256..2c06ef8 100755 ---- a/rpmdev-spectool -+++ b/rpmdev-spectool -@@ -25,7 +25,9 @@ import os - import tempfile - import time - from collections import OrderedDict --from typing import Optional -+from typing import Any, Callable, Dict, List, Optional -+from typing import OrderedDict as OrderedDictT -+from typing import Tuple - from urllib.parse import urlparse - - import progressbar -@@ -46,13 +48,13 @@ anything about missing sources or patches). The plan is to catch errors like - this in spectool itself and warn the user about it in the future.""" - - --def complete_spec_paths(prefix, **kwargs): -+def complete_spec_paths(prefix, **kwargs) -> List[str]: - import glob - - return glob.glob(prefix + "*.spec") - - --def get_args() -> dict: -+def get_args() -> Dict[str, Any]: - try: - import argcomplete - except ImportError: -@@ -191,6 +193,15 @@ def get_args() -> dict: - help="output debug info, don't clean up when done", - ) - -+ misc.add_argument( -+ "--http-header", -+ "-H", -+ action="append", -+ dest="headers", -+ default=[], -+ help="Optionally add custom headers", -+ ) -+ - specfile = parser.add_argument("specfile", action="store") - - if argcomplete: -@@ -202,17 +213,17 @@ def get_args() -> dict: - return vars(parser.parse_args()) - - --def split_numbers(args: str) -> list: -+def split_numbers(args: str) -> List[str]: - return args.split(",") - - - # simple streamed file download progress tracker inspired by requests_download - class ProgressTracker: -- def __init__(self, progress_bar: progressbar.ProgressBar): -+ def __init__(self, progress_bar: progressbar.ProgressBar) -> None: - self.progress_bar = progress_bar - self.received = 0 - -- def on_start(self, response: requests.Response): -+ def on_start(self, response: requests.Response) -> None: - max_value = None - - if "content-length" in response.headers: -@@ -221,7 +232,7 @@ class ProgressTracker: - self.progress_bar.start(max_value=max_value) - self.received = 0 - -- def on_chunk(self, chunk: bytes): -+ def on_chunk(self, chunk: bytes) -> None: - self.received += len(chunk) - - try: -@@ -229,12 +240,13 @@ class ProgressTracker: - except ValueError: - pass - -- def on_finish(self): -+ def on_finish(self) -> None: - self.progress_bar.finish() - - - # simple streamed file download implementation inspired by requests_download --def download(url, target, headers=None, tracker: Optional[ProgressTracker] = None): -+def download(url, target, headers=None, -+ tracker: Optional[ProgressTracker] = None) -> None: - if headers is None: - headers = {} - -@@ -263,7 +275,8 @@ def download(url, target, headers=None, tracker: Optional[ProgressTracker] = Non - tracker.on_finish() - - --def get_file(url: str, path: str, force: bool) -> bool: -+def get_file(url: str, path: str, force: bool, -+ headers: Optional[Dict[str, str]] = None) -> bool: - if os.path.exists(path): - if force: - os.remove(path) -@@ -272,13 +285,13 @@ def get_file(url: str, path: str, force: bool) -> bool: - return False - - progress = ProgressTracker(progressbar.DataTransferBar()) -- download(url, path, tracker=progress) -+ download(url, path, tracker=progress, headers=headers) - - return True - - - class Spec: -- def __init__(self, path: str): -+ def __init__(self, path: str) -> None: - self.path = path - self.spec = rpm.spec(self.path) - -@@ -289,10 +302,10 @@ class Spec: - self.files = list(self.spec.sources) - self.files.sort(key=(lambda file: file[1])) - -- self._sources = None -- self._patches = None -+ self._sources: Optional[OrderedDictT[str, str]] = None -+ self._patches: Optional[OrderedDictT[str, str]] = None - -- def _files(self, typ) -> OrderedDict: -+ def _files(self, typ: int) -> OrderedDictT[str, str]: - # file is a 3-tuple of (path, number, type) - # type 1: source file - # type 2: patch file -@@ -305,41 +318,42 @@ class Spec: - return files - - @property -- def sources(self) -> OrderedDict: -+ def sources(self) -> OrderedDictT[str, str]: - if not self._sources: - self._sources = self._files(1) - - return self._sources - - @property -- def patches(self) -> OrderedDict: -+ def patches(self) -> OrderedDictT[str, str]: - if not self._patches: - self._patches = self._files(2) - - return self._patches - -- def print_source(self, number: int, value: str = None): -+ def print_source(self, number: str, value: Optional[str] = None) -> None: - if not value: - value = self.sources[number] - - print("Source{}: {}".format(number, value)) - -- def print_patch(self, number: int, value: str = None): -+ def print_patch(self, number: str, value: Optional[str] = None) -> None: - if not value: - value = self.patches[number] - - print("Patch{}: {}".format(number, value)) - -- def list_sources(self): -+ def list_sources(self) -> None: - for (number, value) in self.sources.items(): - self.print_source(number, value) - -- def list_patches(self): -+ def list_patches(self) -> None: - for (number, value) in self.patches.items(): - self.print_patch(number, value) - - @staticmethod -- def _get_file(value: str, directory: str, force: bool, dry: bool): -+ def _get_file(value: str, directory: str, force: bool, dry: bool, -+ headers: Optional[Dict[str, str]] = None) -> None: - parsed = urlparse(value) - - if "#" not in value: -@@ -354,19 +368,23 @@ class Spec: - return - - if parsed.scheme: -+ if dry: -+ print("Would have downloaded: {}".format(value)) -+ return None - if not dry: - path = os.path.join(directory, basename) - - try: - print("Downloading: {}".format(value)) - os.makedirs(directory, exist_ok=True) -- really = get_file(value, path, force) -+ really = get_file(value, path, force, headers=headers) - if really: - print("Downloaded: {}".format(basename)) - - except IOError as e: - print("Download failed:") - print(e) -+ raise e - - except KeyboardInterrupt: - if os.path.isfile(path): -@@ -376,28 +394,53 @@ class Spec: - print("Download cancelled.") - raise - -- else: -- print("Would have downloaded: {}".format(value)) -- -- def get_source(self, number: int, directory: str, force: bool, dry: bool, value: str = None): -+ def get_source(self, number: str, directory: str, force: bool, dry: bool, -+ value: Optional[str] = None, -+ headers: Optional[Dict[str, str]] = None) -> bool: - if not value: - value = self.sources[number] - -- self._get_file(value, directory, force, dry) -+ try: -+ self._get_file(value, directory, force, dry, headers=headers) -+ return False -+ -+ except IOError: -+ return True - -- def get_patch(self, number: int, directory: str, force: bool, dry: bool, value: str = None): -+ def get_patch(self, number: str, directory: str, force: bool, dry: bool, -+ value: Optional[str] = None, -+ headers: Optional[Dict[str, str]] = None) -> bool: - if not value: - value = self.patches[number] - -- self._get_file(value, directory, force, dry) -+ try: -+ self._get_file(value, directory, force, dry, headers=headers) -+ return False -+ -+ except IOError: -+ return True -+ -+ def get_sources(self, directory: str, force: bool, dry: bool, -+ headers: Optional[Dict[str, str]] = None): -+ failure = False - -- def get_sources(self, directory: str, force: bool, dry: bool): - for number, value in self.sources.items(): -- self.get_source(number, directory, force, dry, value) -+ if self.get_source(number, directory, force, dry, value, -+ headers=headers): -+ failure = True -+ -+ return failure -+ -+ def get_patches(self, directory: str, force: bool, dry: bool, -+ headers: Optional[Dict[str, str]] = None): -+ failure = False - -- def get_patches(self, directory: str, force: bool, dry: bool): - for number, value in self.patches.items(): -- self.get_patch(number, directory, force, dry, value) -+ if self.get_patch(number, directory, force, dry, value, -+ headers=headers): -+ failure = True -+ -+ return failure - - - def main() -> int: -@@ -484,6 +527,10 @@ def main() -> int: - if args["get_files"]: - force = args["force"] - dry = args["dry_run"] -+ headers = {} -+ for header in args["headers"]: -+ k, sep, v = header.partition(':') -+ headers[k.strip()] = v.strip() - - if args["directory"] and args["sourcedir"]: - print("Conflicting requests for download directory.") -@@ -496,18 +543,21 @@ def main() -> int: - else: - directory = os.getcwd() - -+ tasks: List[Tuple[Callable[..., bool], Tuple[Any, ...]]] = [] -+ - if args["source"]: - numbers = split_numbers(args["source"]) - - for number in numbers: - if number not in spec.sources.keys(): -- print("No patch with number '{}' found.".format(number)) -+ print("No source with number '{}' found.".format(number)) - continue - -- spec.get_source(number, directory, force, dry) -+ tasks.append((spec.get_source, (number, directory, force, dry, -+ headers))) - - elif args["sources"] and not args["patch"]: -- spec.get_sources(directory, force, dry) -+ tasks.append((spec.get_sources, (directory, force, dry, headers))) - - if args["patch"]: - numbers = split_numbers(args["patch"]) -@@ -517,10 +567,22 @@ def main() -> int: - print("No patch with number '{}' found.".format(number)) - continue - -- spec.get_patch(number, directory, force, dry) -+ tasks.append((spec.get_patch, (number, directory, force, dry, -+ headers))) - - elif args["patches"] and not args["source"]: -- spec.get_patches(directory, force, dry) -+ tasks.append((spec.get_patches, (directory, force, dry, headers))) -+ -+ failure = False -+ -+ for task, fargs in tasks: -+ fail = task(*fargs) -+ -+ if fail: -+ failure = True -+ -+ if failure: -+ return 1 - - return 0 - -diff --git a/spectemplate-cmake.spec b/spectemplate-cmake.spec -new file mode 100644 -index 0000000..0cdcbb8 ---- /dev/null -+++ b/spectemplate-cmake.spec -@@ -0,0 +1,38 @@ -+Name: -+Version: -+Release: 1%{?dist} -+Summary: -+ -+License: -+URL: -+Source0: -+ -+BuildRequires: cmake -+ -+%description -+%{summary}. -+ -+ -+%prep -+%autosetup -q -+ -+ -+%build -+%cmake -+%cmake_build -+ -+ -+%install -+%cmake_install -+ -+ -+%check -+%ctest -+ -+ -+%files -+%license add-license-file-here -+%doc add-docs-here -+ -+ -+%changelog -diff --git a/spectemplate-pyproject.spec b/spectemplate-pyproject.spec -new file mode 100644 -index 0000000..15d5a65 ---- /dev/null -+++ b/spectemplate-pyproject.spec -@@ -0,0 +1,60 @@ -+Name: python-... -+Version: ... -+Release: 1%{?dist} -+Summary: ... -+ -+License: ... -+URL: https://... -+# use a source from git forge or PyPI: -+Source: %{url}/archive/v%{version}/...-%{version}.tar.gz / %{pypi_source ...} -+ -+# for pure Python packages: -+BuildArch: noarch -+# for packages with extension modules: -+BuildRequires: gcc -+ -+BuildRequires: python3-devel -+ -+%global _description %{expand: -+...} -+ -+%description %_description -+ -+%package -n python3-... -+Summary: %{summary} -+ -+%description -n python3-... %_description -+ -+ -+%prep -+%autosetup -p1 -n ...-%{version} -+ -+ -+%generate_buildrequires -+# use the appropriate flags to get all test dependencies: -+%pyproject_buildrequires -x... / -t -+ -+ -+%build -+%pyproject_wheel -+ -+ -+%install -+%pyproject_install -+# list the installed top-level Python module names: -+%pyproject_save_files ... -+ -+ -+%check -+# testing the package is mandatory, at least somehow: -+%tox / %pytest / %pyproject_check_import ... -+ -+ -+%files -n python3-... -f %{pyproject_files} -+%doc README.* -+# only add LICENSE / COPYING if not included in %%{pyproject_files} -+%license LICENSE / COPYING -+%{_bindir}/... -+ -+ -+%changelog diff --git a/rpmdevtools.spec b/rpmdevtools.spec index 86879d9..a07688a 100644 --- a/rpmdevtools.spec +++ b/rpmdevtools.spec @@ -1,6 +1,6 @@ Name: rpmdevtools Version: 9.6 -Release: 13%{?dist} +Release: 7%{?dist} Summary: RPM Development Tools # rpmdev-md5 and rpmdev-setuptree are GPL-2.0-only, @@ -132,24 +132,6 @@ cp %{SOURCE1} %{buildroot}%{_datadir}/rpmdevtools/ %changelog -* Sat Aug 09 2025 Fabio Valentini - 9.6-13 -- Revert to last stable release - -* Mon Aug 04 2025 Mark Wielaard - 9.6-12.git83b35ac -- Add BuildRequires for autoreconf, fixes rhbz#2385580 - -* Fri Jul 25 2025 Fedora Release Engineering - 9.6-11.git83b35ac -- Rebuilt for https://fedoraproject.org/wiki/Fedora_43_Mass_Rebuild - -* Thu Jan 23 2025 Jens Petersen - 9.6-10.git83b35ac -- update to latest git 83b35ac changes - -* Sat Jan 18 2025 Fedora Release Engineering - 9.6-9 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_42_Mass_Rebuild - -* Fri Jul 19 2024 Fedora Release Engineering - 9.6-8 -- Rebuilt for https://fedoraproject.org/wiki/Fedora_41_Mass_Rebuild - * Fri Jan 26 2024 Fedora Release Engineering - 9.6-7 - Rebuilt for https://fedoraproject.org/wiki/Fedora_40_Mass_Rebuild