105 lines
3.0 KiB
Python
105 lines
3.0 KiB
Python
import os
|
|
from dataclasses import dataclass, field
|
|
from pathlib import PurePosixPath
|
|
from typing import Any
|
|
|
|
from src.container import Container
|
|
from src.recipe import Recipe
|
|
|
|
|
|
@dataclass
|
|
class RecipeContext:
|
|
"""The `self` value passed to recipe phase functions."""
|
|
|
|
recipe: Recipe
|
|
profile: dict
|
|
container: Container
|
|
jobs: int
|
|
_dest_output: str | None = None
|
|
env: dict[str, str] = field(default_factory=dict)
|
|
|
|
@property
|
|
def name(self) -> str:
|
|
return self.recipe.name
|
|
|
|
@property
|
|
def version(self) -> str:
|
|
return self.recipe.version
|
|
|
|
@property
|
|
def revision(self) -> int:
|
|
return self.recipe.revision
|
|
|
|
@property
|
|
def source_dir(self) -> PurePosixPath:
|
|
srcs = self.recipe.sources
|
|
if len(srcs) == 1:
|
|
return PurePosixPath("/sources")
|
|
raise RuntimeError(f"{self.name}: multiple sources; use self.sources")
|
|
|
|
@property
|
|
def sources(self) -> dict[str, PurePosixPath]:
|
|
srcs = self.recipe.sources
|
|
if len(srcs) == 1:
|
|
raise RuntimeError(f"{self.name}: only one source; use self.source_dir")
|
|
out: dict[str, PurePosixPath] = {}
|
|
for k in srcs.keys():
|
|
if k is None:
|
|
raise RuntimeError(f"{self.name}: multiple sources must be named")
|
|
out[k] = PurePosixPath("/sources") / k
|
|
return out
|
|
|
|
@property
|
|
def build_dir(self) -> PurePosixPath:
|
|
return PurePosixPath("/build")
|
|
|
|
@property
|
|
def sysroot(self) -> PurePosixPath:
|
|
return PurePosixPath("/sysroot")
|
|
|
|
@property
|
|
def dest_dir(self) -> PurePosixPath:
|
|
if self._dest_output is None:
|
|
raise RuntimeError("dest_dir only available during install/package phases")
|
|
return PurePosixPath("/dest") / self._dest_output
|
|
|
|
@property
|
|
def files(self) -> PurePosixPath:
|
|
if self.recipe.files_dir is None:
|
|
raise RuntimeError(f"{self.name}: no files/ dir")
|
|
return PurePosixPath("/files")
|
|
|
|
@property
|
|
def prefix(self) -> str:
|
|
return f"/tools/{self.name}" if self.recipe.kind == "host" else "/usr"
|
|
|
|
@property
|
|
def triple(self) -> str:
|
|
return self.profile["triple"]
|
|
|
|
@property
|
|
def arch(self) -> str:
|
|
return self.profile["arch"]
|
|
|
|
def run(
|
|
self,
|
|
*argv,
|
|
env: dict[str, str] | None = None,
|
|
cwd: str | os.PathLike | None = None,
|
|
) -> None:
|
|
flat: list[str] = []
|
|
for a in argv:
|
|
if isinstance(a, (PurePosixPath, os.PathLike)):
|
|
flat.append(str(a))
|
|
elif isinstance(a, bool):
|
|
raise TypeError("bool not allowed in run(); use str")
|
|
elif isinstance(a, (str, int)):
|
|
flat.append(str(a))
|
|
else:
|
|
raise TypeError(f"unsupported arg type in run(): {type(a).__name__}")
|
|
merged = dict(self.env)
|
|
if env:
|
|
merged.update(env)
|
|
cwd_s = str(cwd) if cwd is not None else "/build"
|
|
self.container.exec(flat, env=merged, cwd=cwd_s)
|