Skip to content

Commit

Permalink
Merge pull request #568 from boehmseb/f-ArgsToken
Browse files Browse the repository at this point in the history
Adds command token for arguments.
  • Loading branch information
simbuerg authored Oct 9, 2023
2 parents e2f829b + bad9f85 commit 745eefd
Showing 1 changed file with 61 additions and 4 deletions.
65 changes: 61 additions & 4 deletions benchbuild/command.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,22 @@
LOG = logging.getLogger(__name__)


@runtime_checkable
class ArgsRenderStrategy(Protocol):
"""
Rendering strategy protocol for command line argument tokens.
"""

@property
def unrendered(self) -> str:
"""
Returns an unrendered representation of this strategy.
"""

def rendered(self, **kwargs: tp.Any) -> tp.Tuple[str, ...]:
"""Renders this strategy."""


@runtime_checkable
class PathRenderStrategy(Protocol):
"""
Expand Down Expand Up @@ -162,6 +178,36 @@ def __str__(self) -> str:
return self.unrendered


class ArgsToken:
"""
Base class for tokens that can be rendered into command-line arguments.
"""
renderer: ArgsRenderStrategy

@classmethod
def make_token(
cls, renderer: ArgsRenderStrategy
) -> 'ArgsToken':
return ArgsToken(renderer)

def __init__(self, renderer: ArgsRenderStrategy) -> None:
self.renderer = renderer

def render(self, **kwargs: tp.Any) -> tp.Tuple[str, ...]:
"""
Renders the PathToken as a standard pathlib Path.
Any kwargs will be forwarded to the PathRenderStrategy.
"""
return self.renderer.rendered(**kwargs)

def __str__(self) -> str:
return self.renderer.unrendered

def __repr__(self) -> str:
return str(self)


class PathToken:
"""
Base class used for command token substitution.
Expand Down Expand Up @@ -462,7 +508,7 @@ def _to_pathtoken(token: ArtefactPath) -> PathToken:
return token

self._path = path
self._args = tuple(str(arg) for arg in args)
self._args = tuple(args)
self._output = output

self._output_param = output_param if output_param is not None else []
Expand Down Expand Up @@ -534,6 +580,17 @@ def __call__(self, *args: tp.Any, **kwargs: tp.Any) -> tp.Any:
cmd_w_output = self.as_plumbum(**kwargs)
return watch(cmd_w_output)(*args)

def rendered_args(self, **kwargs: tp.Any) -> tp.Tuple[str, ...]:
args: tp.List[str] = []

for arg in self._args:
if isinstance(arg, ArgsToken):
args.extend(arg.render(**kwargs))
else:
args.append(str(arg))

return tuple(args)

def as_plumbum(self, **kwargs: tp.Any) -> BoundEnvCommand:
"""
Convert this command into a plumbum compatible command.
Expand All @@ -551,7 +608,7 @@ def as_plumbum(self, **kwargs: tp.Any) -> BoundEnvCommand:
assert cmd_path.exists(), f"{str(cmd_path)} doesn't exist!"

cmd = local[str(cmd_path)]
cmd_w_args = cmd[self._args]
cmd_w_args = cmd[self.rendered_args(**kwargs)]
cmd_w_output = cmd_w_args
if self.output:
output_path = self.output.render(**kwargs)
Expand All @@ -569,7 +626,7 @@ def __repr__(self) -> str:
if self._label:
repr_str = f"{self._label} {repr_str}"
if self._args:
repr_str += f" args={self._args}"
repr_str += f" args={tuple(str(arg) for arg in self._args)}"
if self._env:
repr_str += f" env={self._env}"
if self._output:
Expand All @@ -581,7 +638,7 @@ def __repr__(self) -> str:

def __str__(self) -> str:
env_str = " ".join([f"{k}={str(v)}" for k, v in self._env.items()])
args_str = " ".join(self._args)
args_str = " ".join(tuple(str(arg) for arg in self._args))

command_str = f"{self._path}"
if env_str:
Expand Down

0 comments on commit 745eefd

Please sign in to comment.