Skip to content

Commit 9543deb

Browse files
Improve compatibility with rpm 4.20alpha (#380)
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á
2 parents 557c33b + b2ed90e commit 9543deb

File tree

5 files changed

+58
-29
lines changed

5 files changed

+58
-29
lines changed

specfile/prep.py

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -112,19 +112,26 @@ class PatchMacro(PrepMacro):
112112
@property
113113
def number(self) -> int:
114114
"""Number of the %patch macro."""
115-
if self.options.P is not None:
116-
return int(self.options.P)
117115
tokens = re.split(r"(\d+)", self.name, maxsplit=1)
118116
if len(tokens) > 1:
119117
return int(tokens[1])
118+
if self.options.P is not None:
119+
return int(self.options.P)
120+
if self.options.positional:
121+
return int(self.options.positional[0])
120122
return 0
121123

122124
@number.setter
123125
def number(self, value: int) -> None:
124-
if self.options.P is not None:
126+
tokens = re.split(r"(\d+)", self.name, maxsplit=1)
127+
if len(tokens) > 1:
128+
self.name = f"{tokens[0]}{value}"
129+
elif self.options.P is not None:
125130
self.options.P = value
126-
return
127-
self.name = f"{self.CANONICAL_NAME}{value}"
131+
elif self.options.positional:
132+
self.options.positional[0] = value
133+
else:
134+
self.name = f"{self.CANONICAL_NAME}{value}"
128135

129136

130137
class AutosetupMacro(PrepMacro):
@@ -280,12 +287,18 @@ def __delattr__(self, name: str) -> None:
280287
return super().__delattr__(name)
281288
return delattr(self.macros, name)
282289

283-
def add_patch_macro(self, number: int, **kwargs: Any) -> None:
290+
def add_patch_macro(
291+
self,
292+
number: Optional[int] = None,
293+
old_style_number: bool = False,
294+
**kwargs: Any,
295+
) -> None:
284296
"""
285297
Adds a new _%patch_ macro with given number and options.
286298
287299
Args:
288-
number: Macro number.
300+
number: Optional macro number.
301+
old_style_number: Whether the number should be part of macro name.
289302
P: The _-P_ option (patch number).
290303
p: The _-p_ option (strip number).
291304
R: The _-R_ option (reverse).
@@ -297,19 +310,24 @@ def add_patch_macro(self, number: int, **kwargs: Any) -> None:
297310
o: The _-o_ option (output file).
298311
Z: The _-Z_ option (set UTC times).
299312
"""
313+
name = PatchMacro.CANONICAL_NAME
300314
options = Options([], PatchMacro.OPTSTRING, PatchMacro.DEFAULTS)
315+
if number is not None:
316+
if old_style_number:
317+
name += str(number)
318+
else:
319+
options.positional.append(number)
301320
for k, v in kwargs.items():
302321
setattr(options, k, v)
303-
macro = PatchMacro(PatchMacro.CANONICAL_NAME, options, " ")
304-
macro.number = number
322+
macro = PatchMacro(name, options, " ")
305323
index, _ = min(
306324
((i, m) for i, m in enumerate(self.macros) if isinstance(m, PatchMacro)),
307-
key=lambda im: abs(im[1].number - number),
325+
key=lambda im: abs(im[1].number - macro.number),
308326
default=(len(self.macros), None),
309327
)
310328
if (
311329
index < len(self.macros)
312-
and cast(PatchMacro, self.macros[index]).number <= number
330+
and cast(PatchMacro, self.macros[index]).number <= macro.number
313331
):
314332
index += 1
315333
self.macros.insert(index, macro)

tests/data/spec_macros/test.spec

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -40,9 +40,9 @@ Test package
4040
%prep
4141
%setup -q -n %{name}-%{version}
4242
%setup -c -T -D -b 1
43-
%patch0 -p1
44-
%patch1 -p1
45-
%patch2 -p1
43+
%patch -P0 -p1
44+
%patch -P1 -p1
45+
%patch -P2 -p1
4646

4747

4848
%changelog

tests/data/spec_traditional/test.spec

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,9 @@ Test package
1717

1818
%prep
1919
%setup -q
20-
%patch0 -p1
21-
%patch1 -p1
22-
%patch2 -p1
20+
%patch -P0 -p1
21+
%patch -P1 -p1
22+
%patch -P2 -p1
2323

2424

2525
%changelog

tests/integration/test_specfile.py

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -41,12 +41,13 @@ def test_prep_traditional(spec_traditional):
4141
assert len([m for m in prep.macros if isinstance(m, PatchMacro)]) == 2
4242
prep.add_patch_macro(0, p=2, b=".test")
4343
assert len(prep.macros) == 4
44-
assert prep.patch0.options.p == 2
45-
assert prep.patch0.options.b == ".test"
46-
prep.patch0.options.b = ".test2"
47-
prep.patch0.options.E = True
44+
assert prep.macros[1].options.positional == [0]
45+
assert prep.macros[1].options.p == 2
46+
assert prep.macros[1].options.b == ".test"
47+
prep.macros[1].options.b = ".test2"
48+
prep.macros[1].options.E = True
4849
with spec.sections() as sections:
49-
assert sections.prep[1] == "%patch0 -p2 -b .test2 -E"
50+
assert sections.prep[1] == "%patch 0 -p2 -b .test2 -E"
5051

5152

5253
def test_prep_autosetup(spec_autosetup):

tests/unit/test_prep.py

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,10 @@
1717
("%patch0028", "-p2", 28),
1818
("%patch", "-p1", 0),
1919
("%patch", "-P1", 1),
20-
("%patch3", "-P5", 5),
20+
("%patch3", "-P5", 3),
21+
("%patch0", "-P1 2", 0),
22+
("%patch", "-P1 2", 1),
23+
("%patch", "2", 2),
2124
],
2225
)
2326
def test_patch_macro_number(name, options, number):
@@ -40,48 +43,55 @@ def test_prep_macros_find():
4043

