Coverage for src/prosemark/cli/edit.py: 100%

41 statements  

« prev     ^ index     » next       coverage.py v7.8.0, created at 2025-09-24 18:08 +0000

1"""CLI command for editing node content.""" 

2 

3from pathlib import Path 

4 

5import click 

6 

7from prosemark.adapters.binder_repo_fs import BinderRepoFs 

8from prosemark.adapters.clock_system import ClockSystem 

9from prosemark.adapters.editor_launcher_system import EditorLauncherSystem 

10from prosemark.adapters.logger_stdout import LoggerStdout 

11from prosemark.adapters.node_repo_fs import NodeRepoFs 

12from prosemark.app.use_cases import EditPart 

13from prosemark.domain.models import NodeId 

14from prosemark.exceptions import EditorLaunchError, FileSystemError, NodeNotFoundError 

15 

16 

17@click.command() 

18@click.argument('node_id') 

19@click.option('--part', required=True, help='Content part to edit (draft/notes/synopsis)') 

20@click.option('--path', '-p', type=click.Path(path_type=Path), help='Project directory') 

21def edit_command(node_id: str, part: str, path: Path | None) -> None: 

22 """Open node content in your preferred editor.""" 

23 try: 

24 project_root = path or Path.cwd() 

25 

26 # Wire up dependencies 

27 binder_repo = BinderRepoFs(project_root) 

28 clock = ClockSystem() 

29 editor = EditorLauncherSystem() 

30 node_repo = NodeRepoFs(project_root, editor, clock) 

31 logger = LoggerStdout() 

32 

33 # Execute use case 

34 interactor = EditPart( 

35 binder_repo=binder_repo, 

36 node_repo=node_repo, 

37 logger=logger, 

38 ) 

39 

40 interactor.execute(NodeId(node_id), part) 

41 

42 # Success output 

43 if part == 'draft': 

44 click.echo(f'Opened {node_id}.md in editor') 

45 elif part == 'notes': 

46 click.echo(f'Opened {node_id}.notes.md in editor') 

47 else: 

48 click.echo(f'Opened {part} for {node_id} in editor') 

49 

50 except NodeNotFoundError as err: 

51 click.echo('Error: Node not found', err=True) 

52 raise SystemExit(1) from err 

53 except EditorLaunchError as err: 

54 click.echo('Error: Editor not available', err=True) 

55 raise SystemExit(2) from err 

56 except FileSystemError as err: 

57 click.echo('Error: File permission denied', err=True) 

58 raise SystemExit(3) from err 

59 except ValueError as err: 

60 click.echo(f'Error: {err}', err=True) 

61 raise SystemExit(1) from err