11import argparse
22import os
3- from typing import Any , List , Optional , Tuple
3+ from typing import Any , Dict , Optional
44
5+ from strictdoc .cli .base_command import CLIValidationError
56from strictdoc .cli .command_parser_builder import (
7+ COMMAND_REGISTRY ,
68 CommandParserBuilder ,
79 SDocArgumentParser ,
810)
9- from strictdoc .helpers .auto_described import auto_described
1011from strictdoc .helpers .cast import assert_cast
11- from strictdoc .helpers .net import is_valid_host
12-
13-
14- class CLIValidationError (Exception ):
15- pass
12+ from strictdoc .helpers .parallelizer import Parallelizer
1613
1714
1815class ImportReqIFCommandConfig :
@@ -73,149 +70,27 @@ def __init__(
7370 self .parser : SDocArgumentParser = parser
7471
7572
76- @auto_described
77- class ServerCommandConfig :
78- def __init__ (
79- self ,
80- * ,
81- input_path : str ,
82- output_path : Optional [str ],
83- config_path : Optional [str ],
84- reload : bool ,
85- host : Optional [str ],
86- port : Optional [int ],
87- ):
88- self ._input_path : str = input_path
89- self .output_path : Optional [str ] = output_path
90- self ._config_path : Optional [str ] = config_path
91- self .reload : bool = reload
92- self .host : Optional [str ] = host
93- self .port : Optional [int ] = port
94-
95- def get_full_input_path (self ) -> str :
96- return os .path .abspath (self ._input_path )
97-
98- def get_path_to_config (self ) -> str :
99- return (
100- self ._config_path
101- if self ._config_path is not None
102- else self ._input_path
103- )
104-
105- def validate (self ) -> None :
106- if not os .path .exists (self ._input_path ):
107- raise CLIValidationError (
108- f"Provided input path does not exist: { self ._input_path } "
109- )
110-
111- if self ._config_path is not None and not os .path .exists (
112- self ._config_path
113- ):
114- raise CLIValidationError (
115- "Provided path to a configuration file does not exist: "
116- f"{ self ._config_path } "
117- )
118-
119- if (host_ := self .host ) is not None :
120- if not is_valid_host (host_ ):
121- raise CLIValidationError (
122- f"Provided 'host' argument is not a valid host: { host_ } "
123- )
124-
125-
126- @auto_described
127- class ExportCommandConfig :
128- def __init__ (
129- self ,
130- * ,
131- input_paths : List [str ],
132- output_dir : Optional [str ],
133- config_path : Optional [str ],
134- project_title : Optional [str ],
135- formats : List [str ],
136- fields : List [str ],
137- generate_bundle_document : bool ,
138- no_parallelization : bool ,
139- enable_mathjax : bool ,
140- included_documents : bool ,
141- filter_nodes : Optional [str ],
142- reqif_profile : Optional [str ],
143- reqif_multiline_is_xhtml : bool ,
144- reqif_enable_mid : bool ,
145- view : Optional [str ],
146- generate_diff_git : Optional [str ],
147- generate_diff_dirs : Optional [Tuple [str , str ]],
148- chromedriver : Optional [str ],
149- ):
150- assert isinstance (input_paths , list ), f"{ input_paths } "
151- self .input_paths : List [str ] = input_paths
152- self .output_dir : Optional [str ] = output_dir
153- self ._config_path : Optional [str ] = config_path
154- self .project_title : Optional [str ] = project_title
155- self .formats : List [str ] = formats
156- self .fields : List [str ] = fields
157- self .generate_bundle_document : bool = generate_bundle_document
158- self .no_parallelization : bool = no_parallelization
159- self .enable_mathjax : bool = enable_mathjax
160- self .included_documents : bool = included_documents
161- self .filter_nodes : Optional [str ] = filter_nodes
162- self .reqif_profile : Optional [str ] = reqif_profile
163- self .reqif_multiline_is_xhtml : bool = reqif_multiline_is_xhtml
164- self .reqif_enable_mid : bool = reqif_enable_mid
165- self .view : Optional [str ] = view
166- self .generate_diff_git : Optional [str ] = generate_diff_git
167- self .generate_diff_dirs : Optional [Tuple [str , str ]] = generate_diff_dirs
168- self .chromedriver : Optional [str ] = chromedriver
169-
170- def get_path_to_config (self ) -> str :
171- # FIXME: The control flow can be improved.
172- path_to_input_dir : str = self .input_paths [0 ]
173- if os .path .isfile (path_to_input_dir ):
174- path_to_input_dir = os .path .dirname (path_to_input_dir )
175- path_to_config = (
176- self ._config_path
177- if self ._config_path is not None
178- else path_to_input_dir
179- )
180- return path_to_config
181-
182- def validate (self ) -> None :
183- for idx_ , input_path_ in enumerate (self .input_paths .copy ()):
184- if not os .path .exists (input_path_ ):
185- raise CLIValidationError (
186- f"Provided input path does not exist: { input_path_ } "
187- )
188- if not os .path .isabs (input_path_ ):
189- self .input_paths [idx_ ] = os .path .abspath (input_path_ ).rstrip (
190- "/"
191- )
192- if self ._config_path is not None :
193- if not os .path .exists (self ._config_path ):
194- raise CLIValidationError (
195- "Provided path to a configuration file does not exist: "
196- f"{ self ._config_path } "
197- )
198-
199-
200- class DumpGrammarCommandConfig :
201- def __init__ (self , output_file : str ):
202- self .output_file : str = output_file
203-
204-
20573class SDocArgsParser :
206- def __init__ (self , args : argparse .Namespace ):
74+ def __init__ (self , args : argparse .Namespace , registry : Dict [ str , Any ] ):
20775 self .args : argparse .Namespace = args
76+ self .registry : Dict [str , Any ] = registry
20877
20978 def is_debug_mode (self ) -> bool :
21079 return assert_cast (self .args .debug , bool )
21180
212- @ property
213- def is_about_command ( self ) -> bool :
214- return str ( self . args . command ) == "about"
81+ def run ( self , parallelizer : Parallelizer ) -> bool :
82+ if self . args . command not in self . registry :
83+ return False
21584
216- @property
217- def is_export_command (self ) -> bool :
218- return str (self .args .command ) == "export"
85+ cmd = self .registry [self .args .command ]
86+ if isinstance (cmd , dict ):
87+ assert self .args .subcommand in cmd
88+ command_instance = cmd [self .args .subcommand ](self .args )
89+ else :
90+ command_instance = cmd (self .args )
91+ command_instance .run (parallelizer )
92+
93+ return True
21994
22095 @property
22196 def is_import_command_reqif (self ) -> bool :
@@ -235,45 +110,13 @@ def is_import_command_excel(self) -> bool:
235110 def is_server_command (self ) -> bool :
236111 return str (self .args .command ) == "server"
237112
238- @property
239- def is_dump_grammar_command (self ) -> bool :
240- return str (self .args .command ) == "dump-grammar"
241-
242- @property
243- def is_version_command (self ) -> bool :
244- return str (self .args .command ) == "version"
245-
246113 @property
247114 def is_manage_autouid_command (self ) -> bool :
248115 return (
249116 str (self .args .command ) == "manage"
250117 and str (self .args .subcommand ) == "auto-uid"
251118 )
252119
253- def get_export_config (self ) -> ExportCommandConfig :
254- project_title : Optional [str ] = self .args .project_title
255-
256- return ExportCommandConfig (
257- input_paths = self .args .input_paths ,
258- output_dir = self .args .output_dir ,
259- config_path = self .args .config ,
260- project_title = project_title ,
261- formats = self .args .formats ,
262- fields = self .args .fields ,
263- generate_bundle_document = self .args .generate_bundle_document ,
264- no_parallelization = self .args .no_parallelization ,
265- enable_mathjax = self .args .enable_mathjax ,
266- included_documents = self .args .included_documents ,
267- filter_nodes = self .args .filter_nodes ,
268- reqif_profile = self .args .reqif_profile ,
269- reqif_multiline_is_xhtml = self .args .reqif_multiline_is_xhtml ,
270- reqif_enable_mid = self .args .reqif_enable_mid ,
271- view = self .args .view ,
272- generate_diff_git = self .args .generate_diff_git ,
273- generate_diff_dirs = self .args .generate_diff_dirs ,
274- chromedriver = self .args .chromedriver ,
275- )
276-
277120 def get_import_config_reqif (self , _ : Any ) -> ImportReqIFCommandConfig :
278121 return ImportReqIFCommandConfig (
279122 self .args .input_path ,
@@ -295,19 +138,6 @@ def get_import_config_excel(self, _: Any) -> ImportExcelCommandConfig:
295138 self .args .input_path , self .args .output_path , self .args .parser
296139 )
297140
298- def get_server_config (self ) -> ServerCommandConfig :
299- return ServerCommandConfig (
300- input_path = self .args .input_path ,
301- output_path = self .args .output_path ,
302- config_path = self .args .config ,
303- reload = self .args .reload ,
304- host = self .args .host ,
305- port = self .args .port ,
306- )
307-
308- def get_dump_grammar_config (self ) -> DumpGrammarCommandConfig :
309- return DumpGrammarCommandConfig (output_file = self .args .output_file )
310-
311141
312142def create_sdoc_args_parser (
313143 testing_args : Optional [argparse .Namespace ] = None ,
@@ -317,4 +147,4 @@ def create_sdoc_args_parser(
317147 builder = CommandParserBuilder ()
318148 parser = builder .build ()
319149 args = parser .parse_args ()
320- return SDocArgsParser (args )
150+ return SDocArgsParser (args , COMMAND_REGISTRY )
0 commit comments