Skip to content

Commit

Permalink
Handle multi-line tag values
Browse files Browse the repository at this point in the history
Signed-off-by: Nikola Forró <[email protected]>
  • Loading branch information
nforro committed Sep 26, 2024
1 parent f5a4e59 commit b20d072
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 6 deletions.
31 changes: 26 additions & 5 deletions specfile/tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from specfile.macros import Macros
from specfile.sections import Section
from specfile.types import SupportsIndex
from specfile.utils import UserList, split_conditional_macro_expansion
from specfile.utils import UserList, count_brackets, split_conditional_macro_expansion

if TYPE_CHECKING:
from specfile.specfile import Specfile
Expand Down Expand Up @@ -489,6 +489,13 @@ def parse(cls, section: Section, context: Optional["Specfile"] = None) -> "Tags"
New instance of `Tags` class.
"""

def pop(lines):
line = lines.pop(0)
if isinstance(line, str):
return line, True
else:
return line

def regex_pattern(tag):
name_regex = get_tag_name_regex(tag)
return rf"^(?P<n>{name_regex})(?P<s>\s*:\s*)(?P<v>.+)"
Expand All @@ -498,7 +505,8 @@ def regex_pattern(tag):
tag_regexes = [re.compile(regex_pattern(t), re.IGNORECASE) for t in TAG_NAMES]
data = []
buffer: List[str] = []
for line, valid in lines:
while lines:
line, valid = pop(lines)
ws = ""
tokens = re.split(r"([^\S\n]+)$", line, maxsplit=1)
if len(tokens) > 1:
Expand All @@ -507,10 +515,21 @@ def regex_pattern(tag):
# 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)
if m:
value = m.group("v")
if not suffix:
bc, pc = count_brackets(value)
while (bc > 0 or pc > 0) and lines:
value += ws
line, _ = pop(lines)
tokens = re.split(r"([^\S\n]+)$", line, maxsplit=1)
if len(tokens) > 1:
line, ws, _ = tokens
value += "\n" + line
bc, pc = count_brackets(value)
data.append(
Tag(
m.group("n"),
m.group("v"),
value,
m.group("s"),
Comments.parse(buffer),
valid,
Expand All @@ -534,8 +553,10 @@ def get_raw_section_data(self) -> List[str]:
result = []
for tag in self.data:
result.extend(tag.comments.get_raw_data())
result.append(
f"{tag._prefix}{tag.name}{tag._separator}{tag.value}{tag._suffix}"
result.extend(
f"{tag._prefix}{tag.name}{tag._separator}{tag.value}{tag._suffix}".split(
"\n"
)
)
result.extend(self._remainder)
return result
28 changes: 27 additions & 1 deletion tests/unit/test_tags.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ def test_parse():
"Epoch: 1",
"%endif",
"",
"License: %{shrink:",
" MIT AND",
" (MIT OR Apache-2.0)",
" }",
"",
"Requires: make ",
"Requires(post): bash",
"",
Expand All @@ -62,6 +67,13 @@ def test_parse():
assert not tags[1].comments
assert tags.release.comments[0].prefix == " # "
assert tags.epoch.name == "Epoch"
assert tags[-6].name == "License"
assert (
tags[-6].value == "%{shrink:\n"
" MIT AND\n"
" (MIT OR Apache-2.0)\n"
" }"
)
assert tags.requires.value == "make"
assert "requires(post)" in tags
assert tags[-4].name == "Requires(post)"
Expand Down Expand Up @@ -102,11 +114,20 @@ def test_get_raw_section_data():
Comments([Comment("this is a valid comment", " # ")]),
),
Tag("Epoch", "1", ": ", Comments([], ["", "%if 0"])),
Tag(
"License",
"%{shrink:\n"
" MIT AND\n"
" (MIT OR Apache-2.0)\n"
" }",
": ",
Comments([], ["%endif", ""]),
),
Tag(
"Requires",
"make",
": ",
Comments([], ["%endif", ""]),
Comments([], [""]),
True,
"",
" ",
Expand Down Expand Up @@ -141,6 +162,11 @@ def test_get_raw_section_data():
"Epoch: 1",
"%endif",
"",
"License: %{shrink:",
" MIT AND",
" (MIT OR Apache-2.0)",
" }",
"",
"Requires: make ",
"Requires(post): bash",
"",
Expand Down

0 comments on commit b20d072

Please sign in to comment.