mirror of
https://github.com/arcan1s/ahriman.git
synced 2026-10-30 13:06:38 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
47158d9db4 |
No files matched your search
@@ -17,7 +17,6 @@
|
|||||||
# You should have received a copy of the GNU General Public License
|
# You should have received a copy of the GNU General Public License
|
||||||
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
import re
|
|
||||||
import shlex
|
import shlex
|
||||||
import tree_sitter_bash
|
import tree_sitter_bash
|
||||||
|
|
||||||
@@ -26,6 +25,7 @@ from enum import StrEnum
|
|||||||
from tree_sitter import Language, Node, Parser
|
from tree_sitter import Language, Node, Parser
|
||||||
from typing import IO, cast
|
from typing import IO, cast
|
||||||
|
|
||||||
|
from ahriman.core.configuration.shell_interpolator import ShellInterpolator
|
||||||
from ahriman.core.exceptions import PkgbuildParserError
|
from ahriman.core.exceptions import PkgbuildParserError
|
||||||
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
from ahriman.models.pkgbuild_patch import PkgbuildPatch
|
||||||
|
|
||||||
@@ -113,8 +113,6 @@ class PkgbuildParser(Iterable[PkgbuildPatch]):
|
|||||||
... print(patch.key, patch.value)
|
... print(patch.key, patch.value)
|
||||||
"""
|
"""
|
||||||
|
|
||||||
_BRACE_EXPANSION = re.compile(r"(.*)\{([^{}]+)\}(.*)")
|
|
||||||
|
|
||||||
def __init__(self, stream: IO[bytes]) -> None:
|
def __init__(self, stream: IO[bytes]) -> None:
|
||||||
"""
|
"""
|
||||||
Args:
|
Args:
|
||||||
@@ -122,26 +120,6 @@ class PkgbuildParser(Iterable[PkgbuildPatch]):
|
|||||||
"""
|
"""
|
||||||
self._content = stream.read()
|
self._content = stream.read()
|
||||||
|
|
||||||
@staticmethod
|
|
||||||
def _expand_array(value: str, *, expand: bool = True) -> list[str]:
|
|
||||||
"""
|
|
||||||
expand comma-separated brace expressions in a value
|
|
||||||
|
|
||||||
Args:
|
|
||||||
value(str): value that may contain a brace expression
|
|
||||||
expand(bool, optional): whether brace expansion is allowed (Default value = True)
|
|
||||||
|
|
||||||
Returns:
|
|
||||||
list[str]: expanded values if applicable
|
|
||||||
"""
|
|
||||||
match = PkgbuildParser._BRACE_EXPANSION.fullmatch(value)
|
|
||||||
# if there is no comma inside it should be treated as normal value
|
|
||||||
if match is None or not expand or "," not in match.group(2):
|
|
||||||
return [value]
|
|
||||||
|
|
||||||
prefix, values, suffix = match.groups()
|
|
||||||
return [f"{prefix}{item}{suffix}" for item in values.split(",")]
|
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def _text(node: Node) -> str:
|
def _text(node: Node) -> str:
|
||||||
"""
|
"""
|
||||||
@@ -155,6 +133,19 @@ class PkgbuildParser(Iterable[PkgbuildPatch]):
|
|||||||
"""
|
"""
|
||||||
return cast(bytes, node.text).decode("utf8", errors="backslashreplace")
|
return cast(bytes, node.text).decode("utf8", errors="backslashreplace")
|
||||||
|
|
||||||
|
@staticmethod
|
||||||
|
def _unquote(value: str) -> str:
|
||||||
|
"""
|
||||||
|
remove shell quotes and escapes from a single value
|
||||||
|
|
||||||
|
Args:
|
||||||
|
value(str): shell value to unquote
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
str: unquoted value
|
||||||
|
"""
|
||||||
|
return "".join(shlex.split(value, comments=False, posix=True))
|
||||||
|
|
||||||
def _assignment(self, node: Node) -> PkgbuildPatch:
|
def _assignment(self, node: Node) -> PkgbuildPatch:
|
||||||
"""
|
"""
|
||||||
convert an assignment node
|
convert an assignment node
|
||||||
@@ -178,14 +169,46 @@ class PkgbuildParser(Iterable[PkgbuildPatch]):
|
|||||||
case PkgbuildNodeType.Array:
|
case PkgbuildNodeType.Array:
|
||||||
array_values = []
|
array_values = []
|
||||||
for element in filter(lambda child: child.type != PkgbuildNodeType.Comment, value.named_children):
|
for element in filter(lambda child: child.type != PkgbuildNodeType.Comment, value.named_children):
|
||||||
item = self._value(element)
|
array_values.extend(self._expand_array(element))
|
||||||
values = self._expand_array(item, expand=element.type == PkgbuildNodeType.Concatenation)
|
|
||||||
array_values.extend(values)
|
|
||||||
return PkgbuildPatch(key, array_values)
|
return PkgbuildPatch(key, array_values)
|
||||||
|
|
||||||
case _:
|
case _:
|
||||||
return PkgbuildPatch(key, self._value(value))
|
return PkgbuildPatch(key, self._value(value))
|
||||||
|
|
||||||
|
def _expand_array(self, node: Node) -> list[str]:
|
||||||
|
"""
|
||||||
|
expand simple comma-separated brace groups in an array element
|
||||||
|
|
||||||
|
Args:
|
||||||
|
node(Node): array element to expand
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
list[str]: expanded element values
|
||||||
|
"""
|
||||||
|
if node.type != PkgbuildNodeType.Concatenation:
|
||||||
|
return [self._value(node)]
|
||||||
|
|
||||||
|
values = [""]
|
||||||
|
children = node.named_children
|
||||||
|
while children:
|
||||||
|
match children[:3]:
|
||||||
|
case [
|
||||||
|
Node(type=PkgbuildNodeType.Word, text=b"{"),
|
||||||
|
Node(type=PkgbuildNodeType.Word) as content,
|
||||||
|
Node(type=PkgbuildNodeType.Word, text=b"}"),
|
||||||
|
] if "," in (escaped := self._text(content).replace("\\,", ShellInterpolator.DATA_LINK_ESCAPE)):
|
||||||
|
parts = [
|
||||||
|
self._unquote(part).replace(ShellInterpolator.DATA_LINK_ESCAPE, ",")
|
||||||
|
for part in escaped.split(",")
|
||||||
|
]
|
||||||
|
children = children[3:]
|
||||||
|
|
||||||
|
case [head, *_]:
|
||||||
|
parts = [self._value(head)]
|
||||||
|
children = children[1:]
|
||||||
|
values = [prefix + part for prefix in values for part in parts]
|
||||||
|
return values
|
||||||
|
|
||||||
def _read(self, node: Node, values: dict[str | None, PkgbuildPatch]) -> Iterator[PkgbuildPatch]:
|
def _read(self, node: Node, values: dict[str | None, PkgbuildPatch]) -> Iterator[PkgbuildPatch]:
|
||||||
"""
|
"""
|
||||||
find assignments and functions in a syntax tree node
|
find assignments and functions in a syntax tree node
|
||||||
@@ -254,7 +277,7 @@ class PkgbuildParser(Iterable[PkgbuildPatch]):
|
|||||||
case _:
|
case _:
|
||||||
return value
|
return value
|
||||||
|
|
||||||
return "".join(shlex.split(value, comments=False, posix=True))
|
return self._unquote(value)
|
||||||
|
|
||||||
def parse(self) -> Iterator[PkgbuildPatch]:
|
def parse(self) -> Iterator[PkgbuildPatch]:
|
||||||
"""
|
"""
|
||||||
|
|||||||
@@ -18,9 +18,20 @@ def test_expand_array() -> None:
|
|||||||
parser = PkgbuildParser(BytesIO(b"array=(prefix{first,second}suffix)"))
|
parser = PkgbuildParser(BytesIO(b"array=(prefix{first,second}suffix)"))
|
||||||
assert list(parser.parse()) == [PkgbuildPatch("array", ["prefixfirstsuffix", "prefixsecondsuffix"])]
|
assert list(parser.parse()) == [PkgbuildPatch("array", ["prefixfirstsuffix", "prefixsecondsuffix"])]
|
||||||
|
|
||||||
|
parser = PkgbuildParser(BytesIO(br"array=(prefix{first\,second,third}suffix)"))
|
||||||
|
assert list(parser.parse()) == [PkgbuildPatch("array", ["prefixfirst,secondsuffix", "prefixthirdsuffix"])]
|
||||||
|
|
||||||
parser = PkgbuildParser(BytesIO(b"""array=("prefix{first,second}suffix")"""))
|
parser = PkgbuildParser(BytesIO(b"""array=("prefix{first,second}suffix")"""))
|
||||||
assert list(parser.parse()) == [PkgbuildPatch("array", ["prefix{first,second}suffix"])]
|
assert list(parser.parse()) == [PkgbuildPatch("array", ["prefix{first,second}suffix"])]
|
||||||
|
|
||||||
|
parser = PkgbuildParser(BytesIO(b"""array=(x"{a,b}" x'{a,b}' "{x,y}"{a,b})"""))
|
||||||
|
assert list(parser) == [PkgbuildPatch("array", ["x{a,b}", "x{a,b}", "{x,y}a", "{x,y}b"])]
|
||||||
|
|
||||||
|
parser = PkgbuildParser(BytesIO(b"""array=(${v:-a,b}suffix ${v:-a,b}{,.sig} $(echo '{a,b}')suffix)"""))
|
||||||
|
assert list(parser) == [PkgbuildPatch("array", [
|
||||||
|
"${v:-a,b}suffix", "${v:-a,b}", "${v:-a,b}.sig", "$(echo '{a,b}')suffix",
|
||||||
|
])]
|
||||||
|
|
||||||
|
|
||||||
def test_parse_append_array() -> None:
|
def test_parse_append_array() -> None:
|
||||||
"""
|
"""
|
||||||
|
|||||||
Reference in new issue
Block a user