Coverage for src/prosemark/cli/materialize.py: 100%
37 statements
« prev ^ index » next coverage.py v7.8.0, created at 2025-09-24 18:08 +0000
« prev ^ index » next coverage.py v7.8.0, created at 2025-09-24 18:08 +0000
1"""CLI command for materializing placeholders."""
3from pathlib import Path
5import click
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.id_generator_uuid7 import IdGeneratorUuid7
11from prosemark.adapters.logger_stdout import LoggerStdout
12from prosemark.adapters.node_repo_fs import NodeRepoFs
13from prosemark.app.use_cases import MaterializeNode
14from prosemark.exceptions import AlreadyMaterializedError, FileSystemError, PlaceholderNotFoundError
17@click.command()
18@click.argument('title')
19@click.option('--parent', '_parent', help='Parent node ID to search within')
20@click.option('--path', '-p', type=click.Path(path_type=Path), help='Project directory')
21def materialize_command(title: str, _parent: str | None, path: Path | None) -> None:
22 """Convert a placeholder to an actual node."""
23 try:
24 project_root = path or Path.cwd()
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 id_generator = IdGeneratorUuid7()
32 logger = LoggerStdout()
34 # Execute use case
35 interactor = MaterializeNode(
36 binder_repo=binder_repo,
37 node_repo=node_repo,
38 id_generator=id_generator,
39 logger=logger,
40 )
42 node_id = interactor.execute(display_title=title, synopsis=None)
44 # Success output
45 click.echo(f'Materialized "{title}" ({node_id})')
46 click.echo(f'Created files: {node_id}.md, {node_id}.notes.md')
47 click.echo('Updated binder structure')
49 except PlaceholderNotFoundError:
50 click.echo('Error: Placeholder not found', err=True)
51 raise SystemExit(1) from None
52 except AlreadyMaterializedError:
53 click.echo(f"Error: '{title}' is already materialized", err=True)
54 raise SystemExit(1) from None
55 except FileSystemError:
56 click.echo('Error: File creation failed', err=True)
57 raise SystemExit(2) from None