-
Notifications
You must be signed in to change notification settings - Fork 13
Expand file tree
/
Copy pathrunparams.py
More file actions
155 lines (129 loc) · 7.45 KB
/
Copy pathrunparams.py
File metadata and controls
155 lines (129 loc) · 7.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
# the parameters of a run
# SPDX-License-Identifier: Apache-2.0
import argparse
import importlib.util
import logging
import shutil
import sys
from datetime import datetime, timezone
from pathlib import Path
from types import SimpleNamespace
class RunParams(SimpleNamespace):
def __init__(self, name, logger):
self.logger = logger
self.name = name
self._ts = datetime.now(timezone.utc)
self.process_args()
self.check_requirements()
@property
def autogen_header(self):
return f"Automatically generated by spec-parser v{self.parser_version} on {self._ts.isoformat()}"
@property
def parser_version(self):
return sys.modules["spec_parser"].__version__
@property
def all_as_dict(self):
return {k: getattr(self, k) for k in ("autogen_header",)}
def check_requirements(self):
def check_import_module(module_name, condition):
if importlib.util.find_spec(module_name) is None:
self.logger.error(f"Python module '{module_name}' is required when {condition} is specified. Make sure it's installed.")
def check_external_program(program_name, condition):
if shutil.which(program_name) is None:
self.logger.error(
f"Program '{program_name}' is required when {condition} is specified. Make sure it's installed and present in your PATH."
)
if self.generate_jsondump:
check_import_module("jsonpickle", "JSON dump generation")
if self.generate_mkdocs:
check_import_module("jinja2", "MkDocs generation")
if self.generate_rdf:
check_import_module("rdflib", "RDF generation")
if self.generate_tex:
check_external_program("pandoc", "TeX generation")
check_import_module("jinja2", "TeX generation")
if self.generate_singlefile:
check_external_program("pandoc", "singlefile generation")
check_import_module("jinja2", "singlefile generation")
def process_args(self, opts=sys.argv[1:]):
def check_input_path(p):
if not p.exists():
raise argparse.ArgumentTypeError(f"Input directory '{p}' does not exist.")
if not p.is_dir():
raise argparse.ArgumentTypeError(f"Input path '{p}' is not a directory.")
if p.name != "model":
raise argparse.ArgumentTypeError(f"Input directory '{p}' must be named 'model'.")
parser = argparse.ArgumentParser(description="Generate documentation from an SPDXv3 model.")
parser.add_argument("input_dir", type=str, help="Path to the input 'model' directory.")
parser.add_argument("-d", "--debug", action="store_true", help="Print spec-parser debug information.")
parser.add_argument("-f", "--force", action="store_true", help="Force overwrite of existing output directories.")
parser.add_argument("-j", "--generate-jsondump", action="store_true", help="Generate a dump of the model in JSON format.")
parser.add_argument("-J", "--output-jsondump", type=str, help="Output directory for JSON dump file.")
parser.add_argument("-m", "--generate-mkdocs", action="store_true", help="Generate MkDocs output.")
parser.add_argument("-M", "--output-mkdocs", type=str, help="Output directory for MkDocs files.")
parser.add_argument("-n", "--no-output", action="store_true", help="Perform no output generation, only input validation.")
parser.add_argument("-o", "--output", type=str, help="Single output directory for all output types.")
parser.add_argument("-p", "--generate-plantuml", action="store_true", help="Generate PlantUML output.")
parser.add_argument("-P", "--output-plantuml", type=str, help="Output directory for PlantUML files.")
parser.add_argument("-r", "--generate-rdf", action="store_true", help="Generate RDF output.")
parser.add_argument("-R", "--output-rdf", type=str, help="Output directory for RDF files.")
parser.add_argument("-t", "--generate-tex", action="store_true", help="Generate TeX output.")
parser.add_argument("-T", "--output-tex", type=str, help="Output directory for TeX files.")
parser.add_argument("-v", "--verbose", action="store_true", help="Print verbose information.")
parser.add_argument("-V", "--version", action="version", version=f"%(prog)s {self.parser_version}")
parser.add_argument("-w", "--generate-webpages", action="store_true", help="Generate web pages output.")
parser.add_argument("-W", "--output-webpages", type=str, help="Output directory for web pages.")
parser.add_argument("-x", "--generate-singlefile", action="store_true", help="Generate singlefile Markdown output.")
parser.add_argument("-X", "--output-singlefile", type=str, help="Output directory for singlefile Markdown file.")
opts = parser.parse_args()
gen_list = ["jsondump", "mkdocs", "plantuml", "rdf", "tex", "webpages", "singlefile"]
desc_list = ["JSON dump", "MkDocs", "PlantUML", "RDF", "TeX", "Web pages", "singlefile Markdown document"]
if opts.verbose:
self.logger.setLevel(level=logging.INFO)
if opts.debug:
self.logger.setLevel(level=logging.DEBUG)
self.input_path = Path(opts.input_dir)
check_input_path(self.input_path)
if opts.no_output:
self.no_output = True
if any(getattr(opts, "generate_" + g) for g in gen_list):
self.logger.warning("Incompatible flag combination: -n/--no-output overwrites any generation")
for g in gen_list:
setattr(self, "generate_" + g, False)
else:
self.no_output = False
if not any(getattr(opts, "generate_" + g) for g in gen_list):
for g in gen_list:
setattr(self, "generate_" + g, True)
else:
for g in gen_list:
setattr(self, "generate_" + g, getattr(opts, "generate_" + g))
if opts.output:
self.output_path = Path(opts.output)
if self.output_path.exists() and not opts.force:
self.logger.error(f"Output directory '{self.output_path}' already exists (use -f/--force to overwrite).")
for desc, g in zip(desc_list, gen_list):
genflag = "generate_" + g
if getattr(self, genflag, False):
outdir = "output_" + g
outpath = outdir + "_path"
if d := getattr(opts, outdir, None):
setattr(self, outpath, Path(d))
elif p := getattr(self, "output_path", None):
setattr(self, outpath, p / g)
else:
self.logger.error(f"{desc} was specified, but no output directory.")
if p := getattr(self, outpath, None):
if p.exists() and not opts.force:
self.logger.error(f"Output directory '{p}' already exists (use -f/--force to overwrite).")
self.force = opts.force
def create_output_dirs(self):
gen_list = ["jsondump", "mkdocs", "plantuml", "rdf", "tex", "webpages", "singlefile"]
for g in gen_list:
genflag = "generate_" + g
if getattr(self, genflag, False):
outpath = "output_" + g + "_path"
p = getattr(self, outpath)
if self.force and p.exists():
shutil.rmtree(p)
p.mkdir(parents=True)