Skip to content

Commit

Permalink
Merge pull request #141 from packit/misc
Browse files Browse the repository at this point in the history
A few improvements

RELEASE NOTES BEGIN
Section and Tag objects now have normalized_name property for more convenient comparison.
There is a new method, Specfile.get_active_macros(), to get active macros in the context of the spec file.
The underlying rpm.spec instance is now exposed as Specfile.rpm_spec property.
There is a new utility class for parsing NEVRA strings.
RELEASE NOTES END

Reviewed-by: Tomas Tomecek <[email protected]>
  • Loading branch information
softwarefactory-project-zuul[bot] authored Nov 29, 2022
2 parents 87894de + 721e64b commit daf36bc
Show file tree
Hide file tree
Showing 8 changed files with 315 additions and 109 deletions.
2 changes: 1 addition & 1 deletion fedora/python-specfile.spec
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ sed -i 's/rpm-py-installer/rpm/' setup.cfg
%pyproject_save_files specfile


%if 0%{?with_tests}
%if %{with tests}
%check
%pytest
%endif
Expand Down
193 changes: 193 additions & 0 deletions specfile/constants.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
# Copyright Contributors to the Packit project.
# SPDX-License-Identifier: MIT

# valid section names as defined in build/parseSpec.c in RPM source
SECTION_NAMES = {
"package",
"prep",
"generate_buildrequires",
"conf",
"build",
"install",
"check",
"clean",
"preun",
"postun",
"pretrans",
"posttrans",
"pre",
"post",
"files",
"changelog",
"description",
"triggerpostun",
"triggerprein",
"triggerun",
"triggerin",
"trigger",
"verifyscript",
"sepolicy",
"filetriggerin",
"filetrigger",
"filetriggerun",
"filetriggerpostun",
"transfiletriggerin",
"transfiletrigger",
"transfiletriggerun",
"transfiletriggerpostun",
"end",
"patchlist",
"sourcelist",
}

# valid tag names as defined in build/parsePreamble.c in RPM source
TAG_NAMES = {
"name",
"version",
"release",
"epoch",
"summary",
"license",
"distribution",
"disturl",
"vendor",
"group",
"packager",
"url",
"vcs",
"source",
"patch",
"nosource",
"nopatch",
"excludearch",
"exclusivearch",
"excludeos",
"exclusiveos",
"icon",
"provides",
"requires",
"recommends",
"suggests",
"supplements",
"enhances",
"prereq",
"conflicts",
"obsoletes",
"prefixes",
"prefix",
"buildroot",
"buildarchitectures",
"buildarch",
"buildconflicts",
"buildprereq",
"buildrequires",
"autoreqprov",
"autoreq",
"autoprov",
"docdir",
"disttag",
"bugurl",
"translationurl",
"upstreamreleases",
"orderwithrequires",
"removepathpostfixes",
"modularitylabel",
}

# tags that can optionally have an argument (language or qualifier)
TAGS_WITH_ARG = {
"summary",
"group",
"requires",
"prereq",
"orderwithrequires",
}

# canonical architecture names as defined in rpmrc.in in RPM source
ARCH_NAMES = {
"aarch64",
"alpha",
"alphaev5",
"alphaev56",
"alphaev6",
"alphaev67",
"alphapca56",
"amd64",
"armv3l",
"armv4b",
"armv4l",
"armv5tejl",
"armv5tel",
"armv5tl",
"armv6hl",
"armv6l",
"armv7hl",
"armv7hnl",
"armv7l",
"armv8hl",
"armv8l",
"atariclone",
"atarist",
"atariste",
"ataritt",
"athlon",
"em64t",
"falcon",
"geode",
"hades",
"i370",
"i386",
"i486",
"i586",
"i686",
"ia32e",
"ia64",
"IP",
"loongarch64",
"m68k",
"m68kmint",
"milan",
"mips",
"mips64",
"mips64el",
"mips64r6",
"mips64r6el",
"mipsel",
"mipsr6",
"mipsr6el",
"pentium3",
"pentium4",
"ppc",
"ppc32dy4",
"ppc64",
"ppc64iseries",
"ppc64le",
"ppc64p7",
"ppc64pseries",
"ppc8260",
"ppc8560",
"ppciseries",
"ppcpseries",
"riscv",
"riscv64",
"rs6000",
"s390",
"s390x",
"sh",
"sh3",
"sh4",
"sh4a",
"sparc",
"sparc64",
"sparc64v",
"sparcv8",
"sparcv9",
"sparcv9v",
"sun4",
"sun4c",
"sun4d",
"sun4m",
"sun4u",
"x86_64",
"xtensa",
}
45 changes: 6 additions & 39 deletions specfile/sections.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,7 @@
import re
from typing import List, Optional, SupportsIndex, Union, cast, overload

