try to improve parser

This commit is contained in:
Evgenii Alekseev 2024-09-12 03:26:38 +03:00
parent 4938f8ffe7
commit 405af4da5b
3 changed files with 21 additions and 28 deletions

View File

@ -96,12 +96,13 @@ class Task(LazyLogging):
if self.include_debug_packages or not package.name.startswith(debug_package_prefix)
]
def build(self, sources_dir: Path, **kwargs: str | None) -> list[Path]:
def build(self, sources_dir: Path, *, dry_run: bool = False, **kwargs: str | None) -> list[Path]:
"""
run package build
Args:
sources_dir(Path): path to where sources are
dry_run(bool, optional): do not perform build itself (Default value = False)
**kwargs(str | None): environment variables to be passed to build processes
Returns:
@ -111,6 +112,8 @@ class Task(LazyLogging):
command.extend(self.archbuild_flags)
command.extend(["--"] + self.makechrootpkg_flags)
command.extend(["--"] + self.makepkg_flags)
if dry_run:
command.extend(["--nobuild"])
self.logger.info("using %s for %s", command, self.package.base)
environment: dict[str, str] = {
@ -157,25 +160,3 @@ class Task(LazyLogging):
patch.write(sources_dir / "PKGBUILD")
return last_commit_sha
def setup(self, sources_dir: Path) -> None:
"""
setup chroot environment without building package itself. This function, in particular, useful in case if it is
required to refresh pkgver to the actual value without package building
Args:
sources_dir(Path): path to where sources are
"""
command = [self.build_command, "-r", str(self.paths.chroot)]
command.extend(self.archbuild_flags)
command.extend(["--"] + self.makechrootpkg_flags)
command.extend(["--"] + self.makepkg_flags + ["--nobuild"])
self.logger.info("using %s for %s", command, self.package.base)
check_output(
*command,
exception=BuildError.from_process(self.package.base),
cwd=sources_dir,
logger=self.logger,
user=self.uid,
)

View File

@ -435,7 +435,7 @@ class Package(LazyLogging):
try:
# create fresh chroot environment, fetch sources and - automagically - update PKGBUILD
task.init(paths.cache_for(self.base), [], None)
task.setup(paths.cache_for(self.base))
task.build(paths.cache_for(self.base), dry_run=False)
pkgbuild = Pkgbuild.from_file(paths.cache_for(self.base) / "PKGBUILD")

View File

@ -39,11 +39,11 @@ class PkgbuildToken(StrEnum):
well-known tokens dictionary
Attributes:
ArrayStarts(PkgbuildToken): (class attribute) array starts token
ArrayEnds(PkgbuildToken): (class attribute) array ends token
ArrayStarts(PkgbuildToken): (class attribute) array starts token
FunctionDeclaration(PkgbuildToken): (class attribute) function declaration token
FunctionStarts(PkgbuildToken): (class attribute) function starts token
FunctionEnds(PkgbuildToken): (class attribute) function ends token
FunctionStarts(PkgbuildToken): (class attribute) function starts token
"""
ArrayStarts = "("
@ -113,6 +113,10 @@ class Pkgbuild(Mapping[str, str | list[str]]):
fields = {}
parser = shlex.shlex(stream, posix=True, punctuation_chars=True)
# ignore substitution and extend bash symbols
parser.wordchars += "${}#:+"
# in case of default behaviour, it will ignore, for example, segment part of url outside of quotes
parser.commenters = ""
while token := parser.get_token():
try:
key, value = cls._parse_token(token, parser)
@ -180,7 +184,7 @@ class Pkgbuild(Mapping[str, str | list[str]]):
raise ValueError("Function body wasn't found")
# read the specified interval from source stream
io.seek(start_position - 1) # start from the previous symbol ({)
io.seek(start_position - 1) # start from the previous symbol ("{")
content = io.read(end_position - start_position + 1)
return content
@ -198,7 +202,7 @@ class Pkgbuild(Mapping[str, str | list[str]]):
tuple[str, PkgbuildPatch]: extracted a pair of key and its value
Raises:
StopIteration: if iteration reaches the end of the file'
StopIteration: if iteration reaches the end of the file
"""
# simple assignment rule
if (match := Pkgbuild._STRING_ASSIGNMENT.match(token)) is not None:
@ -219,6 +223,14 @@ class Pkgbuild(Mapping[str, str | list[str]]):
value = Pkgbuild._parse_function(parser)
return token, PkgbuildPatch(key, value) # this is not mistake, assign to token without ()
# special function case, where "(" and ")" are separated tokens, e.g. "pkgver ( )"
case PkgbuildToken.ArrayStarts if Pkgbuild._FUNCTION_DECLARATION.match(token):
next_token = parser.get_token()
if next_token == PkgbuildToken.ArrayEnds: # replace closing bracket with "()"
next_token = PkgbuildToken.FunctionDeclaration
parser.push_token(next_token) # type: ignore[arg-type]
return Pkgbuild._parse_token(token, parser)
# some random token received without continuation, lets guess it is empty assignment (i.e. key=)
case other if other is not None:
return Pkgbuild._parse_token(other, parser)