Coverage for src/prosemark/app/init_project.py: 100%
20 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"""InitProject use case for creating new prosemark projects."""
3from pathlib import Path
4from typing import TYPE_CHECKING
6from prosemark.domain.models import Binder
8if TYPE_CHECKING: # pragma: no cover
9 from prosemark.ports.binder_repo import BinderRepo
10 from prosemark.ports.console_port import ConsolePort
11 from prosemark.ports.logger import Logger
14class InitProject:
15 """Initialize a new prosemark writing project."""
17 def __init__(
18 self,
19 *,
20 binder_repo: 'BinderRepo',
21 console: 'ConsolePort',
22 logger: 'Logger',
23 ) -> None:
24 """Initialize the InitProject use case.
26 Args:
27 binder_repo: Repository for binder operations.
28 console: Console output port.
29 logger: Logger port.
31 """
32 self.binder_repo = binder_repo
33 self.console = console
34 self.logger = logger
36 def execute(self, *, project_title: str, project_path: Path | None = None) -> None:
37 """Initialize a new prosemark project.
39 Args:
40 project_title: Title for the new project.
41 project_path: Optional path for project, defaults to current directory.
43 """
44 project_path = project_path or Path.cwd()
45 self.logger.info('Initializing project: %s at %s', project_title, project_path)
47 # Check if binder already exists
48 binder_path = project_path / '_binder.md'
49 if binder_path.exists():
50 self.console.print_error(f'Binder already exists at {binder_path}')
51 return
53 # Create new binder
54 binder = Binder(roots=[])
56 # Save the binder
57 self.binder_repo.save(binder)
59 self.console.print_success(f'Project "{project_title}" initialized successfully')
60 self.console.print_info(f'Created {binder_path}')
61 self.logger.info('Project initialized: %s', project_title)