Coverage for src/workstack/cli/activation.py: 100%

7 statements  

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

1"""Shell activation script generation for worktree environments. 

2 

3This module provides utilities for generating shell scripts that activate 

4worktree environments by setting up virtual environments and loading .env files. 

5""" 

6 

7import shlex 

8from pathlib import Path 

9 

10 

11def render_activation_script( 

12 *, 

13 worktree_path: Path, 

14 final_message: str = 'echo "Activated worktree: $(pwd)"', 

15 comment: str = "work activate-script", 

16) -> str: 

17 """Return shell code that activates a worktree's venv and .env. 

18 

19 The script: 

20 - cds into the worktree 

21 - creates .venv with `uv sync` if not present 

22 - sources `.venv/bin/activate` if present 

23 - exports variables from `.env` if present 

24 Works in bash and zsh. 

25 

26 Args: 

27 worktree_path: Path to the worktree directory 

28 final_message: Shell command for final echo message (default shows activation) 

29 comment: Comment line for script identification (default: "work activate-script") 

30 

31 Returns: 

32 Shell script as a string with newlines 

33 

34 Example: 

35 >>> script = render_activation_script( 

36 ... worktree_path=Path("/path/to/worktree"), 

37 ... final_message='echo "Ready: $(pwd)"' 

38 ... ) 

39 """ 

40 wt = shlex.quote(str(worktree_path)) 

41 venv_dir = shlex.quote(str(worktree_path / ".venv")) 

42 venv_activate = shlex.quote(str(worktree_path / ".venv" / "bin" / "activate")) 

43 

44 return f"""# {comment} 

45cd {wt} 

46# Unset VIRTUAL_ENV to avoid conflicts with previous activations 

47unset VIRTUAL_ENV 

48# Create venv if it doesn't exist 

49if [ ! -d {venv_dir} ]; then 

50 echo 'Creating virtual environment with uv sync...' 

51 uv sync 

52fi 

53if [ -f {venv_activate} ]; then 

54 . {venv_activate} 

55fi 

56# Load .env into the environment (allexport) 

57set -a 

58if [ -f ./.env ]; then . ./.env; fi 

59set +a 

60# Optional: show where we are 

61{final_message} 

62"""