Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package python-specfile for openSUSE:Factory checked in at 2024-07-09 20:06:02 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/python-specfile (Old) and /work/SRC/openSUSE:Factory/.python-specfile.new.2080 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-specfile" Tue Jul 9 20:06:02 2024 rev:22 rq:1186413 version:0.31.0 Changes: -------- --- /work/SRC/openSUSE:Factory/python-specfile/python-specfile.changes 2024-06-10 17:38:23.172624231 +0200 +++ /work/SRC/openSUSE:Factory/.python-specfile.new.2080/python-specfile.changes 2024-07-09 20:06:36.858434486 +0200 @@ -1,0 +2,16 @@ +Fri Jul 5 13:06:52 UTC 2024 - Joshua Smith <smolsh...@opensuse.org> + +- Add typing_extensions to BuildRequires +- Remove typing_extensions from Requires -- gh#packit/specfile#179 +- Update to 0.31.0: + * Value of a Tag no longer includes trailing whitespace (if any) + * specfile now tries to expand macros before processing + conditions to be able to resolve conditional expressions + defined by macros, for example OpenSUSE Tumbleweed defines + %ifpython3 macro as %if "%{python_flavor}" == "python3" +- Updates from 0.30.0: + * Fixed an exception that occured when accessing the + Specfile.has_autochangelog property while having unparseable + lines (e.g. lines ending with unescaped %) in %changelog + +------------------------------------------------------------------- Old: ---- specfile-0.29.0.tar.gz New: ---- specfile-0.31.0.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ python-specfile.spec ++++++ --- /var/tmp/diff_new_pack.GV2XZJ/_old 2024-07-09 20:06:37.910472820 +0200 +++ /var/tmp/diff_new_pack.GV2XZJ/_new 2024-07-09 20:06:37.914472966 +0200 @@ -17,7 +17,7 @@ Name: python-specfile -Version: 0.29.0 +Version: 0.31.0 Release: 0 Summary: A library for parsing and manipulating RPM spec files License: MIT @@ -30,12 +30,12 @@ BuildRequires: fdupes BuildRequires: python-rpm-macros Requires: python-rpm -Requires: python-typing_extensions BuildArch: noarch # SECTION test requirements BuildRequires: %{python_module flexmock} BuildRequires: %{python_module pytest} BuildRequires: %{python_module rpm} +BuildRequires: %{python_module typing_extensions} BuildRequires: git-core # /SECTION %python_subpackages ++++++ specfile-0.29.0.tar.gz -> specfile-0.31.0.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/.packit.yaml new/specfile-0.31.0/.packit.yaml --- old/specfile-0.29.0/.packit.yaml 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/.packit.yaml 2024-07-04 16:25:42.000000000 +0200 @@ -136,8 +136,19 @@ trigger: pull_request packages: [specfile-epel8] tmt_plan: "smoke|full" + use_internal_tf: true targets: - - epel-8 + epel-8: + distros: [RHEL-8] + # enable EPEL + tf_extra_params: + environments: + - kickstart: + post-install: | + %post --log=/dev/console + set -x + dnf -y install https://dl.fedoraproject.org/pub/epel/epel-release-latest-8.noarch.rpm + %end - job: tests trigger: pull_request diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/CHANGELOG.md new/specfile-0.31.0/CHANGELOG.md --- old/specfile-0.29.0/CHANGELOG.md 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/CHANGELOG.md 2024-07-04 16:25:42.000000000 +0200 @@ -1,3 +1,12 @@ +# 0.31.0 + +- Value of a `Tag` no longer includes trailing whitespace (if any). (#393) +- specfile now tries to expand macros before processing conditions to be able to resolve conditional expressions defined by macros, for example OpenSUSE Tumbleweed defines `%ifpython3` macro as `%if "%{python_flavor}" == "python3"`. (#394) + +# 0.30.0 + +- Fixed an exception that occured when accessing the `Specfile.has_autochangelog` property while having unparseable lines (e.g. lines ending with unescaped `%`) in `%changelog`. (#387) + # 0.29.0 - Improved compatibility with RPM 4.20 (alpha version is currently in Fedora Rawhide). (#380) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/PKG-INFO new/specfile-0.31.0/PKG-INFO --- old/specfile-0.29.0/PKG-INFO 2024-06-06 15:50:10.083419300 +0200 +++ new/specfile-0.31.0/PKG-INFO 2024-07-04 16:25:48.267595300 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: specfile -Version: 0.29.0 +Version: 0.31.0 Summary: A library for parsing and manipulating RPM spec files. Home-page: https://github.com/packit/specfile Author: Red Hat diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/epel8/python-specfile.spec new/specfile-0.31.0/epel8/python-specfile.spec --- old/specfile-0.29.0/epel8/python-specfile.spec 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/epel8/python-specfile.spec 2024-07-04 16:25:42.000000000 +0200 @@ -4,7 +4,7 @@ in a minimal diff.} -%global base_version 0.29.0 +%global base_version 0.31.0 #global prerelease rc1 %global package_version %{base_version}%{?prerelease:~%{prerelease}} @@ -68,6 +68,12 @@ %changelog +* Thu Jul 04 2024 Packit Team <he...@packit.dev> - 0.31.0-1 +- New upstream release 0.31.0 + +* Wed Jun 26 2024 Packit Team <he...@packit.dev> - 0.30.0-1 +- New upstream release 0.30.0 + * Thu Jun 06 2024 Packit Team <he...@packit.dev> - 0.29.0-1 - New upstream release 0.29.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/fedora/python-specfile.spec new/specfile-0.31.0/fedora/python-specfile.spec --- old/specfile-0.29.0/fedora/python-specfile.spec 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/fedora/python-specfile.spec 2024-07-04 16:25:42.000000000 +0200 @@ -7,7 +7,7 @@ in a minimal diff.} -%global base_version 0.29.0 +%global base_version 0.31.0 #global prerelease rc1 %global package_version %{base_version}%{?prerelease:~%{prerelease}} @@ -77,6 +77,12 @@ %changelog +* Thu Jul 04 2024 Packit Team <he...@packit.dev> - 0.31.0-1 +- New upstream release 0.31.0 + +* Wed Jun 26 2024 Packit Team <he...@packit.dev> - 0.30.0-1 +- New upstream release 0.30.0 + * Thu Jun 06 2024 Packit Team <he...@packit.dev> - 0.29.0-1 - New upstream release 0.29.0 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/plans/full.fmf new/specfile-0.31.0/plans/full.fmf --- old/specfile-0.29.0/plans/full.fmf 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/plans/full.fmf 2024-07-04 16:25:42.000000000 +0200 @@ -2,3 +2,9 @@ Unit & integration tests discover+: filter: tier:1 +adjust: + - when: "distro == rhel-8" + because: "only platform-python is installed on RHEL 8 by default" + prepare+: + - how: install + package: python3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/plans/smoke.fmf new/specfile-0.31.0/plans/smoke.fmf --- old/specfile-0.29.0/plans/smoke.fmf 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/plans/smoke.fmf 2024-07-04 16:25:42.000000000 +0200 @@ -2,3 +2,9 @@ Basic smoke test discover+: filter: tier:0 +adjust: + - when: "distro == rhel-8" + because: "only platform-python is installed on RHEL 8 by default" + prepare+: + - how: install + package: python3 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/specfile/conditions.py new/specfile-0.31.0/specfile/conditions.py --- old/specfile-0.29.0/specfile/conditions.py 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/specfile/conditions.py 2024-07-04 16:25:42.000000000 +0200 @@ -50,11 +50,11 @@ return True elif keyword.endswith("arch"): target_cpu = expand("%{_target_cpu}") - match = any(t for t in expression.split() if t == target_cpu) + match = any(t for t in expand(expression).split() if t == target_cpu) return not match if keyword == "%ifnarch" else match elif keyword.endswith("os"): target_os = expand("%{_target_os}") - match = any(t for t in expression.split() if t == target_os) + match = any(t for t in expand(expression).split() if t == target_os) return not match if keyword == "%ifnos" else match return False @@ -78,6 +78,15 @@ Returns: List of tuples in the form of (line, validity). """ + + def expand(s): + if not context: + return Macros.expand(s) + result = context.expand(s, skip_parsing=getattr(expand, "skip_parsing", False)) + # parse only once + expand.skip_parsing = True + return result + excluded_lines = [] if macro_definitions: for md in macro_definitions: @@ -110,7 +119,12 @@ if any(index in r for r in excluded_lines): result.append((line, branches[-1])) continue - m = condition_regex.match(line) + try: + expanded_line = expand(line) + except RPMException: + # ignore failed expansion and use the original line + expanded_line = line + m = condition_regex.match(expanded_line) if not m: result.append((line, branches[-1])) continue diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/specfile/prep.py new/specfile-0.31.0/specfile/prep.py --- old/specfile-0.29.0/specfile/prep.py 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/specfile/prep.py 2024-07-04 16:25:42.000000000 +0200 @@ -112,7 +112,7 @@ @property def number(self) -> int: """Number of the %patch macro.""" - tokens = re.split(r"(\d+)", self.name, maxsplit=1) + tokens = re.split(r"(\d+)$", self.name, maxsplit=1) if len(tokens) > 1: return int(tokens[1]) if self.options.P is not None: @@ -123,7 +123,7 @@ @number.setter def number(self, value: int) -> None: - tokens = re.split(r"(\d+)", self.name, maxsplit=1) + tokens = re.split(r"(\d+)$", self.name, maxsplit=1) if len(tokens) > 1: self.name = f"{tokens[0]}{value}" elif self.options.P is not None: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/specfile/sources.py new/specfile-0.31.0/specfile/sources.py --- old/specfile-0.29.0/specfile/sources.py 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/specfile/sources.py 2024-07-04 16:25:42.000000000 +0200 @@ -104,7 +104,7 @@ Returns: Extracted number or `None` if there isn't one. """ - tokens = re.split(r"(\d+)", self._tag.name, maxsplit=1) + tokens = re.split(r"(\d+)$", self._tag.name, maxsplit=1) if len(tokens) > 1: return tokens[1] return None diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/specfile/specfile.py new/specfile-0.31.0/specfile/specfile.py --- old/specfile-0.29.0/specfile/specfile.py 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/specfile/specfile.py 2024-07-04 16:25:42.000000000 +0200 @@ -12,7 +12,11 @@ from specfile.changelog import Changelog, ChangelogEntry, guess_packager from specfile.context_management import ContextManager -from specfile.exceptions import SourceNumberException, SpecfileException +from specfile.exceptions import ( + SourceNumberException, + SpecfileException, + UnterminatedMacroException, +) from specfile.formatter import formatted from specfile.macro_definitions import ( CommentOutStyle, @@ -28,6 +32,7 @@ from specfile.tags import Tag, Tags from specfile.value_parser import ( SUBSTITUTION_GROUP_PREFIX, + ConditionalMacroExpansion, EnclosedMacroSubstitution, MacroSubstitution, ValueParser, @@ -433,12 +438,16 @@ if line.lstrip().startswith("#"): # skip comments continue - for node in ValueParser.flatten(ValueParser.parse(line)): - if ( - isinstance(node, (MacroSubstitution, EnclosedMacroSubstitution)) - and node.name == "autochangelog" - ): - return True + try: + for node in ValueParser.flatten(ValueParser.parse(line)): + if ( + isinstance(node, (MacroSubstitution, EnclosedMacroSubstitution)) + and node.name == "autochangelog" + ): + return True + except UnterminatedMacroException: + # ignore unparseable lines + continue return False @property @@ -766,7 +775,35 @@ ) entities.sort(key=lambda e: e.position) + def find_reference(entity, value): + def traverse(nodes): + for node in nodes: + if isinstance( + node, + ( + MacroSubstitution, + EnclosedMacroSubstitution, + ConditionalMacroExpansion, + ), + ): + if ( + entity.type == Tag + and entity.name == node.name.lower() + or entity.name == node.name + ): + return True + if isinstance(node, ConditionalMacroExpansion): + if traverse(node.body): + return True + return False + + return traverse(ValueParser.parse(value)) + def update(value, requested_value, position): + if value == requested_value: + # nothing to do + return requested_value + modifiable_entities = { e.name for e in entities @@ -814,6 +851,9 @@ if entity.locked: # avoid infinite recursion return requested_value + if find_reference(entity, val): + # avoid updating entity value if the entity is referenced from the new value + return requested_value entity.locked = True try: entity.value = update(entity.value, val, entity.position) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/specfile/tags.py new/specfile-0.31.0/specfile/tags.py --- old/specfile-0.29.0/specfile/tags.py 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/specfile/tags.py 2024-07-04 16:25:42.000000000 +0200 @@ -499,6 +499,10 @@ data = [] buffer: List[str] = [] for line, valid in lines: + ws = "" + tokens = re.split(r"([^\S\n]+)$", line, maxsplit=1) + if len(tokens) > 1: + line, ws, _ = tokens line, prefix, suffix = split_conditional_macro_expansion(line) # find out if there is a match for one of the tag regexes m = next((m for m in (r.match(line) for r in tag_regexes) if m), None) @@ -511,13 +515,13 @@ Comments.parse(buffer), valid, prefix, - suffix, + suffix + ws, context, ) ) buffer = [] else: - buffer.append(prefix + line + suffix) + buffer.append(prefix + line + suffix + ws) return cls(data, buffer) def get_raw_section_data(self) -> List[str]: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/specfile/value_parser.py new/specfile-0.31.0/specfile/value_parser.py --- old/specfile-0.29.0/specfile/value_parser.py 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/specfile/value_parser.py 2024-07-04 16:25:42.000000000 +0200 @@ -74,7 +74,7 @@ """Node representing macro substitution, e.g. _%version_.""" def __init__(self, body: str) -> None: - tokens = re.split(r"([?!]*)", body, maxsplit=1) + tokens = re.split(r"^([?!]*)", body, maxsplit=1) if len(tokens) == 1: self.prefix, self.name = "", tokens[0] else: @@ -97,7 +97,7 @@ """Node representing macro substitution enclosed in brackets, e.g. _%{?dist}_.""" def __init__(self, body: str) -> None: - tokens = re.split(r"([?!]*)", body, maxsplit=1) + tokens = re.split(r"^([?!]*)", body, maxsplit=1) if len(tokens) == 1: self.prefix, rest = "", tokens[0] else: @@ -129,7 +129,7 @@ """Node representing conditional macro expansion, e.g. _%{?prerel:0.}_.""" def __init__(self, condition: str, body: List[Node]) -> None: - tokens = re.split(r"([?!]*)", condition, maxsplit=1) + tokens = re.split(r"^([?!]*)", condition, maxsplit=1) if len(tokens) == 1: self.prefix, self.name = "", tokens[0] else: @@ -271,7 +271,7 @@ elif value[start + 1] == "{": if ":" in value[start:end]: condition, body = value[start + 2 : end - 1].split(":", maxsplit=1) - tokens = re.split(r"([?!]*)", condition, maxsplit=1) + tokens = re.split(r"^([?!]*)", condition, maxsplit=1) prefix = tokens[0 if len(tokens) == 1 else 1] if "?" in prefix: result.append( diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/specfile.egg-info/PKG-INFO new/specfile-0.31.0/specfile.egg-info/PKG-INFO --- old/specfile-0.29.0/specfile.egg-info/PKG-INFO 2024-06-06 15:50:10.000000000 +0200 +++ new/specfile-0.31.0/specfile.egg-info/PKG-INFO 2024-07-04 16:25:48.000000000 +0200 @@ -1,6 +1,6 @@ Metadata-Version: 2.1 Name: specfile -Version: 0.29.0 +Version: 0.31.0 Summary: A library for parsing and manipulating RPM spec files. Home-page: https://github.com/packit/specfile Author: Red Hat diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/tests/integration/test_specfile.py new/specfile-0.31.0/tests/integration/test_specfile.py --- old/specfile-0.29.0/tests/integration/test_specfile.py 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/tests/integration/test_specfile.py 2024-07-04 16:25:42.000000000 +0200 @@ -329,7 +329,9 @@ @pytest.mark.skipif( rpm.__version__ < "4.16", reason="%autochangelog requires rpm 4.16 or higher" ) -def test_autochangelog(spec_rpmautospec, spec_conditionalized_changelog): +def test_autochangelog( + spec_rpmautospec, spec_conditionalized_changelog, spec_autosetup +): spec = Specfile(spec_rpmautospec) assert spec.has_autochangelog with spec.changelog() as changelog: @@ -350,6 +352,10 @@ assert changelogs[0] == changelog with spec.changelog(changelogs[1]) as changelog: assert changelog[-1].content == ["test"] + spec = Specfile(spec_autosetup) + with spec.changelog() as changelog: + changelog[0].content += "%" + assert not spec.has_autochangelog @pytest.mark.skipif( @@ -401,6 +407,10 @@ assert spec.raw_release == "%{release}" with spec.macro_definitions() as md: assert md.release.body == "2%{?dist}" + spec.update_tag("Release", "%release") + assert spec.raw_release == "%release" + with spec.macro_definitions() as md: + assert md.release.body == "2%{?dist}" spec.update_tag( "Source0", "https://example.com/archived_releases/test/v6.0.0/test-v6.0.0.tar.xz", diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/tests/unit/test_conditions.py new/specfile-0.31.0/tests/unit/test_conditions.py --- old/specfile-0.29.0/tests/unit/test_conditions.py 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/tests/unit/test_conditions.py 2024-07-04 16:25:42.000000000 +0200 @@ -4,23 +4,31 @@ import pytest from flexmock import flexmock -import specfile.conditions from specfile.conditions import process_conditions from specfile.macro_definitions import MacroDefinitions +from specfile.macros import Macros @pytest.mark.parametrize( - "lines, validity, resolve_func", + "lines, validity, expand_func", [ ( ["%ifarch %{power64}", "export ARCH=PPC64", "%endif"], [True, True, True], - lambda kwd, exp: True, + lambda expr: ( + "ppc64" + if expr == "%{_target_cpu}" + else "ppc64 ppc64p7 ppc64le" if expr == "%{power64}" else expr + ), ), ( ["%ifarch %{power64}", "export ARCH=PPC64", "%endif"], [True, False, True], - lambda kwd, exp: False, + lambda expr: ( + "x86_64" + if expr == "%{_target_cpu}" + else "ppc64 ppc64p7 ppc64le" if expr == "%{power64}" else expr + ), ), ( [ @@ -33,7 +41,11 @@ "%endif", ], [True, False, True, True, True, False, True], - lambda kwd, exp: "rhel" in exp, + lambda expr: ( + "0" + if expr == "%{expr:0%{?fedora} > 38}" + else "1" if expr == "%{expr:0%{?rhel} > 8}" else expr + ), ), ( [ @@ -64,17 +76,19 @@ True, True, ], - lambda kwd, exp: "fedora" in exp, + lambda expr: ( + "0" + if expr.startswith("%{expr:%{with_") + else "1" if expr == "%{expr:0%{?fedora}}" else expr + ), ), ], ) -def test_process_conditions(lines, validity, resolve_func): - def resolve_expression(kwd, exp, *_, **__): - return resolve_func(kwd, exp) +def test_process_conditions(lines, validity, expand_func): + def expand(expr): + return expand_func(expr) - flexmock(specfile.conditions).should_receive("resolve_expression").replace_with( - resolve_expression - ) + flexmock(Macros).should_receive("expand").replace_with(expand) processed_lines, processed_validity = zip(*process_conditions(lines)) assert list(processed_lines) == lines assert list(processed_validity) == validity diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/specfile-0.29.0/tests/unit/test_tags.py new/specfile-0.31.0/tests/unit/test_tags.py --- old/specfile-0.29.0/tests/unit/test_tags.py 2024-06-06 15:50:01.000000000 +0200 +++ new/specfile-0.31.0/tests/unit/test_tags.py 2024-07-04 16:25:42.000000000 +0200 @@ -43,7 +43,7 @@ "Epoch: 1", "%endif", "", - "Requires: make", + "Requires: make ", "Requires(post): bash", "", "Provides: testX = %{version}-%{release}", @@ -102,7 +102,15 @@ Comments([Comment("this is a valid comment", " # ")]), ), Tag("Epoch", "1", ": ", Comments([], ["", "%if 0"])), - Tag("Requires", "make", ": ", Comments([], ["%endif", ""])), + Tag( + "Requires", + "make", + ": ", + Comments([], ["%endif", ""]), + True, + "", + " ", + ), Tag("Requires(post)", "bash", ": ", Comments()), Tag( "Suggests", @@ -133,7 +141,7 @@ "Epoch: 1", "%endif", "", - "Requires: make", + "Requires: make ", "Requires(post): bash", "", "%{?fedora:Suggests: diffutils}",