From 547e918d30785cc922051bd5db76cb5913c1e8f3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=BDna=20Streitov=C3=A1?= Date: Mon, 15 Jul 2019 18:58:30 +0200 Subject: [PATCH 1/2] Replace legacy packageand() with 'and' expression Starting with rpm-4.13, RPM is able to process boolean expressions in all dependency tokens so 'packageand(pkgA:pkgB)' can be replaced by '(pkgA and pkgB)' statement. (Closes #241). --- spec_cleaner/rpmregexp.py | 1 + spec_cleaner/rpmrequirestoken.py | 15 +++++++++++---- tests/in/packageand.spec | 10 ++++++++++ tests/out-minimal/packageand.spec | 12 ++++++++++++ tests/out/packageand.spec | 12 ++++++++++++ 5 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 tests/in/packageand.spec create mode 100644 tests/out-minimal/packageand.spec create mode 100644 tests/out/packageand.spec diff --git a/spec_cleaner/rpmregexp.py b/spec_cleaner/rpmregexp.py index f7f36dcf..d0330d74 100644 --- a/spec_cleaner/rpmregexp.py +++ b/spec_cleaner/rpmregexp.py @@ -91,6 +91,7 @@ class Regexp(object): # Special bracketed deps dection re_brackety_requires = re.compile(r'(pkgconfig|cmake|perl|tex|rubygem)\(') re_version_separator = re.compile(r'(\S+)((\s*[<>=\s]+)(\S+))*') + re_packageand = re.compile(r'^packageand\(\s*(\S+)\s*:\s*(\S+)\s*\)\s*$') # rpmdescription re_authors = re.compile(r'^\s*Author(s)?:\s*') diff --git a/spec_cleaner/rpmrequirestoken.py b/spec_cleaner/rpmrequirestoken.py index 93c45c8e..64367f5f 100644 --- a/spec_cleaner/rpmrequirestoken.py +++ b/spec_cleaner/rpmrequirestoken.py @@ -1,14 +1,15 @@ from typing import Optional from .rpmexception import RpmException +from .rpmregexp import Regexp class RpmRequiresToken(object): """ Class containing information about the dependency token. - Can be used to specify all the values present on the line. - Later on we use this to do various conversions. + Process dependencies like Requires, Recommends, Suggests, Supplements, Enhances, Conflicts. Can be used to specify + all the values present on the line. Later on we use this to do various conversions. This class uses the following format and naming: @@ -44,7 +45,7 @@ def _format_operator(operator: str) -> str: @staticmethod def _format_name(name: str) -> str: """ - Make sure the name looks sane. + Make sure the name looks sane and make various replacements. Args: name: A string representing the name used in the dependency token. @@ -55,10 +56,16 @@ def _format_name(name: str) -> str: # we just rename pkgconfig names to one unified one working everywhere if name == 'pkgconfig(pkg-config)' or name == 'pkg-config': name = 'pkgconfig' - # if there is otherproviders codeblock just ommit it + + # omit legacy 'otherproviders' codeblock if name.startswith('otherproviders('): name = name.rstrip(')') name = name.replace('otherproviders(', '') + + # replace 'packageand(pkgA:pkgB)' with '(pkgA and pkgB)' - new in RPM 4.13 + match = Regexp.re_packageand.match(name) + if match: + name = f'({match.group(1)} and {match.group(2)})' return name def __str__(self) -> str: diff --git a/tests/in/packageand.spec b/tests/in/packageand.spec new file mode 100644 index 00000000..05bed929 --- /dev/null +++ b/tests/in/packageand.spec @@ -0,0 +1,10 @@ +Requires: packageand(packA:packB) +Recommends: packageand(packC:packD) +Suggests: packageand(packE:packF) +Supplements: packageand(packG:packH) +Enhances: packageand(packI:packJ) +Conflicts: packageand(packK:packL) +Supplements: packageand(nginx:moodle) +Supplements: packageand(pam_xyz:pam-32bit) +Supplements: packageand(libpulse0:libxine1) +Supplements: packageand(MozillaFirefox:branding-openSUSE) diff --git a/tests/out-minimal/packageand.spec b/tests/out-minimal/packageand.spec new file mode 100644 index 00000000..a63c0523 --- /dev/null +++ b/tests/out-minimal/packageand.spec @@ -0,0 +1,12 @@ +Requires: (packA and packB) +Recommends: (packC and packD) +Suggests: (packE and packF) +Enhances: (packI and packJ) +Supplements: (MozillaFirefox and branding-openSUSE) +Supplements: (libpulse0 and libxine1) +Supplements: (nginx and moodle) +Supplements: (packG and packH) +Supplements: (pam_xyz and pam-32bit) +Conflicts: (packK and packL) + +%changelog diff --git a/tests/out/packageand.spec b/tests/out/packageand.spec new file mode 100644 index 00000000..a63c0523 --- /dev/null +++ b/tests/out/packageand.spec @@ -0,0 +1,12 @@ +Requires: (packA and packB) +Recommends: (packC and packD) +Suggests: (packE and packF) +Enhances: (packI and packJ) +Supplements: (MozillaFirefox and branding-openSUSE) +Supplements: (libpulse0 and libxine1) +Supplements: (nginx and moodle) +Supplements: (packG and packH) +Supplements: (pam_xyz and pam-32bit) +Conflicts: (packK and packL) + +%changelog From a888a9905b66ace554efc23f33a3a99381814321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Krist=C3=BDna=20Streitov=C3=A1?= Date: Tue, 16 Jul 2019 14:17:18 +0200 Subject: [PATCH 2/2] Use regexp for 'otherproviders' matching --- spec_cleaner/rpmregexp.py | 3 +++ spec_cleaner/rpmrequirestoken.py | 6 +++--- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/spec_cleaner/rpmregexp.py b/spec_cleaner/rpmregexp.py index d0330d74..89562a17 100644 --- a/spec_cleaner/rpmregexp.py +++ b/spec_cleaner/rpmregexp.py @@ -91,7 +91,10 @@ class Regexp(object): # Special bracketed deps dection re_brackety_requires = re.compile(r'(pkgconfig|cmake|perl|tex|rubygem)\(') re_version_separator = re.compile(r'(\S+)((\s*[<>=\s]+)(\S+))*') + # packageand(pkg1:pkg2) re_packageand = re.compile(r'^packageand\(\s*(\S+)\s*:\s*(\S+)\s*\)\s*$') + # otherproviders(foo) + re_otherproviders = re.compile(r'^otherproviders\(\s*(\S+)\s*\)\s*$') # rpmdescription re_authors = re.compile(r'^\s*Author(s)?:\s*') diff --git a/spec_cleaner/rpmrequirestoken.py b/spec_cleaner/rpmrequirestoken.py index 64367f5f..120bf4e3 100644 --- a/spec_cleaner/rpmrequirestoken.py +++ b/spec_cleaner/rpmrequirestoken.py @@ -58,9 +58,9 @@ def _format_name(name: str) -> str: name = 'pkgconfig' # omit legacy 'otherproviders' codeblock - if name.startswith('otherproviders('): - name = name.rstrip(')') - name = name.replace('otherproviders(', '') + match = Regexp.re_otherproviders.match(name) + if match: + name = match.group(1) # replace 'packageand(pkgA:pkgB)' with '(pkgA and pkgB)' - new in RPM 4.13 match = Regexp.re_packageand.match(name)