dfd
Some checks failed
smoke-mm / Install & smoke test mm --help (push) Has been cancelled
Some checks failed
smoke-mm / Install & smoke test mm --help (push) Has been cancelled
This commit is contained in:
@@ -39,6 +39,16 @@ class CmdletArg:
|
||||
requires_db: bool = False
|
||||
"""Whether this argument requires the local DB/library root to be configured."""
|
||||
|
||||
# Query-mapping support:
|
||||
# Some cmdlets use a unified `-query` string. When configured, individual args
|
||||
# can be populated from fields inside `-query` (e.g., -query "hash:<sha256>").
|
||||
query_key: Optional[str] = None
|
||||
"""Field name inside -query that maps to this argument (e.g., 'hash')."""
|
||||
query_aliases: List[str] = field(default_factory=list)
|
||||
"""Additional field names inside -query that map to this argument."""
|
||||
query_only: bool = False
|
||||
"""When True, do not accept a dedicated CLI flag for this arg; only map from -query."""
|
||||
|
||||
def resolve(self, value: Any) -> Any:
|
||||
"""Resolve/process the argument value using the handler if available.
|
||||
|
||||
@@ -95,6 +105,37 @@ class CmdletArg:
|
||||
return tuple(flags)
|
||||
|
||||
|
||||
def QueryArg(
|
||||
name: str,
|
||||
*,
|
||||
key: Optional[str] = None,
|
||||
aliases: Optional[Sequence[str]] = None,
|
||||
type: str = "string",
|
||||
required: bool = False,
|
||||
description: str = "",
|
||||
choices: Optional[Sequence[str]] = None,
|
||||
handler: Optional[Any] = None,
|
||||
query_only: bool = True,
|
||||
) -> CmdletArg:
|
||||
"""Create an argument that can be populated from `-query` fields.
|
||||
|
||||
By default, this does NOT create a dedicated flag (query_only=True). This is
|
||||
useful for deprecating bloat flags like `-hash` while still making `hash:` a
|
||||
first-class, documented, reusable field.
|
||||
"""
|
||||
return CmdletArg(
|
||||
name=str(name),
|
||||
type=str(type or "string"),
|
||||
required=bool(required),
|
||||
description=str(description or ""),
|
||||
choices=list(choices or []),
|
||||
handler=handler,
|
||||
query_key=str(key or name).strip().lower() if str(key or name).strip() else None,
|
||||
query_aliases=[str(a).strip().lower() for a in (aliases or []) if str(a).strip()],
|
||||
query_only=bool(query_only),
|
||||
)
|
||||
|
||||
|
||||
# ============================================================================
|
||||
# SHARED ARGUMENTS - Reusable argument definitions across cmdlet
|
||||
# ============================================================================
|
||||
@@ -127,6 +168,7 @@ class SharedArgs:
|
||||
type="enum",
|
||||
choices=[], # Dynamically populated via get_store_choices()
|
||||
description="Selects store",
|
||||
query_key="store",
|
||||
)
|
||||
|
||||
PATH = CmdletArg(
|
||||
@@ -497,6 +539,7 @@ def parse_cmdlet_args(args: Sequence[str], cmdlet_spec: Dict[str, Any] | Cmdlet)
|
||||
arg_specs: List[CmdletArg] = cmdlet_spec.arg
|
||||
positional_args: List[CmdletArg] = [] # args without prefix in definition
|
||||
flagged_args: List[CmdletArg] = [] # args with prefix in definition
|
||||
query_mapped_args: List[CmdletArg] = []
|
||||
|
||||
arg_spec_map: Dict[str, str] = {} # prefix variant -> canonical name (without prefix)
|
||||
|
||||
@@ -504,9 +547,23 @@ def parse_cmdlet_args(args: Sequence[str], cmdlet_spec: Dict[str, Any] | Cmdlet)
|
||||
name = spec.name
|
||||
if not name:
|
||||
continue
|
||||
|
||||
# Track args that can be populated from -query.
|
||||
try:
|
||||
if getattr(spec, "query_key", None):
|
||||
query_mapped_args.append(spec)
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
name_str = str(name)
|
||||
canonical_name = name_str.lstrip("-")
|
||||
|
||||
# Query-only args do not register dedicated flags/positionals.
|
||||
try:
|
||||
if bool(getattr(spec, "query_only", False)):
|
||||
continue
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
# Determine if this is positional (no dashes in original definition)
|
||||
if "-" not in name_str:
|
||||
@@ -592,7 +649,49 @@ def parse_cmdlet_args(args: Sequence[str], cmdlet_spec: Dict[str, Any] | Cmdlet)
|
||||
else:
|
||||
# Unknown token, skip it
|
||||
i += 1
|
||||
|
||||
|
||||
# Populate query-mapped args from the unified -query string.
|
||||
try:
|
||||
raw_query = result.get("query")
|
||||
except Exception:
|
||||
raw_query = None
|
||||
|
||||
if query_mapped_args and raw_query is not None:
|
||||
try:
|
||||
from cli_syntax import parse_query as _parse_query
|
||||
parsed_query = _parse_query(str(raw_query))
|
||||
fields = parsed_query.get("fields", {}) if isinstance(parsed_query, dict) else {}
|
||||
norm_fields = {str(k).strip().lower(): v for k, v in fields.items()} if isinstance(fields, dict) else {}
|
||||
except Exception:
|
||||
norm_fields = {}
|
||||
|
||||
for spec in query_mapped_args:
|
||||
canonical_name = str(getattr(spec, "name", "") or "").lstrip("-")
|
||||
if not canonical_name:
|
||||
continue
|
||||
# Do not override explicit flags.
|
||||
if canonical_name in result and result.get(canonical_name) not in (None, ""):
|
||||
continue
|
||||
try:
|
||||
key = str(getattr(spec, "query_key", "") or "").strip().lower()
|
||||
aliases = getattr(spec, "query_aliases", None)
|
||||
alias_list = [str(a).strip().lower() for a in (aliases or []) if str(a).strip()]
|
||||
except Exception:
|
||||
key = ""
|
||||
alias_list = []
|
||||
candidates = [k for k in [key, canonical_name] + alias_list if k]
|
||||
val = None
|
||||
for k in candidates:
|
||||
if k in norm_fields:
|
||||
val = norm_fields.get(k)
|
||||
break
|
||||
if val is None:
|
||||
continue
|
||||
try:
|
||||
result[canonical_name] = spec.resolve(val)
|
||||
except Exception:
|
||||
result[canonical_name] = val
|
||||
|
||||
return result
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user