xil-remove-episode — remove workspace files for a single episode.
Deletes every workspace artifact belonging to the named episode while leaving
the source production script untouched. The following are removed:
- configs/{slug}/cast_{tag}.json
- configs/{slug}/sfx_{tag}.json
- parsed/{slug}/parsed_{tag}.json (and .csv, orig_, pre_splice_, stem_verify_)
- cues/{slug}/cues_{tag}.md + cues_manifest_{tag}.json
- stems/{slug}/{tag}/ (directory)
- daw/{slug}/{tag}/ (directory)
- masters/{slug}/{tag}_*.mp3 (glob — date-tagged masters from xil-master)
- posts/{slug}/{tag}_posts.md
- voice_samples/{tag}/ (directory — from xil-sample)
- legacy root files: cast_{slug}{tag}.json, sfx{slug}_{tag}.json
- legacy parsed files in parsed/ (flat naming, pre-0.1.8 layout)
Shared assets (SFX/, logs/) and the source script (scripts/) are never touched.
Usage::
xil remove-episode S01E01 --dry-run
xil remove-episode S01E01 --yes
xil remove-episode S01E01 --show "Night Owls" --dry-run
logger
module-attribute
logger = get_logger(__name__)
RemovalItem
module-attribute
RemovalItem = _Dir | _File
get_parser
get_parser() -> argparse.ArgumentParser
Return the argument parser for xil-remove-episode.
Source code in src/xil_pipeline/XILU018_remove_episode.py
| def get_parser() -> argparse.ArgumentParser:
"""Return the argument parser for xil-remove-episode."""
parser = argparse.ArgumentParser(
prog="xil-remove-episode",
description=(
"Remove all workspace files for a single episode. "
"The source production script is never touched. "
"Shared assets (SFX/, logs/) are never touched."
),
formatter_class=argparse.RawDescriptionHelpFormatter,
epilog=(
"Examples:\n"
" xil remove-episode S01E01 --dry-run\n"
" xil remove-episode S01E01 --yes\n"
' xil remove-episode S01E01 --show "Night Owls" --dry-run\n'
),
)
parser.add_argument(
"episode",
metavar="TAG",
help="Episode tag to remove (e.g. S01E01)",
)
parser.add_argument(
"--show", "-s",
default=None,
metavar="SHOW",
help="Show name or slug (default: resolved from project.json / XIL_PROJECTROOT)",
)
parser.add_argument(
"--dry-run", "-n",
action="store_true",
help="Show what would be removed without deleting anything",
)
parser.add_argument(
"--yes", "-y",
action="store_true",
help="Skip the confirmation prompt",
)
return parser
|
main
CLI entry point for episode workspace removal.
Source code in src/xil_pipeline/XILU018_remove_episode.py
| def main() -> None:
"""CLI entry point for episode workspace removal."""
configure_logging()
args = get_parser().parse_args()
slug = resolve_slug(args.show)
tag = args.episode
items = _collect(slug, tag)
total_files, total_bytes = _report(items, slug, tag, dry_run=args.dry_run)
if args.dry_run:
if total_files > 0:
logger.info("")
logger.info("Dry run — nothing deleted. Run without --dry-run to remove.")
sys.exit(0)
if total_files == 0:
sys.exit(0)
if not args.yes:
logger.info("")
confirm = input(
f'⚠️ This will permanently delete {total_files} file(s) ({_fmt_bytes(total_bytes)}) '
f'for episode "{tag}" (show "{slug}").\n'
f' Type "{tag}" to confirm (or Ctrl-C to abort): '
).strip()
if confirm != tag:
logger.info("Aborted — input did not match. Nothing deleted.")
sys.exit(1)
logger.info("")
removed = _delete(items)
logger.info("")
logger.info(f"✓ Removed {removed} file(s) for episode '{tag}' (show '{slug}').")
|