4144

4245
@pytest.mark.parametrize(
43-
"lines_before, number, options, lines_after",
46+
"lines_before, number, old_style_number, options, lines_after",
4447
[
4548
(
4649
["%setup -q"],
4750
0,
51+
True,
4852
dict(p=1),
4953
["%setup -q", "%patch0 -p1"],
5054
),
5155
(
5256
["%setup -q", "%patch0 -p1"],
5357
0,
58+
True,
5459
dict(p=2),
5560
["%setup -q", "%patch0 -p1", "%patch0 -p2"],
5661
),
5762
(
5863
["%setup -q", "%patch999 -p1"],
5964
28,
65+
False,
6066
dict(p=1),
61-
["%setup -q", "%patch28 -p1", "%patch999 -p1"],
67+
["%setup -q", "%patch 28 -p1", "%patch999 -p1"],
6268
),
6369
(
6470
["%setup -q", "%patch999 -p1"],
6571
1001,
72+
False,
6673
dict(p=1),
67-
["%setup -q", "%patch999 -p1", "%patch1001 -p1"],
74+
["%setup -q", "%patch999 -p1", "%patch 1001 -p1"],
6875
),
6976
(
7077
["%setup -q", "%{!?skip_first_patch:%patch0 -p1}", "%patch999 -p1"],
7178
28,
79+
False,
7280
dict(p=2, b=".patch28"),
7381
[
7482
"%setup -q",
7583
"%{!?skip_first_patch:%patch0 -p1}",
76-
"%patch28 -p2 -b .patch28",
84+
"%patch 28 -p2 -b .patch28",
7785
"%patch999 -p1",
7886
],
7987
),
8088
],
8189
)
82-
def test_prep_add_patch_macro(lines_before, number, options, lines_after):
90+
def test_prep_add_patch_macro(
91+
lines_before, number, old_style_number, options, lines_after
92+
):
8393
prep = Prep.parse(Section("prep", data=lines_before))
84-
prep.add_patch_macro(number, **options)
94+
prep.add_patch_macro(number, old_style_number, **options)
8595
assert prep.get_raw_section_data() == lines_after
8696

8797

0 commit comments

Comments
 (0)