cmdlet refactor
This commit is contained in:
+79
-36
@@ -1282,15 +1282,30 @@ class PipelineExecutor:
|
||||
def _norm(name: str) -> str:
|
||||
return str(name or "").replace("_", "-").strip().lower()
|
||||
|
||||
def _file_action(stage_tokens: List[str]) -> str | None:
|
||||
if not stage_tokens:
|
||||
return None
|
||||
head = _norm(stage_tokens[0])
|
||||
if head in {"download-file", "add-file"}:
|
||||
return head
|
||||
if head != "file":
|
||||
return None
|
||||
args = {_norm(t) for t in stage_tokens[1:]}
|
||||
if "-download" in args or "--download" in args or "-dl" in args or "--dl" in args:
|
||||
return "download-file"
|
||||
if "-add" in args or "--add" in args:
|
||||
return "add-file"
|
||||
return None
|
||||
|
||||
names: List[str] = []
|
||||
for stage in stages or []:
|
||||
if not stage:
|
||||
continue
|
||||
names.append(_norm(stage[0]))
|
||||
|
||||
dl_idxs = [i for i, n in enumerate(names) if n == "download-file"]
|
||||
dl_idxs = [i for i, stage in enumerate(stages or []) if _file_action(stage or []) == "download-file"]
|
||||
rel_idxs = [i for i, n in enumerate(names) if n == "add-relationship"]
|
||||
add_file_idxs = [i for i, n in enumerate(names) if n == "add-file"]
|
||||
add_file_idxs = [i for i, stage in enumerate(stages or []) if _file_action(stage or []) == "add-file"]
|
||||
|
||||
if not dl_idxs or not rel_idxs:
|
||||
return True
|
||||
@@ -1981,6 +1996,23 @@ class PipelineExecutor:
|
||||
def _norm_cmd_name(value: Any) -> str:
|
||||
return str(value or "").replace("_", "-").strip().lower()
|
||||
|
||||
def _stage_file_action(stage_tokens: Sequence[Any]) -> str | None:
|
||||
if not stage_tokens:
|
||||
return None
|
||||
head = _norm_cmd_name(stage_tokens[0])
|
||||
if head in {"add-file", "download-file", "delete-file"}:
|
||||
return head
|
||||
if head != "file":
|
||||
return None
|
||||
args = {_norm_cmd_name(t) for t in stage_tokens[1:]}
|
||||
if "-add" in args or "--add" in args:
|
||||
return "add-file"
|
||||
if "-download" in args or "--download" in args or "-dl" in args or "--dl" in args:
|
||||
return "download-file"
|
||||
if "-delete" in args or "--delete" in args or "-del" in args or "--del" in args:
|
||||
return "delete-file"
|
||||
return None
|
||||
|
||||
# ============================================================================
|
||||
# PHASE 2: Parse source command and table metadata
|
||||
# ============================================================================
|
||||
@@ -2333,8 +2365,8 @@ class PipelineExecutor:
|
||||
# ====================================================================
|
||||
if not stages:
|
||||
if isinstance(table_type, str) and table_type.startswith("metadata."):
|
||||
print("Auto-applying metadata selection via get-tag")
|
||||
stages.append(["get-tag"])
|
||||
print("Auto-applying metadata selection via metadata -get")
|
||||
stages.append(["metadata", "-get"])
|
||||
elif auto_stage:
|
||||
try:
|
||||
print(f"Auto-running selection via {auto_stage[0]}")
|
||||
@@ -2383,12 +2415,12 @@ class PipelineExecutor:
|
||||
first_cmd_norm = _norm_cmd_name(first_cmd)
|
||||
|
||||
inserted_provider_download = False
|
||||
if first_cmd_norm == "add-file":
|
||||
if _stage_file_action(stages[0]) == "add-file":
|
||||
# If selected rows advertise an explicit download-file action,
|
||||
# run download before add-file so add-file receives local files.
|
||||
if len(selection_indices) == 1:
|
||||
row_action = _get_row_action(selection_indices[0], items_list)
|
||||
if row_action and _norm_cmd_name(row_action[0]) == "download-file":
|
||||
if row_action and _stage_file_action(row_action) == "download-file":
|
||||
stages.insert(0, [str(x) for x in row_action if x is not None])
|
||||
inserted_provider_download = True
|
||||
debug("Auto-inserting row download-file action before add-file")
|
||||
@@ -2401,24 +2433,24 @@ class PipelineExecutor:
|
||||
has_download_row_action = False
|
||||
for idx in selection_indices:
|
||||
row_action = _get_row_action(idx, items_list)
|
||||
if row_action and _norm_cmd_name(row_action[0]) == "download-file":
|
||||
if row_action and _stage_file_action(row_action) == "download-file":
|
||||
has_download_row_action = True
|
||||
break
|
||||
if has_download_row_action:
|
||||
stages.insert(0, ["download-file"])
|
||||
stages.insert(0, ["file", "-download"])
|
||||
inserted_provider_download = True
|
||||
debug("Auto-inserting download-file before add-file for provider selection")
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if isinstance(table_type, str) and table_type.startswith("metadata.") and first_cmd not in (
|
||||
"get-tag",
|
||||
"get_tag",
|
||||
"metadata",
|
||||
"tag",
|
||||
".pipe",
|
||||
".mpv",
|
||||
):
|
||||
print("Auto-inserting get-tag after metadata selection")
|
||||
stages.insert(0, ["get-tag"])
|
||||
print("Auto-inserting metadata -get after metadata selection")
|
||||
stages.insert(0, ["metadata", "-get"])
|
||||
elif auto_stage:
|
||||
first_cmd_norm = _norm_cmd_name(stages[0][0] if stages and stages[0] else None)
|
||||
auto_cmd_norm = _norm_cmd_name(auto_stage[0])
|
||||
@@ -2513,8 +2545,7 @@ class PipelineExecutor:
|
||||
|
||||
# add-file directory selector stage: avoid Live progress so the
|
||||
# selection table renders cleanly.
|
||||
if name in {"add-file",
|
||||
"add_file"}:
|
||||
if _stage_file_action(stage_tokens) == "add-file" or name in {"add_file"}:
|
||||
try:
|
||||
from pathlib import Path as _Path
|
||||
|
||||
@@ -2559,8 +2590,7 @@ class PipelineExecutor:
|
||||
continue
|
||||
# `delete-file` prints a Rich table directly; Live progress interferes and
|
||||
# can truncate/overwrite the output.
|
||||
if name in {"delete-file",
|
||||
"del-file"}:
|
||||
if _stage_file_action(stage_tokens) == "delete-file" or name in {"del-file"}:
|
||||
continue
|
||||
pipe_stage_indices.append(idx)
|
||||
pipe_labels.append(name)
|
||||
@@ -2707,7 +2737,7 @@ class PipelineExecutor:
|
||||
stage_args = stage_tokens[1:]
|
||||
|
||||
if cmd_name == "@":
|
||||
# Special-case get-tag tables: `@ | add-tag ...` should target the
|
||||
# Special-case metadata -get tables: `@ | metadata -add ...` should target the
|
||||
# underlying file subject once, not each emitted TagItem row.
|
||||
try:
|
||||
next_cmd = None
|
||||
@@ -2721,28 +2751,36 @@ class PipelineExecutor:
|
||||
current_table = None
|
||||
|
||||
source_cmd = str(getattr(current_table, "source_command", "") or "").replace("_", "-").strip().lower()
|
||||
is_get_tag_table = source_cmd == "get-tag"
|
||||
is_get_tag_table = source_cmd == "metadata"
|
||||
|
||||
if is_get_tag_table and next_cmd in {"add-tag"}:
|
||||
if is_get_tag_table and next_cmd == "metadata":
|
||||
subject = ctx.get_last_result_subject()
|
||||
if subject is not None:
|
||||
piped_result = subject
|
||||
try:
|
||||
subject_items = subject if isinstance(subject, list) else [subject]
|
||||
ctx.set_last_items(subject_items)
|
||||
except Exception:
|
||||
logger.exception("Failed to set last_items from get-tag subject during @ handling")
|
||||
if pipeline_session and worker_manager:
|
||||
next_args = [
|
||||
str(x).replace("_", "-").strip().lower()
|
||||
for x in (stages[stage_index + 1][1:] if stage_index + 1 < len(stages) else [])
|
||||
]
|
||||
if "-add" not in next_args and "--add" not in next_args:
|
||||
# Only apply this flattening for explicit tag-add pipelines.
|
||||
pass
|
||||
else:
|
||||
piped_result = subject
|
||||
try:
|
||||
worker_manager.log_step(
|
||||
pipeline_session.worker_id,
|
||||
"@ used get-tag table subject for add-tag"
|
||||
)
|
||||
subject_items = subject if isinstance(subject, list) else [subject]
|
||||
ctx.set_last_items(subject_items)
|
||||
except Exception:
|
||||
logger.exception("Failed to record pipeline log step for '@ used get-tag table subject for add-tag' (pipeline_session=%r)", getattr(pipeline_session, 'worker_id', None))
|
||||
continue
|
||||
logger.exception("Failed to set last_items from tag subject during @ handling")
|
||||
if pipeline_session and worker_manager:
|
||||
try:
|
||||
worker_manager.log_step(
|
||||
pipeline_session.worker_id,
|
||||
"@ used metadata table subject for metadata -add"
|
||||
)
|
||||
except Exception:
|
||||
logger.exception("Failed to record pipeline log step for '@ used metadata table subject for metadata -add' (pipeline_session=%r)", getattr(pipeline_session, 'worker_id', None))
|
||||
continue
|
||||
except Exception:
|
||||
logger.exception("Failed to evaluate get-tag @ subject special-case")
|
||||
logger.exception("Failed to evaluate tag @ subject special-case")
|
||||
|
||||
# Prefer piping the last emitted/visible items (e.g. add-file results)
|
||||
# over the result-table subject. The subject can refer to older context
|
||||
@@ -2962,17 +3000,23 @@ class PipelineExecutor:
|
||||
stage_is_last=(stage_index + 1 >= len(stages))):
|
||||
return
|
||||
|
||||
# Special case: selecting multiple tags from get-tag and piping into delete-tag
|
||||
# Special case: selecting multiple metadata tag rows and piping into metadata -delete
|
||||
# should batch into a single operation (one backend call).
|
||||
next_cmd = None
|
||||
next_args: List[str] = []
|
||||
try:
|
||||
if stage_index + 1 < len(stages) and stages[stage_index + 1]:
|
||||
next_cmd = str(stages[stage_index + 1][0]
|
||||
).replace("_",
|
||||
"-").lower()
|
||||
next_args = [
|
||||
str(x).replace("_", "-").strip().lower()
|
||||
for x in stages[stage_index + 1][1:]
|
||||
]
|
||||
except Exception:
|
||||
logger.exception("Failed to determine next_cmd during selection expansion for stage_index %s", stage_index)
|
||||
next_cmd = None
|
||||
next_args = []
|
||||
|
||||
def _is_tag_row(obj: Any) -> bool:
|
||||
try:
|
||||
@@ -2991,8 +3035,7 @@ class PipelineExecutor:
|
||||
logger.exception("Failed to inspect dict tag_name while checking _is_tag_row")
|
||||
return False
|
||||
|
||||
if (next_cmd in {"delete-tag",
|
||||
"delete_tag"} and len(filtered) > 1
|
||||
if (next_cmd == "tag" and ("-delete" in next_args or "--delete" in next_args) and len(filtered) > 1
|
||||
and all(_is_tag_row(x) for x in filtered)):
|
||||
from SYS.field_access import get_field
|
||||
|
||||
|
||||
Reference in New Issue
Block a user