Skip to content

Commit a1166df

Browse files
committed
refactor(cli): migrate "manage autouid" to a command pattern
1 parent b2b5e14 commit a1166df

5 files changed

Lines changed: 112 additions & 132 deletions

File tree

strictdoc/cli/cli_arg_parser.py

Lines changed: 0 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import argparse
2-
import os
32
from typing import Any, Dict, Optional
43

5-
from strictdoc.cli.base_command import CLIValidationError
64
from strictdoc.cli.command_parser_builder import (
75
COMMAND_REGISTRY,
86
CommandParserBuilder,
@@ -28,39 +26,6 @@ def __init__(
2826
self.reqif_import_markup: Optional[str] = reqif_import_markup
2927

3028

31-
class ManageAutoUIDCommandConfig:
32-
def __init__(
33-
self,
34-
*,
35-
input_path: str,
36-
config_path: Optional[str],
37-
include_sections: bool,
38-
):
39-
self.input_path: str = input_path
40-
self._config_path: Optional[str] = config_path
41-
self.include_sections: bool = include_sections
42-
43-
def get_path_to_config(self) -> str:
44-
path_to_input_dir: str = self.input_path
45-
if os.path.isfile(path_to_input_dir):
46-
path_to_input_dir = os.path.dirname(path_to_input_dir)
47-
path_to_config = (
48-
self._config_path
49-
if self._config_path is not None
50-
else path_to_input_dir
51-
)
52-
return path_to_config
53-
54-
def validate(self) -> None:
55-
if self._config_path is not None and not os.path.exists(
56-
self._config_path
57-
):
58-
raise CLIValidationError(
59-
"Provided path to a configuration file does not exist: "
60-
f"{self._config_path}"
61-
)
62-
63-
6429
class ImportExcelCommandConfig:
6530
def __init__(
6631
self, input_path: str, output_path: str, parser: SDocArgumentParser
@@ -110,13 +75,6 @@ def is_import_command_excel(self) -> bool:
11075
def is_server_command(self) -> bool:
11176
return str(self.args.command) == "server"
11277

113-
@property
114-
def is_manage_autouid_command(self) -> bool:
115-
return (
116-
str(self.args.command) == "manage"
117-
and str(self.args.subcommand) == "auto-uid"
118-
)
119-
12078
def get_import_config_reqif(self, _: Any) -> ImportReqIFCommandConfig:
12179
return ImportReqIFCommandConfig(
12280
self.args.input_path,
@@ -126,13 +84,6 @@ def get_import_config_reqif(self, _: Any) -> ImportReqIFCommandConfig:
12684
self.args.reqif_import_markup,
12785
)
12886

129-
def get_manage_autouid_config(self) -> ManageAutoUIDCommandConfig:
130-
return ManageAutoUIDCommandConfig(
131-
input_path=self.args.input_path,
132-
config_path=self.args.config,
133-
include_sections=self.args.include_sections,
134-
)
135-
13687
def get_import_config_excel(self, _: Any) -> ImportExcelCommandConfig:
13788
return ImportExcelCommandConfig(
13889
self.args.input_path, self.args.output_path, self.args.parser

strictdoc/cli/command_parser_builder.py

Lines changed: 3 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
from strictdoc.backend.sdoc.constants import SDocMarkup
88
from strictdoc.commands.about_command import AboutCommand
99
from strictdoc.commands.export import ExportCommand
10+
from strictdoc.commands.manage_autouid_command import ManageAutoUIDCommand
1011
from strictdoc.commands.server import ServerCommand
1112
from strictdoc.commands.shared import _check_reqif_profile
1213
from strictdoc.commands.version_command import VersionCommand
@@ -17,6 +18,7 @@
1718
COMMAND_REGISTRY: Dict[str, Any] = {
1819
"about": AboutCommand,
1920
"export": ExportCommand,
21+
"manage": {"auto-uid": ManageAutoUIDCommand},
2022
"server": ServerCommand,
2123
"version": VersionCommand,
2224
}
@@ -91,7 +93,6 @@ def build(self) -> SDocArgumentParser:
9193
)
9294
command_subparsers.required = True
9395

94-
self.add_manage_command(command_subparsers)
9596
self.add_import_command(command_subparsers)
9697

9798
# Dynamically add subcommands
@@ -101,6 +102,7 @@ def build(self) -> SDocArgumentParser:
101102
family_subparsers = family_parser.add_subparsers(
102103
dest="subcommand"
103104
)
105+
family_subparsers.required = True
104106
for subname, subcmd in cmd.items():
105107
sub_parser = family_subparsers.add_parser(
106108
subname,
@@ -220,46 +222,3 @@ def check_excel_parser(parser: str) -> str:
220222
type=str,
221223
help="Path to the output SDoc file.",
222224
)
223-
224-
@staticmethod
225-
def add_manage_command(
226-
parent_command_parser: "argparse._SubParsersAction[SDocArgumentParser]",
227-
) -> None:
228-
manage_command_parser = parent_command_parser.add_parser(
229-
"manage",
230-
help="Manage StrictDoc project.",
231-
description="See subcommands to manage StrictDoc project.",
232-
formatter_class=formatter,
233-
)
234-
manage_command_subparsers = manage_command_parser.add_subparsers(
235-
title="subcommand", dest="subcommand"
236-
)
237-
manage_command_subparsers.required = True
238-
239-
command_parser_auto_uid = manage_command_subparsers.add_parser(
240-
"auto-uid",
241-
help="Generates missing requirements UIDs automatically.",
242-
description=(
243-
"This command generates missing requirement UID automatically. "
244-
"The UIDs are generated based on the nearest section "
245-
"PREFIX (if provided) or the document's "
246-
'PREFIX (if provided or "REQ-" by default).'
247-
),
248-
formatter_class=formatter,
249-
)
250-
251-
command_parser_auto_uid.add_argument(
252-
"input_path",
253-
type=str,
254-
help="Path to the project tree.",
255-
)
256-
command_parser_auto_uid.add_argument(
257-
"--include-sections",
258-
action="store_true",
259-
help=(
260-
"By default, the command only generates the UID for "
261-
"requirements. This option enables the generation of UID for "
262-
"sections."
263-
),
264-
)
265-
add_config_argument(command_parser_auto_uid)

strictdoc/cli/main.py

Lines changed: 0 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@
66
import multiprocessing
77
import os
88
import sys
9-
from pathlib import Path
109
from typing import Optional
1110

1211
strictdoc_root_path = os.path.abspath(
@@ -16,15 +15,12 @@
1615
sys.path.append(strictdoc_root_path)
1716

1817
from strictdoc import environment
19-
from strictdoc.cli.base_command import CLIValidationError
2018
from strictdoc.cli.cli_arg_parser import (
2119
ImportExcelCommandConfig,
2220
ImportReqIFCommandConfig,
23-
ManageAutoUIDCommandConfig,
2421
SDocArgsParser,
2522
create_sdoc_args_parser,
2623
)
27-
from strictdoc.commands.manage_autouid_command import ManageAutoUIDCommand
2824
from strictdoc.core.actions.import_action import ImportAction
2925
from strictdoc.core.project_config import ProjectConfig, ProjectConfigLoader
3026
from strictdoc.helpers.coverage import register_code_coverage_hook
@@ -67,35 +63,6 @@ def _main_internal(parallelizer: Parallelizer, parser: SDocArgsParser) -> None:
6763
import_action = ImportAction()
6864
import_action.do_import(import_excel_config, project_config)
6965

70-
elif parser.is_manage_autouid_command:
71-
manage_config: ManageAutoUIDCommandConfig = (
72-
parser.get_manage_autouid_config()
73-
)
74-
try:
75-
manage_config.validate()
76-
except CLIValidationError as exception_:
77-
raise exception_
78-
79-
project_config = ProjectConfigLoader.load_from_path_or_get_default(
80-
path_to_config=manage_config.get_path_to_config(),
81-
)
82-
83-
# FIXME: Encapsulate all this in project_config.integrate_manage_autouid_config(),
84-
# following the example of integrate_export_config().
85-
project_config.input_paths = [manage_config.input_path]
86-
project_config.source_root_path = str(
87-
Path(manage_config.input_path).resolve()
88-
)
89-
project_config.auto_uid_mode = True
90-
project_config.autouuid_include_sections = (
91-
manage_config.include_sections
92-
)
93-
project_config.validate_and_finalize()
94-
95-
ManageAutoUIDCommand.execute(
96-
project_config=project_config, parallelizer=parallelizer
97-
)
98-
9966
else:
10067
raise NotImplementedError
10168

strictdoc/commands/manage_autouid_command.py

Lines changed: 66 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
1+
import argparse
12
import sys
3+
from pathlib import Path
24
from typing import Dict, Optional
35

46
from strictdoc.backend.sdoc.errors.document_tree_error import DocumentTreeError
@@ -9,12 +11,14 @@
911
SourceFileTraceabilityInfo,
1012
)
1113
from strictdoc.backend.sdoc_source_code.source_writer import SourceWriter
14+
from strictdoc.cli.base_command import BaseCommand, CLIValidationError
15+
from strictdoc.commands.manage_autouid_config import ManageAutoUIDCommandConfig
1216
from strictdoc.core.analyzers.document_stats import (
1317
DocumentStats,
1418
DocumentTreeStats,
1519
)
1620
from strictdoc.core.analyzers.document_uid_analyzer import DocumentUIDAnalyzer
17-
from strictdoc.core.project_config import ProjectConfig
21+
from strictdoc.core.project_config import ProjectConfig, ProjectConfigLoader
1822
from strictdoc.core.traceability_index import TraceabilityIndex
1923
from strictdoc.core.traceability_index_builder import TraceabilityIndexBuilder
2024
from strictdoc.helpers.parallelizer import Parallelizer
@@ -42,15 +46,71 @@ def generate_code_hash(
4246
return bytes(get_sha256(hash_input), encoding="utf8")
4347

4448

45-
class ManageAutoUIDCommand:
46-
@staticmethod
47-
def execute(
48-
*, project_config: ProjectConfig, parallelizer: Parallelizer
49-
) -> None:
49+
class ManageAutoUIDCommand(BaseCommand):
50+
HELP = "Generates missing requirements UIDs automatically."
51+
DETAILED_HELP = """\
52+
This command generates missing requirement UID automatically.
53+
The UIDs are generated based on the nearest section PREFIX (if provided) or
54+
the document's PREFIX (if provided or "REQ-" by default).
55+
"""
56+
57+
@classmethod
58+
def add_arguments(cls, parser: argparse.ArgumentParser) -> None:
59+
command_parser_auto_uid = parser
60+
61+
command_parser_auto_uid.add_argument(
62+
"input_path",
63+
type=str,
64+
help="Path to the project tree.",
65+
)
66+
command_parser_auto_uid.add_argument(
67+
"--include-sections",
68+
action="store_true",
69+
help=(
70+
"By default, the command only generates the UID for "
71+
"requirements. This option enables the generation of UID for "
72+
"sections."
73+
),
74+
)
75+
parser.add_argument(
76+
"--config",
77+
type=str,
78+
help="Path to the StrictDoc TOML config file.",
79+
)
80+
81+
def __init__(self, args: argparse.Namespace) -> None:
82+
self.args = args
83+
self.config: ManageAutoUIDCommandConfig = ManageAutoUIDCommandConfig(
84+
**vars(args)
85+
)
86+
87+
def run(self, parallelizer: Parallelizer) -> None: # noqa: ARG002
5088
"""
5189
@relation(SDOC-SRS-85, scope=function)
5290
"""
5391

92+
manage_config: ManageAutoUIDCommandConfig = self.config
93+
try:
94+
manage_config.validate()
95+
except CLIValidationError as exception_:
96+
raise exception_
97+
98+
project_config = ProjectConfigLoader.load_from_path_or_get_default(
99+
path_to_config=manage_config.get_path_to_config(),
100+
)
101+
102+
# FIXME: Encapsulate all this in project_config.integrate_manage_autouid_config(),
103+
# following the example of integrate_export_config().
104+
project_config.input_paths = [manage_config.input_path]
105+
project_config.source_root_path = str(
106+
Path(manage_config.input_path).resolve()
107+
)
108+
project_config.auto_uid_mode = True
109+
project_config.autouuid_include_sections = (
110+
manage_config.include_sections
111+
)
112+
project_config.validate_and_finalize()
113+
54114
# FIXME: Traceability Index is coupled with HTML output.
55115
project_config.export_output_html_root = "NOT_RELEVANT"
56116

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import os
2+
from typing import Optional
3+
4+
from strictdoc.cli.base_command import CLIValidationError
5+
6+
7+
class ManageAutoUIDCommandConfig:
8+
def __init__(
9+
self,
10+
*,
11+
debug: bool,
12+
command: str,
13+
subcommand: str,
14+
input_path: str,
15+
config: Optional[str],
16+
include_sections: bool,
17+
):
18+
self.debug: bool = debug
19+
self.command: str = command
20+
self.subcommand: str = subcommand
21+
self.input_path: str = input_path
22+
self._config_path: Optional[str] = config
23+
self.include_sections: bool = include_sections
24+
25+
def get_path_to_config(self) -> str:
26+
path_to_input_dir: str = self.input_path
27+
if os.path.isfile(path_to_input_dir):
28+
path_to_input_dir = os.path.dirname(path_to_input_dir)
29+
path_to_config = (
30+
self._config_path
31+
if self._config_path is not None
32+
else path_to_input_dir
33+
)
34+
return path_to_config
35+
36+
def validate(self) -> None:
37+
if self._config_path is not None and not os.path.exists(
38+
self._config_path
39+
):
40+
raise CLIValidationError(
41+
"Provided path to a configuration file does not exist: "
42+
f"{self._config_path}"
43+
)

0 commit comments

Comments
 (0)