hh
This commit is contained in:
@@ -34,6 +34,28 @@ def _extract_title_tag(tags: List[str]) -> Optional[str]:
|
||||
return None
|
||||
|
||||
|
||||
def _extract_item_tags(res: Any) -> List[str]:
|
||||
if isinstance(res, models.PipeObject):
|
||||
raw = getattr(res, "tag", None)
|
||||
elif isinstance(res, dict):
|
||||
raw = res.get("tag")
|
||||
else:
|
||||
raw = None
|
||||
|
||||
if isinstance(raw, list):
|
||||
return [str(t) for t in raw if t is not None]
|
||||
if isinstance(raw, str) and raw.strip():
|
||||
return [raw]
|
||||
return []
|
||||
|
||||
|
||||
def _set_item_tags(res: Any, tags: List[str]) -> None:
|
||||
if isinstance(res, models.PipeObject):
|
||||
res.tag = tags
|
||||
elif isinstance(res, dict):
|
||||
res["tag"] = tags
|
||||
|
||||
|
||||
def _apply_title_to_result(res: Any, title_value: Optional[str]) -> None:
|
||||
"""Update result object/dict title fields and columns in-place."""
|
||||
if not title_value:
|
||||
@@ -332,6 +354,8 @@ class Add_Tag(Cmdlet):
|
||||
|
||||
store_override = parsed.get("store")
|
||||
|
||||
store_registry = Store(config)
|
||||
|
||||
for res in results:
|
||||
store_name: Optional[str]
|
||||
raw_hash: Optional[str]
|
||||
@@ -350,8 +374,90 @@ class Add_Tag(Cmdlet):
|
||||
continue
|
||||
|
||||
if not store_name:
|
||||
log("[add_tag] Error: Missing -store and item has no store field", file=sys.stderr)
|
||||
return 1
|
||||
store_name = None
|
||||
|
||||
# If the item isn't in a configured store backend yet (e.g., store=PATH) but has a local file,
|
||||
# treat add-tag as a pipeline mutation (carry tags forward for add-file) instead of a store write.
|
||||
if not store_override:
|
||||
store_name_str = str(store_name) if store_name is not None else ""
|
||||
local_mode_requested = (not store_name_str) or (store_name_str.upper() == "PATH") or (store_name_str.lower() == "local")
|
||||
is_known_backend = bool(store_name_str) and store_registry.is_available(store_name_str)
|
||||
|
||||
if local_mode_requested and raw_path:
|
||||
try:
|
||||
if Path(str(raw_path)).expanduser().exists():
|
||||
existing_tag_list = _extract_item_tags(res)
|
||||
existing_lower = {t.lower() for t in existing_tag_list if isinstance(t, str)}
|
||||
|
||||
item_tag_to_add = list(tag_to_add)
|
||||
item_tag_to_add = collapse_namespace_tag(item_tag_to_add, "title", prefer="last")
|
||||
|
||||
if duplicate_arg:
|
||||
parts = str(duplicate_arg).split(':')
|
||||
source_ns = ""
|
||||
targets: list[str] = []
|
||||
|
||||
if len(parts) > 1:
|
||||
source_ns = parts[0]
|
||||
targets = [t.strip() for t in parts[1].split(',') if t.strip()]
|
||||
else:
|
||||
parts2 = str(duplicate_arg).split(',')
|
||||
if len(parts2) > 1:
|
||||
source_ns = parts2[0]
|
||||
targets = [t.strip() for t in parts2[1:] if t.strip()]
|
||||
|
||||
if source_ns and targets:
|
||||
source_prefix = source_ns.lower() + ":"
|
||||
for t in existing_tag_list:
|
||||
if not t.lower().startswith(source_prefix):
|
||||
continue
|
||||
value = t.split(":", 1)[1]
|
||||
for target_ns in targets:
|
||||
new_tag = f"{target_ns}:{value}"
|
||||
if new_tag.lower() not in existing_lower:
|
||||
item_tag_to_add.append(new_tag)
|
||||
|
||||
removed_namespace_tag: list[str] = []
|
||||
for new_tag in item_tag_to_add:
|
||||
if not isinstance(new_tag, str) or ":" not in new_tag:
|
||||
continue
|
||||
ns = new_tag.split(":", 1)[0].strip()
|
||||
if not ns:
|
||||
continue
|
||||
ns_prefix = ns.lower() + ":"
|
||||
for t in existing_tag_list:
|
||||
if t.lower().startswith(ns_prefix) and t.lower() != new_tag.lower():
|
||||
removed_namespace_tag.append(t)
|
||||
removed_namespace_tag = sorted({t for t in removed_namespace_tag})
|
||||
|
||||
actual_tag_to_add = [
|
||||
t
|
||||
for t in item_tag_to_add
|
||||
if isinstance(t, str) and t.lower() not in existing_lower
|
||||
]
|
||||
|
||||
updated_tag_list = [t for t in existing_tag_list if t not in removed_namespace_tag]
|
||||
updated_tag_list.extend(actual_tag_to_add)
|
||||
|
||||
_set_item_tags(res, updated_tag_list)
|
||||
final_title = _extract_title_tag(updated_tag_list)
|
||||
_apply_title_to_result(res, final_title)
|
||||
|
||||
total_added += len(actual_tag_to_add)
|
||||
total_modified += 1 if (removed_namespace_tag or actual_tag_to_add) else 0
|
||||
|
||||
ctx.emit(res)
|
||||
continue
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
if local_mode_requested:
|
||||
log("[add_tag] Error: Missing usable local path for tagging (or provide -store)", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
if store_name_str and not is_known_backend:
|
||||
log(f"[add_tag] Error: Unknown store '{store_name_str}'. Available: {store_registry.list_backends()}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
resolved_hash = normalize_hash(hash_override) if hash_override else normalize_hash(raw_hash)
|
||||
if not resolved_hash and raw_path:
|
||||
@@ -371,7 +477,7 @@ class Add_Tag(Cmdlet):
|
||||
continue
|
||||
|
||||
try:
|
||||
backend = Store(config)[str(store_name)]
|
||||
backend = store_registry[str(store_name)]
|
||||
except Exception as exc:
|
||||
log(f"[add_tag] Error: Unknown store '{store_name}': {exc}", file=sys.stderr)
|
||||
return 1
|
||||
|
||||
Reference in New Issue
Block a user