# valid section names as defined in build/parseSpec.c in RPM source
SECTION_NAMES = {
"package",
"prep",
"generate_buildrequires",
"conf",
"build",
"install",
"check",
"clean",
"preun",
"postun",
"pretrans",
"posttrans",
"pre",
"post",
"files",
"changelog",
"description",
"triggerpostun",
"triggerprein",
"triggerun",
"triggerin",
"trigger",
"verifyscript",
"sepolicy",
"filetriggerin",
"filetrigger",
"filetriggerun",
"filetriggerpostun",
"transfiletriggerin",
"transfiletrigger",
"transfiletriggerun",
"transfiletriggerpostun",
"end",
"patchlist",
"sourcelist",
}

from specfile.constants import SECTION_NAMES

# name for the implicit "preamble" section
PREAMBLE = "package"
Expand Down Expand Up @@ -93,6 +55,11 @@ def __getitem__(self, i):
else:
return self.data[i]

@property
def normalized_name(self) -> str:
"""Normalized name of the section. All characters are lowercased."""
return self.name.lower()

def copy(self) -> "Section":
return Section(self.name, self.data)

Expand Down
22 changes: 21 additions & 1 deletion specfile/specfile.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,12 @@
from pathlib import Path
from typing import Iterator, List, Optional, Tuple, Type, Union

import rpm

from specfile.changelog import Changelog, ChangelogEntry
from specfile.exceptions import SourceNumberException, SpecfileException
from specfile.macro_definitions import MacroDefinition, MacroDefinitions
from specfile.macros import Macros
from specfile.macros import Macro, Macros
from specfile.prep import Prep
from specfile.sections import Section, Sections
from specfile.sourcelist import Sourcelist
Expand Down Expand Up @@ -103,6 +105,11 @@ def tainted(self) -> bool:
"""
return self._parser.tainted

@property
def rpm_spec(self) -> rpm.spec:
"""Underlying `rpm.spec` instance."""
return self._parser.spec

def reload(self) -> None:
"""Reload the spec file content."""
self._lines = self.path.read_text().splitlines()
Expand All @@ -128,6 +135,19 @@ def expand(
self._parser.parse(str(self), extra_macros)
return Macros.expand(expression)

def get_active_macros(self) -> List[Macro]:
"""
Gets active macros in the context of the spec file.
This includes built-in RPM macros, macros loaded from macro files
and macros defined in the spec file itself.
Returns:
List of `Macro` objects.
"""
self._parser.parse(str(self))
return Macros.dump()

@contextlib.contextmanager
def lines(self) -> Iterator[List[str]]:
"""
Expand Down
72 changes: 9 additions & 63 deletions specfile/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,71 +6,9 @@
import re
from typing import Any, Iterable, List, Optional, SupportsIndex, Union, cast, overload

from specfile.constants import TAG_NAMES, TAGS_WITH_ARG
from specfile.sections import Section

# valid tag names as defined in build/parsePreamble.c in RPM source
TAG_NAMES = {
"name",
"version",
"release",
"epoch",
"summary",
"license",
"distribution",
"disturl",
"vendor",
"group",
"packager",
"url",
"vcs",
"source",
"patch",
"nosource",
"nopatch",
"excludearch",
"exclusivearch",
"excludeos",
"exclusiveos",
"icon",
"provides",
"requires",
"recommends",
"suggests",
"supplements",
"enhances",
"prereq",
"conflicts",
"obsoletes",
"prefixes",
"prefix",
"buildroot",
"buildarchitectures",
"buildarch",
"buildconflicts",
"buildprereq",
"buildrequires",
"autoreqprov",
"autoreq",
"autoprov",
"docdir",
"disttag",
"bugurl",
"translationurl",
"upstreamreleases",
"orderwithrequires",
"removepathpostfixes",
"modularitylabel",
}

# tags that can optionally have an argument (language or qualifier)
TAGS_WITH_ARG = {
"summary",
"group",
"requires",
"prereq",
"orderwithrequires",
}


def get_tag_name_regex(name: str) -> str:
"""Contructs regex corresponding to the specified tag name."""
Expand Down Expand Up @@ -297,6 +235,14 @@ def __repr__(self) -> str:
f"'{self._separator}', {comments})"
)

@property
def normalized_name(self) -> str:
"""
Normalized name of the tag. The first character is capitalized
and the rest lowercased.
"""
return self.name.capitalize()

@property
def valid(self) -> bool:
"""Validity of the tag. A tag is valid if it 'survives' the expansion of the spec file."""
Expand Down
Loading

0 comments on commit daf36bc

Please sign in to comment.