Skip to content

Commit

Permalink
Improve compatibility with rpm 4.20alpha (#380)
Browse files Browse the repository at this point in the history
Improve compatibility with rpm 4.20alpha

rpm 4.20alpha (now in rawhide) obsoletes %patchN macros and spec files containing them are unparseable. Stop using such macros in integration tests and add support for the %patch N variant.
RELEASE NOTES BEGIN
Improved compatibility with RPM 4.20 (alpha version is currently in Fedora Rawhide).
RELEASE NOTES END

Reviewed-by: Matej Focko
Reviewed-by: Nikola Forró
Reviewed-by: Laura Barcziová
  • Loading branch information
2 parents 557c33b + b2ed90e commit 9543deb
Show file tree
Hide file tree
Showing 5 changed files with 58 additions and 29 deletions.
40 changes: 29 additions & 11 deletions specfile/prep.py
Original file line number Diff line number Diff line change
Expand Up @@ -112,19 +112,26 @@ class PatchMacro(PrepMacro):
@property
def number(self) -> int:
"""Number of the %patch macro."""
if self.options.P is not None:
return int(self.options.P)
tokens = re.split(r"(\d+)", self.name, maxsplit=1)
if len(tokens) > 1:
return int(tokens[1])
if self.options.P is not None:
return int(self.options.P)
if self.options.positional:
return int(self.options.positional[0])
return 0

@number.setter
def number(self, value: int) -> None:
if self.options.P is not None:
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:
self.options.P = value
return
self.name = f"{self.CANONICAL_NAME}{value}"
elif self.options.positional:
self.options.positional[0] = value
else:
self.name = f"{self.CANONICAL_NAME}{value}"


class AutosetupMacro(PrepMacro):
Expand Down Expand Up @@ -280,12 +287,18 @@ def __delattr__(self, name: str) -> None:
return super().__delattr__(name)
return delattr(self.macros, name)

def add_patch_macro(self, number: int, **kwargs: Any) -> None:
def add_patch_macro(
self,
number: Optional[int] = None,
old_style_number: bool = False,
**kwargs: Any,
) -> None:
"""
Adds a new _%patch_ macro with given number and options.
Args:
number: Macro number.
number: Optional macro number.
old_style_number: Whether the number should be part of macro name.
P: The _-P_ option (patch number).
p: The _-p_ option (strip number).
R: The _-R_ option (reverse).
Expand All @@ -297,19 +310,24 @@ def add_patch_macro(self, number: int, **kwargs: Any) -> None:
o: The _-o_ option (output file).
Z: The _-Z_ option (set UTC times).
"""
name = PatchMacro.CANONICAL_NAME
options = Options([], PatchMacro.OPTSTRING, PatchMacro.DEFAULTS)
if number is not None:
if old_style_number:
name += str(number)
else:
options.positional.append(number)
for k, v in kwargs.items():
setattr(options, k, v)
macro = PatchMacro(PatchMacro.CANONICAL_NAME, options, " ")
macro.number = number
macro = PatchMacro(name, options, " ")
index, _ = min(
((i, m) for i, m in enumerate(self.macros) if isinstance(m, PatchMacro)),
key=lambda im: abs(im[1].number - number),
key=lambda im: abs(im[1].number - macro.number),
default=(len(self.macros), None),
)
if (
index < len(self.macros)
and cast(PatchMacro, self.macros[index]).number <= number
and cast(PatchMacro, self.macros[index]).number <= macro.number
):
index += 1
self.macros.insert(index, macro)
Expand Down
6 changes: 3 additions & 3 deletions tests/data/spec_macros/test.spec
Original file line number Diff line number Diff line change
Expand Up @@ -40,9 +40,9 @@ Test package
%prep
%setup -q -n %{name}-%{version}
%setup -c -T -D -b 1
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch -P0 -p1
%patch -P1 -p1
%patch -P2 -p1


%changelog
Expand Down
6 changes: 3 additions & 3 deletions tests/data/spec_traditional/test.spec
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,9 @@ Test package

%prep
%setup -q
%patch0 -p1
%patch1 -p1
%patch2 -p1
%patch -P0 -p1
%patch -P1 -p1
%patch -P2 -p1


%changelog
Expand Down
11 changes: 6 additions & 5 deletions tests/integration/test_specfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,12 +41,13 @@ def test_prep_traditional(spec_traditional):
assert len([m for m in prep.macros if isinstance(m, PatchMacro)]) == 2
prep.add_patch_macro(0, p=2, b=".test")
assert len(prep.macros) == 4
assert prep.patch0.options.p == 2
assert prep.patch0.options.b == ".test"
prep.patch0.options.b = ".test2"
prep.patch0.options.E = True
assert prep.macros[1].options.positional == [0]
assert prep.macros[1].options.p == 2
assert prep.macros[1].options.b == ".test"
prep.macros[1].options.b = ".test2"
prep.macros[1].options.E = True
with spec.sections() as sections:
assert sections.prep[1] == "%patch0 -p2 -b .test2 -E"
assert sections.prep[1] == "%patch 0 -p2 -b .test2 -E"


def test_prep_autosetup(spec_autosetup):
Expand Down
24 changes: 17 additions & 7 deletions tests/unit/test_prep.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,10 @@
("%patch0028", "-p2", 28),
("%patch", "-p1", 0),
("%patch", "-P1", 1),
("%patch3", "-P5", 5),
("%patch3", "-P5", 3),
("%patch0", "-P1 2", 0),
("%patch", "-P1 2", 1),
("%patch", "2", 2),
],
)
def test_patch_macro_number(name, options, number):
Expand All @@ -40,48 +43,55 @@ def test_prep_macros_find():


@pytest.mark.parametrize(
"lines_before, number, options, lines_after",
"lines_before, number, old_style_number, options, lines_after",
[
(
["%setup -q"],
0,
True,
dict(p=1),
["%setup -q", "%patch0 -p1"],
),
(
["%setup -q", "%patch0 -p1"],
0,
True,
dict(p=2),
["%setup -q", "%patch0 -p1", "%patch0 -p2"],
),
(
["%setup -q", "%patch999 -p1"],
28,
False,
dict(p=1),
["%setup -q", "%patch28 -p1", "%patch999 -p1"],
["%setup -q", "%patch 28 -p1", "%patch999 -p1"],
),
(
["%setup -q", "%patch999 -p1"],
1001,
False,
dict(p=1),
["%setup -q", "%patch999 -p1", "%patch1001 -p1"],
["%setup -q", "%patch999 -p1", "%patch 1001 -p1"],
),
(
["%setup -q", "%{!?skip_first_patch:%patch0 -p1}", "%patch999 -p1"],
28,
False,
dict(p=2, b=".patch28"),
[
"%setup -q",
"%{!?skip_first_patch:%patch0 -p1}",
"%patch28 -p2 -b .patch28",
"%patch 28 -p2 -b .patch28",
"%patch999 -p1",
],
),
],
)
def test_prep_add_patch_macro(lines_before, number, options, lines_after):
def test_prep_add_patch_macro(
lines_before, number, old_style_number, options, lines_after
):
prep = Prep.parse(Section("prep", data=lines_before))
prep.add_patch_macro(number, **options)
prep.add_patch_macro(number, old_style_number, **options)
assert prep.get_raw_section_data() == lines_after


Expand Down

0 comments on commit 9543deb

Please sign in to comment.