Properly handle extra and operands
This commit is contained in:
parent
2268f94d1f
commit
cc9f7c7b3f
6 changed files with 71 additions and 26 deletions
|
@ -95,7 +95,6 @@ def main() -> int:
|
|||
except RuntimeError as e:
|
||||
logging.exception(e)
|
||||
vt100.error(str(e))
|
||||
cli.usage()
|
||||
return 1
|
||||
|
||||
except KeyboardInterrupt:
|
||||
|
|
|
@ -389,7 +389,7 @@ def _():
|
|||
|
||||
|
||||
class BuildArgs(model.TargetArgs):
|
||||
component: str = cli.operand("component", "Component to build")
|
||||
component: str = cli.operand("component", "Component to build", default="__main__")
|
||||
|
||||
|
||||
@cli.command("b", "builder/build", "Build a component or all components")
|
||||
|
@ -409,16 +409,14 @@ class RunArgs(BuildArgs, shell.DebugArgs, shell.ProfileArgs):
|
|||
|
||||
@cli.command("r", "builder/run", "Run a component")
|
||||
def runCmd(args: RunArgs):
|
||||
componentSpec = args.consumeArg() or "__main__"
|
||||
|
||||
args.props |= {"debug": args.debug}
|
||||
scope = TargetScope.use(args)
|
||||
|
||||
component = scope.registry.lookup(
|
||||
componentSpec, model.Component, includeProvides=True
|
||||
args.component, model.Component, includeProvides=True
|
||||
)
|
||||
if component is None:
|
||||
raise RuntimeError(f"Component {componentSpec} not found")
|
||||
raise RuntimeError(f"Component {args.component} not found")
|
||||
|
||||
product = build(scope, component)[0]
|
||||
|
||||
|
|
|
@ -383,8 +383,8 @@ def arg(
|
|||
return Field(FieldKind.FLAG, shortName, longName, description, default)
|
||||
|
||||
|
||||
def operand(longName: str = "", description: str = "") -> Any:
|
||||
return Field(FieldKind.OPERAND, None, longName, description)
|
||||
def operand(longName: str = "", description: str = "", default: Any = None) -> Any:
|
||||
return Field(FieldKind.OPERAND, None, longName, description, default)
|
||||
|
||||
|
||||
def extra(longName: str = "", description: str = "") -> Any:
|
||||
|
@ -475,8 +475,14 @@ class Schema:
|
|||
return arg
|
||||
raise ValueError(f"Unknown argument '{key}'")
|
||||
|
||||
def _setOperand(self, tok: OperandToken):
|
||||
return
|
||||
def _setOperand(self, obj: Any, value: Any):
|
||||
if len(self.operands) == 0:
|
||||
raise ValueError(f"Unexpected operand '{value}'")
|
||||
|
||||
for operand in self.operands:
|
||||
if operand.getAttr(obj) is None or operand.isList():
|
||||
operand.putValue(obj, value)
|
||||
return
|
||||
|
||||
def _instanciate(self) -> Any:
|
||||
if self.typ is None:
|
||||
|
@ -484,6 +490,16 @@ class Schema:
|
|||
res = self.typ()
|
||||
for arg in self.args:
|
||||
arg.setDefault(res)
|
||||
|
||||
for operand in self.operands:
|
||||
if operand.isList():
|
||||
setattr(res, operand._fieldName, [])
|
||||
else:
|
||||
setattr(res, operand._fieldName, None)
|
||||
|
||||
if self.extras:
|
||||
self.extras.setDefault(res)
|
||||
|
||||
return res
|
||||
|
||||
def parse(self, args: list[str]) -> Any:
|
||||
|
@ -499,7 +515,7 @@ class Schema:
|
|||
if stack[0] == "--":
|
||||
if not self.extras:
|
||||
raise ValueError("Unexpected '--'")
|
||||
self._setExtra(res, stack.pop(0))
|
||||
self.extras.putValue(res, stack[1:])
|
||||
break
|
||||
|
||||
toks = parseArg(stack.pop(0))
|
||||
|
@ -508,7 +524,7 @@ class Schema:
|
|||
arg = self._lookupArg(tok.key, tok.short)
|
||||
arg.putValue(res, tok.value, tok.subkey)
|
||||
elif isinstance(tok, OperandToken):
|
||||
self._setOperand(tok)
|
||||
self._setOperand(res, tok.value)
|
||||
else:
|
||||
raise ValueError(f"Unexpected token: {type(tok)}")
|
||||
|
||||
|
@ -634,10 +650,14 @@ class Command:
|
|||
self.callable()
|
||||
|
||||
if self.subcommands:
|
||||
if len(rest) == 0 and not self.populated:
|
||||
raise ValueError("Expected subcommand")
|
||||
if len(rest) > 0:
|
||||
if not self.populated:
|
||||
raise ValueError("Expected subcommand")
|
||||
else:
|
||||
self.lookupSubcommand(rest[0]).eval(rest)
|
||||
else:
|
||||
self.lookupSubcommand(rest[0]).eval(rest)
|
||||
print("Usage: " + cmd + self.usage(), end="\n\n")
|
||||
return
|
||||
elif len(rest) > 0:
|
||||
raise ValueError(f"Unknown operand '{rest[0]}'")
|
||||
|
||||
|
|
|
@ -56,5 +56,5 @@ class PluginsArgs:
|
|||
|
||||
|
||||
def setup(args: PluginsArgs):
|
||||
if args.safemod:
|
||||
if not args.safemod:
|
||||
loadAll()
|
||||
|
|
|
@ -467,8 +467,11 @@ def _(args: _ProfileArgs):
|
|||
profile(args.fullCmd(), rate=args.rate, what=args.what)
|
||||
|
||||
|
||||
class CompresseArgs:
|
||||
class CompressFormatArg:
|
||||
format: str = cli.arg(None, "format", "The compression format", default="zstd")
|
||||
|
||||
|
||||
class CompresseArgs(CompressFormatArg):
|
||||
dest: Optional[str] = cli.arg(None, "dest", "The destination file or directory")
|
||||
path: str = cli.operand("path", "The file or directory to compress")
|
||||
|
||||
|
|
|
@ -211,15 +211,6 @@ def test_cli_arg_dict_str():
|
|||
)
|
||||
|
||||
|
||||
class StrOptArg:
|
||||
value: str | None = cli.arg(None, "value")
|
||||
|
||||
|
||||
def test_cli_arg_str_opt():
|
||||
assert_equal(extractParse(StrOptArg, []).value, None)
|
||||
assert_equal(extractParse(StrOptArg, ["--value=foo"]).value, "foo")
|
||||
|
||||
|
||||
class FooArg:
|
||||
foo: str = cli.arg(None, "foo")
|
||||
|
||||
|
@ -237,3 +228,37 @@ def test_cli_arg_inheritance():
|
|||
assert_equal(res.foo, "foo")
|
||||
assert_equal(res.bar, "bar")
|
||||
assert_equal(res.baz, "baz")
|
||||
|
||||
|
||||
class ExtraArg:
|
||||
value: str = cli.arg(None, "value")
|
||||
extra: list[str] = cli.extra("extra")
|
||||
|
||||
|
||||
def test_cli_extra_args():
|
||||
res = extractParse(ExtraArg, ["--value=foo", "--", "bar", "baz"])
|
||||
assert_equal(res.value, "foo")
|
||||
assert_equal(res.extra, ["bar", "baz"])
|
||||
|
||||
|
||||
class StrOperandArg:
|
||||
value: str = cli.operand(None, "value")
|
||||
|
||||
|
||||
def test_cli_operand_args():
|
||||
res = extractParse(StrOperandArg, ["foo"])
|
||||
assert_equal(res.value, "foo")
|
||||
|
||||
|
||||
class ListOperandArg:
|
||||
value: list[str] = cli.operand(None, "value")
|
||||
|
||||
|
||||
def test_cli_operand_list_args():
|
||||
res = extractParse(ListOperandArg, ["foo", "bar"])
|
||||
assert_equal(res.value, ["foo", "bar"])
|
||||
|
||||
|
||||
def test_cli_operand_list_args_empty():
|
||||
res = extractParse(ListOperandArg, [])
|
||||
assert_equal(res.value, [])
|
||||
|
|
Loading…
Reference in a new issue