Coverage for src/workstack/cli/commands/rename.py: 97%

35 statements  

« prev     ^ index     » next       coverage.py v7.11.0, created at 2025-10-19 09:31 -0400

1from pathlib import Path 

2 

3import click 

4 

5from workstack.cli.commands.create import make_env_content, sanitize_worktree_name 

6from workstack.cli.commands.switch import complete_worktree_names 

7from workstack.cli.config import load_config 

8from workstack.cli.core import discover_repo_context, ensure_workstacks_dir, worktree_path_for 

9from workstack.core.context import WorkstackContext, create_context 

10 

11 

12@click.command("rename") 

13@click.argument("old_name", metavar="OLD_NAME", shell_complete=complete_worktree_names) 

14@click.argument("new_name", metavar="NEW_NAME") 

15@click.option( 

16 "--dry-run", 

17 is_flag=True, 

18 # dry_run=False: Allow destructive operations by default 

19 default=False, 

20 help="Print what would be done without executing destructive operations.", 

21) 

22@click.pass_obj 

23def rename_cmd(ctx: WorkstackContext, old_name: str, new_name: str, dry_run: bool) -> None: 

24 """Rename a worktree directory. 

25 

26 Renames the worktree directory and updates git metadata. 

27 The .env file is regenerated with updated paths and name. 

28 """ 

29 # Create dry-run context if needed 

30 if dry_run: 

31 ctx = create_context(dry_run=True) 

32 

33 # Sanitize new name 

34 sanitized_new_name = sanitize_worktree_name(new_name) 

35 

36 repo = discover_repo_context(ctx, Path.cwd()) 

37 workstacks_dir = ensure_workstacks_dir(repo) 

38 

39 old_path = worktree_path_for(workstacks_dir, old_name) 

40 new_path = worktree_path_for(workstacks_dir, sanitized_new_name) 

41 

42 # Validate old worktree exists 

43 if not old_path.exists() or not old_path.is_dir(): 

44 click.echo(f"Worktree not found: {old_path}", err=True) 

45 raise SystemExit(1) 

46 

47 # Validate new path doesn't already exist 

48 if new_path.exists(): 

49 click.echo(f"Destination already exists: {new_path}", err=True) 

50 raise SystemExit(1) 

51 

52 # Move via git worktree move 

53 ctx.git_ops.move_worktree(repo.root, old_path, new_path) 

54 

55 # Regenerate .env file with updated paths and name 

56 cfg = load_config(workstacks_dir) 

57 env_content = make_env_content( 

58 cfg, worktree_path=new_path, repo_root=repo.root, name=sanitized_new_name 

59 ) 

60 

61 # Write .env file (dry-run vs real) 

62 env_file = new_path / ".env" 

63 if ctx.dry_run: 

64 click.echo(f"[DRY RUN] Would write .env file: {env_file}", err=True) 

65 else: 

66 env_file.write_text(env_content, encoding="utf-8") 

67 

68 click.echo(f"Renamed worktree: {old_name} -> {sanitized_new_name}") 

69 click.echo(str(new_path))