mirror of
https://github.com/forcedotcom/afv-library.git
synced 2026-07-31 04:01:24 +08:00
99 lines
3.3 KiB
Python
99 lines
3.3 KiB
Python
"""Shared CLI override helper for d360 entry scripts.
|
|
|
|
D360 has 5 independent entry scripts (``fetch_dc.py``, ``assemble_dc.py``,
|
|
``render_dc.py``, ``resolve_session.py``, ``discover_sessions.py``) — each
|
|
needs the same ``--data-dir`` / ``--cache-dir`` flags and the same
|
|
3-level namespace rebind. This module factors that duplication into one
|
|
helper.
|
|
|
|
Usage in each entry script::
|
|
|
|
from _shared.cli_override import add_cli_flags, apply_overrides
|
|
|
|
parser = argparse.ArgumentParser(...)
|
|
parser.add_argument(...)
|
|
add_cli_flags(parser)
|
|
args = parser.parse_args()
|
|
apply_overrides(args, caller_globals=globals())
|
|
|
|
The ``caller_globals=globals()`` parameter is the magic that lets us
|
|
rebind the entry script's own ``DATA_ROOT`` / ``CACHE_ROOT`` snapshot —
|
|
without it, only ``paths.X`` and ``config.X`` would update, and the
|
|
entry script's local ``DATA_ROOT`` would still point at the default.
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import argparse
|
|
from pathlib import Path
|
|
|
|
_SKILL_NAME = "investigating-agentforce-d360"
|
|
|
|
|
|
def add_cli_flags(parser: argparse.ArgumentParser) -> None:
|
|
"""Add --data-dir / --cache-dir flags to the given parser.
|
|
|
|
Defaults are runtime-agnostic (``~/.vibe/...``); other
|
|
runtimes (AFV OOTB, Codex, Cursor, OpenCode) override at invocation
|
|
time.
|
|
"""
|
|
parser.add_argument(
|
|
"--data-dir",
|
|
type=Path,
|
|
default=None,
|
|
help=(
|
|
"Override data root (default: "
|
|
"~/.vibe/data/investigating-agentforce-d360)."
|
|
),
|
|
)
|
|
parser.add_argument(
|
|
"--cache-dir",
|
|
type=Path,
|
|
default=None,
|
|
help=(
|
|
"Override cache root (default: "
|
|
"~/.vibe/cache/investigating-agentforce-d360)."
|
|
),
|
|
)
|
|
|
|
|
|
def apply_overrides(args: argparse.Namespace, caller_globals: dict) -> None:
|
|
"""Apply --data-dir / --cache-dir overrides across all 3 namespace levels.
|
|
|
|
Must be called BEFORE any pipeline code reads ``DATA_ROOT`` or
|
|
``CACHE_ROOT``.
|
|
|
|
Levels rebound:
|
|
1. ``paths.DATA_ROOT`` (the source of truth)
|
|
2. ``config.DATA_ROOT`` (the re-export)
|
|
3. The caller's own local ``DATA_ROOT`` (via ``caller_globals``)
|
|
|
|
Why 3 levels? Python's ``from X import Y`` snapshots ``Y`` into the
|
|
caller's local namespace at import time. Mutating ``X.Y`` later does
|
|
NOT update the caller's local binding. Without the 3rd-level rebind,
|
|
any function in the caller that references ``DATA_ROOT`` still sees
|
|
the default path even after ``paths.DATA_ROOT`` was overridden.
|
|
"""
|
|
if not (args.data_dir or args.cache_dir):
|
|
return
|
|
|
|
from _shared import runtime, paths
|
|
import config
|
|
|
|
if args.data_dir:
|
|
runtime.set_data_root_override(args.data_dir)
|
|
new_data = runtime.resolve_data_root(_SKILL_NAME)
|
|
paths.DATA_ROOT = new_data
|
|
config.DATA_ROOT = new_data
|
|
# Rebind caller's local snapshot, if it captured DATA_ROOT.
|
|
if "DATA_ROOT" in caller_globals:
|
|
caller_globals["DATA_ROOT"] = new_data
|
|
|
|
if args.cache_dir:
|
|
runtime.set_cache_root_override(args.cache_dir)
|
|
new_cache = runtime.resolve_cache_root(_SKILL_NAME)
|
|
paths.CACHE_ROOT = new_cache
|
|
if hasattr(config, "CACHE_ROOT"):
|
|
config.CACHE_ROOT = new_cache
|
|
if "CACHE_ROOT" in caller_globals:
|
|
caller_globals["CACHE_ROOT"] = new_cache
|