Skip to content

Xilu009 Migrate Workspace

src.xil_pipeline.XILU009_migrate_workspace

Migrate a pre-0.1.8 workspace to the normalized directory layout.

Old (flat) layout::

speakers.json                   → configs/{slug}/speakers.json
cast_{slug}_{tag}.json          → configs/{slug}/cast_{tag}.json
sfx_{slug}_{tag}.json           → configs/{slug}/sfx_{tag}.json
parsed/parsed_{slug}_{tag}.json → parsed/{slug}/parsed_{tag}.json
parsed/parsed_{slug}_{tag}.csv  → parsed/{slug}/parsed_{tag}.csv
parsed/annotated_{slug}_{tag}*  → parsed/{slug}/annotated_{tag}.*
parsed/orig_parsed_{slug}_{tag} → parsed/{slug}/orig_parsed_{tag}.json
daw/{tag}/                      → daw/{slug}/{tag}/
masters/{slug}_{tag}_master.mp3 → masters/{slug}/{tag}_master.mp3
cues/cues_{slug}_{tag}.md       → cues/{slug}/cues_{tag}.md
cues/cues_manifest_{tag}.json   → cues/{slug}/cues_manifest_{tag}.json

stems/{slug}/{tag}/ is already normalized — no move needed.

Usage:

xil migrate-workspace --dry-run    # preview what would move
xil migrate-workspace              # execute moves

logger module-attribute

logger = get_logger(__name__)

migrate

migrate(workspace: str = '.', dry_run: bool = True) -> int

Discover and optionally execute workspace migration moves.

Parameters:

  • workspace (str, default: '.' ) –

    Root workspace directory (default: current directory).

  • dry_run (bool, default: True ) –

    If True, prints what would move without touching files.

Returns:

  • int

    Exit code (0 = success, 1 = nothing to migrate).

Source code in src/xil_pipeline/XILU009_migrate_workspace.py
def migrate(workspace: str = ".", dry_run: bool = True) -> int:
    """Discover and optionally execute workspace migration moves.

    Args:
        workspace: Root workspace directory (default: current directory).
        dry_run: If ``True``, prints what would move without touching files.

    Returns:
        Exit code (0 = success, 1 = nothing to migrate).
    """
    run_banner("XILU009 migrate-workspace")
    moves = _discover_moves(workspace)
    if not moves:
        logger.info("Nothing to migrate — workspace already uses the normalized layout.")
        return 0

    mode = "DRY RUN — " if dry_run else ""
    logger.info(f"\n{mode}Workspace migration plan ({len(moves)} moves):\n")
    moved, skipped = _execute_moves(moves, dry_run=dry_run)

    if dry_run:
        logger.info(f"\n{moved} file(s) would be moved, {skipped} already at target.")
        logger.info("Run without --dry-run to execute.")
    else:
        logger.info(f"\n{moved} file(s) moved, {skipped} skipped.")
        logger.info("Migration complete. Run 'xil migrate-workspace --dry-run' to verify.")
    return 0

get_parser

get_parser() -> argparse.ArgumentParser
Source code in src/xil_pipeline/XILU009_migrate_workspace.py
def get_parser() -> argparse.ArgumentParser:
    parser = argparse.ArgumentParser(
        prog="xil-migrate-workspace",
        description="Migrate a pre-0.1.8 workspace to the normalized directory layout",
    )
    parser.add_argument(
        "--workspace", default=".",
        help="Workspace root directory (default: current directory)",
    )
    parser.add_argument(
        "--dry-run", action="store_true",
        help="Preview moves without touching files (default: enabled for safety)",
    )
    return parser

main

main() -> int
Source code in src/xil_pipeline/XILU009_migrate_workspace.py
def main() -> int:
    configure_logging()
    args = get_parser().parse_args()
    return migrate(workspace=args.workspace, dry_run=args.dry_run)