StrictDoc Documentation
strictdoc/commands/new_command.py
Source file coverage
Path:
strictdoc/commands/new_command.py
Lines:
180
Non-empty lines:
154
Non-empty lines covered with requirements:
154 / 154 (100.0%)
Functions:
5
Functions covered by requirements:
5 / 5 (100.0%)
1
"""
2
@relation(SDOC-LLR-208, scope=file)
3
"""
4
 
5
import argparse
6
from pathlib import Path
7
from typing import Dict, List, Tuple
8
 
9
from strictdoc.cli.base_command import BaseCommand, CLIValidationError
10
from strictdoc.helpers.mid import MID
11
from strictdoc.helpers.parallelizer import Parallelizer
12
 
13
 
14
class NewCommand(BaseCommand):
15
    HELP = "Create an initial StrictDoc project."
16
    DETAILED_HELP = HELP
17
 
18
    @classmethod
19
    def add_arguments(cls, parser: argparse.ArgumentParser) -> None:
20
        parser.add_argument(
21
            "input_path",
22
            type=str,
23
            help="Folder where the initial StrictDoc project is created.",
24
        )
25
 
26
    def __init__(self, args: argparse.Namespace) -> None:
27
        self.args = args
28
 
29
    def run(self, parallelizer: Parallelizer) -> None:  # noqa: ARG002
30
        output_path = Path(self.args.input_path)
31
        if output_path.exists() and not output_path.is_dir():
32
            raise CLIValidationError(
33
                "error: "
34
                "Provided path exists and is not a directory: "
35
                f"'{output_path}'"
36
            )
37
 
38
        directories, files = self._get_template_files(output_path)
39
        conflicts = [
40
            directory
41
            for directory in directories
42
            if directory.exists() and not directory.is_dir()
43
        ]
44
        conflicts.extend(file_path for file_path in files if file_path.exists())
45
        if conflicts:
46
            conflict_list = "\n".join(f"- {path}" for path in conflicts)
47
            raise CLIValidationError(
48
                "Refusing to overwrite existing StrictDoc project files:\n"
49
                f"{conflict_list}"
50
            )
51
 
52
        for directory in directories:
53
            directory.mkdir(parents=True, exist_ok=True)
54
 
55
        for file_path, content in files.items():
56
            file_path.write_text(content, encoding="utf-8")
57
 
58
        print(  # noqa: T201
59
            f"""\
60
╔════════════════════════════════════════════════════════════╗
61
║            StrictDoc project skeleton created              ║
62
╚════════════════════════════════════════════════════════════╝
63
 
64
Location: {output_path}
65
 
66
Next steps:
67
 
68
1. Change into the project directory
69
 
70
   cd {output_path}
71
 
72
2. Export static HTML documentation
73
 
74
   strictdoc export .
75
 
76
3. Start the web server
77
 
78
   strictdoc server .
79
"""
80
        )
81
 
82
    @staticmethod
83
    def _get_template_files(
84
        output_path: Path,
85
    ) -> Tuple[List[Path], Dict[Path, str]]:
86
        docs_path = output_path / "docs"
87
        src_path = output_path / "src"
88
        hlr_document_mid = MID.create()
89
        hlr_requirement_mid = MID.create()
90
        llr_document_mid = MID.create()
91
        llr_requirement_mid = MID.create()
92
        return [output_path, docs_path, src_path], {
93
            docs_path / "high_level_requirements.sdoc": (
94
                f"""\
95
[DOCUMENT]
96
MID: {hlr_document_mid}
97
TITLE: High-Level Requirements
98
PREFIX: HLR-
99
OPTIONS:
100
  ENABLE_MID: True
101
 
102
[REQUIREMENT]
103
MID: {hlr_requirement_mid}
104
UID: HLR-1
105
TITLE: Initial high-level requirement
106
STATEMENT: >>>
107
The system shall provide a hello world application.
108
<<<
109
"""
110
            ),
111
            docs_path / "low_level_requirements.sdoc": (
112
                f"""\
113
[DOCUMENT]
114
MID: {llr_document_mid}
115
TITLE: Low-Level Requirements
116
PREFIX: LLR-
117
OPTIONS:
118
  ENABLE_MID: True
119
 
120
[REQUIREMENT]
121
MID: {llr_requirement_mid}
122
UID: LLR-1
123
TITLE: Initial low-level requirement
124
STATEMENT: >>>
125
The software shall print a hello world message.
126
<<<
127
RELATIONS:
128
- TYPE: Parent
129
  VALUE: HLR-1
130
"""
131
            ),
132
            src_path / "main.c": (
133
                """\
134
/**
135
* @relation(LLR-1, scope=file)
136
*/
137
#include <stdio.h>
138
 
139
int main(void)
140
{
141
    printf("Hello, StrictDoc!\\n");
142
    return 0;
143
}
144
"""
145
            ),
146
            output_path / "strictdoc_config.py": (
147
                """\
148
from strictdoc.core.project_config import ProjectConfig
149
 
150
 
151
def create_config() -> ProjectConfig:
152
    return ProjectConfig(
153
        project_title="Hello World",
154
        project_features=[
155
            # Stable features.
156
            "TABLE_SCREEN",
157
            "TRACEABILITY_SCREEN",
158
            "DEEP_TRACEABILITY_SCREEN",
159
            "SEARCH",
160
            "TRACEABILITY_MATRIX_SCREEN",
161
            "REQUIREMENT_TO_SOURCE_TRACEABILITY",
162
            # "MATHJAX"
163
 
164
            # Experimental features.
165
            # "PROJECT_STATISTICS_SCREEN",
166
            # "TREE_MAP_SCREEN",
167
            # "REQIF",
168
            # "HTML2PDF",
169
            # "DIFF",
170
        ],
171
        include_doc_paths=[
172
            "/docs/",
173
        ],
174
        include_source_paths=[
175
            "/src/**",
176
        ],
177
    )
178
"""
179
            ),
180
        }