Skip to content

Commit

Permalink
Set validity of tags based on conditions
Browse files Browse the repository at this point in the history
Signed-off-by: Nikola Forró <[email protected]>
  • Loading branch information
nforro committed Aug 21, 2023
1 parent 35a235c commit 602b1f8
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 7 deletions.
35 changes: 32 additions & 3 deletions specfile/sources.py
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,21 @@ def _get_initial_tag_setup(self, number: int = 0) -> Tuple[int, str, str]:
suffix = f"{number:0{self._default_source_number_digits}}"
return len(self._tags) if self._tags else 0, f"{self.prefix}{suffix}", ": "

def _get_tag_validity(self, reference: Optional[TagSource] = None) -> bool:
"""
Determines validity of a new source tag based on a reference tag, if specified,
or the last tag in the spec file. Defaults to True.
Args:
reference: Optional reference tag source.
Returns:
Whether the new source tag is valid or not.
"""
if reference is not None:
return reference._tag.valid
return self._tags[-1].valid if self._tags else True

def _deduplicate_tag_names(self, start: int = 0) -> None:
"""
Eliminates duplicate numbers in source tag names.
Expand Down Expand Up @@ -505,9 +520,17 @@ def insert(self, i: int, location: str) -> None:
number = source.number
if isinstance(source, self.tag_class):
name, separator = self._get_tag_format(cast(TagSource, source), number)
valid = self._get_tag_validity(cast(TagSource, source))
container.insert(
index,
Tag(name, location, separator, Comments(), context=self._context),
Tag(
name,
location,
separator,
Comments(),
valid,
context=self._context,
),
)
self._deduplicate_tag_names(i)
else:
Expand All @@ -523,9 +546,12 @@ def insert(self, i: int, location: str) -> None:
)
else:
index, name, separator = self._get_initial_tag_setup()
valid = self._get_tag_validity()
self._tags.insert(
index,
Tag(name, location, separator, Comments(), context=self._context),
Tag(
name, location, separator, Comments(), valid, context=self._context
),
)

def insert_numbered(self, number: int, location: str) -> int:
Expand Down Expand Up @@ -555,11 +581,14 @@ def insert_numbered(self, number: int, location: str) -> int:
i += 1
index += 1
name, separator = self._get_tag_format(source, number)
valid = self._get_tag_validity(source)
else:
i = 0
index, name, separator = self._get_initial_tag_setup(number)
valid = self._get_tag_validity()
self._tags.insert(
index, Tag(name, location, separator, Comments(), context=self._context)
index,
Tag(name, location, separator, Comments(), valid, context=self._context),
)
self._deduplicate_tag_names(i)
return i
Expand Down
20 changes: 16 additions & 4 deletions specfile/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,10 @@
overload,
)

from specfile.conditions import process_conditions
from specfile.constants import TAG_NAMES, TAGS_WITH_ARG
from specfile.formatter import formatted
from specfile.macro_definitions import MacroDefinitions
from specfile.macros import Macros
from specfile.sections import Section
from specfile.types import SupportsIndex
Expand Down Expand Up @@ -212,6 +214,7 @@ def __init__(
value: str,
separator: str,
comments: Comments,
valid: bool = True,
prefix: Optional[str] = None,
suffix: Optional[str] = None,
context: Optional["Specfile"] = None,
Expand All @@ -227,6 +230,7 @@ def __init__(
Separator between name and literal value (colon usually surrounded by some
amount of whitespace).
comments: List of comments associated with the tag.
valid: Whether the tag is not located in a false branch of a condition.
prefix: Characters preceding the tag on a line.
suffix: Characters following the tag on a line.
context: `Specfile` instance that defines the context for macro expansions.
Expand All @@ -243,6 +247,7 @@ def __init__(
self.value = value
self._separator = separator
self.comments = comments.copy()
self.valid = valid
self._prefix = prefix or ""
self._suffix = suffix or ""
self._context = context
Expand All @@ -263,7 +268,7 @@ def __eq__(self, other: object) -> bool:
def __repr__(self) -> str:
return (
f"Tag({self.name!r}, {self.value!r}, {self._separator!r}, {self.comments!r}, "
f"{self._prefix!r}, {self._suffix!r}, {self._context!r})"
f"{self.valid!r}, {self._prefix!r}, {self._suffix!r}, {self._context!r})"
)

def __deepcopy__(self, memo: Dict[int, Any]) -> "Tag":
Expand Down Expand Up @@ -433,10 +438,14 @@ def __delattr__(self, name: str) -> None:
def copy(self) -> "Tags":
return copy.copy(self)

def find(self, name: str) -> int:
def get(self, name: str, position: Optional[int] = None) -> Tag:
return self.data[self.find(name, position)]

def find(self, name: str, position: Optional[int] = None) -> int:
for i, tag in enumerate(self.data):
if tag.name.capitalize() == name.capitalize():
return i
if position is None or tag.get_position(self) == position:
return i
raise ValueError

def insert(self, i: int, item: Tag) -> None:
Expand Down Expand Up @@ -472,10 +481,12 @@ def regex_pattern(tag):
name_regex = get_tag_name_regex(tag)
return rf"^(?P<n>{name_regex})(?P<s>\s*:\s*)(?P<v>.+)"

macro_definitions = MacroDefinitions.parse(list(section))
lines = process_conditions(list(section), macro_definitions, context)
tag_regexes = [re.compile(regex_pattern(t), re.IGNORECASE) for t in TAG_NAMES]
data = []
buffer: List[str] = []
for line in section:
for line, valid in lines:
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)
Expand All @@ -486,6 +497,7 @@ def regex_pattern(tag):
m.group("v"),
m.group("s"),
Comments.parse(buffer),
valid,
prefix,
suffix,
context,
Expand Down
1 change: 1 addition & 0 deletions tests/unit/test_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ def test_get_raw_section_data():
"diffutils",
": ",
Comments([], [""]),
True,
"%{?fedora:",
"}",
),
Expand Down

0 comments on commit 602b1f8

Please sign in to comment.