dfdf
This commit is contained in:
@@ -109,19 +109,15 @@ class SharedArgs:
|
||||
summary="Does something",
|
||||
usage="my-cmdlet",
|
||||
args=[
|
||||
SharedArgs.HASH, # Use predefined shared arg
|
||||
SharedArgs.QUERY, # Use predefined shared arg (e.g., -query "hash:<sha256>")
|
||||
SharedArgs.LOCATION, # Use another shared arg
|
||||
CmdletArg(...), # Mix with custom args
|
||||
]
|
||||
)
|
||||
"""
|
||||
|
||||
# File/Hash arguments
|
||||
HASH = CmdletArg(
|
||||
name="hash",
|
||||
type="string",
|
||||
description="File hash (SHA256, 64-char hex string)",
|
||||
)
|
||||
# NOTE: This project no longer exposes a dedicated -hash flag.
|
||||
# Use SharedArgs.QUERY with `hash:` syntax instead (e.g., -query "hash:<sha256>").
|
||||
|
||||
STORE = CmdletArg(
|
||||
name="store",
|
||||
@@ -248,7 +244,7 @@ class SharedArgs:
|
||||
QUERY = CmdletArg(
|
||||
"query",
|
||||
type="string",
|
||||
description="Search query string."
|
||||
description="Unified query string (e.g., hash:<sha256>, hash:{<h1>,<h2>})."
|
||||
)
|
||||
|
||||
REASON = CmdletArg(
|
||||
@@ -321,7 +317,7 @@ class SharedArgs:
|
||||
CmdletArg if found, None otherwise
|
||||
|
||||
Example:
|
||||
arg = SharedArgs.get('HASH') # Returns SharedArgs.HASH
|
||||
arg = SharedArgs.get('QUERY') # Returns SharedArgs.QUERY
|
||||
"""
|
||||
try:
|
||||
return getattr(cls, name.upper())
|
||||
@@ -527,6 +523,16 @@ def parse_cmdlet_args(args: Sequence[str], cmdlet_spec: Dict[str, Any] | Cmdlet)
|
||||
while i < len(args):
|
||||
token = str(args[i])
|
||||
token_lower = token.lower()
|
||||
|
||||
# Legacy guidance: -hash/--hash was removed in favor of -query "hash:...".
|
||||
# We don't error hard here because some cmdlets also accept free-form args.
|
||||
if token_lower in {"-hash", "--hash"}:
|
||||
try:
|
||||
log("Legacy flag -hash is no longer supported. Use: -query \"hash:<sha256>\"", file=sys.stderr)
|
||||
except Exception:
|
||||
pass
|
||||
i += 1
|
||||
continue
|
||||
|
||||
# Check if this token is a known flagged argument
|
||||
if token_lower in arg_spec_map:
|
||||
@@ -608,6 +614,53 @@ def normalize_hash(hash_hex: Optional[str]) -> Optional[str]:
|
||||
return text
|
||||
|
||||
|
||||
def parse_hash_query(query: Optional[str]) -> List[str]:
|
||||
"""Parse a unified query string for `hash:` into normalized SHA256 hashes.
|
||||
|
||||
Supported examples:
|
||||
- hash:<h1>
|
||||
- hash:<h1>,<h2>,<h3>
|
||||
- Hash: <h1> <h2> <h3>
|
||||
- hash:{<h1>, <h2>}
|
||||
|
||||
Returns:
|
||||
List of unique normalized 64-hex SHA256 hashes.
|
||||
"""
|
||||
import re
|
||||
|
||||
q = str(query or "").strip()
|
||||
if not q:
|
||||
return []
|
||||
|
||||
m = re.match(r"^hash(?:es)?\s*:\s*(.+)$", q, flags=re.IGNORECASE)
|
||||
if not m:
|
||||
return []
|
||||
|
||||
rest = (m.group(1) or "").strip()
|
||||
if rest.startswith("{") and rest.endswith("}"):
|
||||
rest = rest[1:-1].strip()
|
||||
if rest.startswith("[") and rest.endswith("]"):
|
||||
rest = rest[1:-1].strip()
|
||||
|
||||
raw_parts = [p.strip() for p in re.split(r"[\s,]+", rest) if p.strip()]
|
||||
out: List[str] = []
|
||||
for part in raw_parts:
|
||||
h = normalize_hash(part)
|
||||
if not h:
|
||||
continue
|
||||
if h not in out:
|
||||
out.append(h)
|
||||
return out
|
||||
|
||||
|
||||
def parse_single_hash_query(query: Optional[str]) -> Optional[str]:
|
||||
"""Parse `hash:` query and require exactly one hash."""
|
||||
hashes = parse_hash_query(query)
|
||||
if len(hashes) != 1:
|
||||
return None
|
||||
return hashes[0]
|
||||
|
||||
|
||||
def get_hash_for_operation(override_hash: Optional[str], result: Any, field_name: str = "hash") -> Optional[str]:
|
||||
"""Get normalized hash from override or result object, consolidating common pattern.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user