70 lines
2.4 KiB
Python
70 lines
2.4 KiB
Python
"""Plan command implementation."""
|
|||
|
|
|
||
|
|
from pathlib import Path
|
||
|
|
|
||
|
|
import click
|
||
|
|
|
||
|
|
from vlm.context import CLIContext
|
||
|
|
from vlm.io import identities_to_plan_input, load_identities_json
|
||
|
|
from vlm.planner import generate_plan, save_plan
|
||
|
|
|
||
|
|
|
||
|
|
def plan_cmd(ctx: CLIContext, input: Path, output: Path) -> None:
|
||
|
|
"""Generate execution plan from identities."""
|
||
|
|
config = ctx.config
|
||
|
|
logger = ctx.logger
|
||
|
|
|
||
|
|
click.echo(f"Generating execution plan from: {input}")
|
||
|
|
click.echo()
|
||
|
|
|
||
|
|
identities_data = load_identities_json(input)
|
||
|
|
movies_data = identities_data.get("movies", [])
|
||
|
|
series_data = identities_data.get("series", [])
|
||
|
|
anime_data = identities_data.get("anime", [])
|
||
|
|
other_data = identities_data.get("other", [])
|
||
|
|
|
||
|
|
click.echo(
|
||
|
|
f"Loaded {len(movies_data)} movies, {len(series_data)} series, "
|
||
|
|
f"{len(anime_data)} anime, {len(other_data)} other"
|
||
|
|
)
|
||
|
|
click.echo()
|
||
|
|
|
||
|
|
identities_list = identities_to_plan_input(identities_data)
|
||
|
|
|
||
|
|
click.echo("Generating execution plan...")
|
||
|
|
execution_plan = generate_plan(identities_list, config)
|
||
|
|
|
||
|
|
click.echo()
|
||
|
|
click.echo("Plan generation complete!")
|
||
|
|
click.echo()
|
||
|
|
click.echo("Operation summary:")
|
||
|
|
click.echo(f" Total operations: {execution_plan.summary['total']}")
|
||
|
|
click.echo(f" Move operations: {execution_plan.summary['move']}")
|
||
|
|
click.echo(f" Rename operations: {execution_plan.summary['rename']}")
|
||
|
|
click.echo(f" Quarantine operations: {execution_plan.summary['quarantine']}")
|
||
|
|
click.echo(f" No-op (skipped): {execution_plan.summary['no-op']}")
|
||
|
|
|
||
|
|
conflicts = sum(1 for op in execution_plan.operations if op.has_conflict)
|
||
|
|
if conflicts > 0:
|
||
|
|
click.echo()
|
||
|
|
click.echo(f" ⚠️ Conflicts detected: {conflicts}")
|
||
|
|
click.echo(" Review the plan file for details on conflicting operations.")
|
||
|
|
|
||
|
|
click.echo()
|
||
|
|
click.echo(f"Saving execution plan to: {output}")
|
||
|
|
output.parent.mkdir(parents=True, exist_ok=True)
|
||
|
|
save_plan(execution_plan, output)
|
||
|
|
|
||
|
|
click.echo("Execution plan saved successfully!")
|
||
|
|
click.echo()
|
||
|
|
click.echo("Next steps:")
|
||
|
|
click.echo(f" 1. Review the plan: {output}")
|
||
|
|
click.echo(" 2. Edit the plan if needed (it's JSON)")
|
||
|
|
click.echo(f" 3. Dry-run: vlm execute --plan {output}")
|
||
|
|
click.echo(f" 4. Execute: vlm execute --plan {output} --confirm")
|
||
|
|
|
||
|
|
logger.info(
|
||
|
|
f"Plan generated: {execution_plan.summary['total']} operations, "
|
||
|
|
f"{conflicts} conflicts, saved to {output}"
|
||
|
|
)
|