Bases: CommandPlusDocs
flowchart TD
trestle.core.commands.assemble.AssembleCmd[AssembleCmd]
trestle.core.commands.command_docs.CommandPlusDocs[CommandPlusDocs]
trestle.core.commands.command_docs.CommandBase[CommandBase]
trestle.core.commands.command_docs.CommandPlusDocs --> trestle.core.commands.assemble.AssembleCmd
trestle.core.commands.command_docs.CommandBase --> trestle.core.commands.command_docs.CommandPlusDocs
click trestle.core.commands.assemble.AssembleCmd href "" "trestle.core.commands.assemble.AssembleCmd"
click trestle.core.commands.command_docs.CommandPlusDocs href "" "trestle.core.commands.command_docs.CommandPlusDocs"
click trestle.core.commands.command_docs.CommandBase href "" "trestle.core.commands.command_docs.CommandBase"
Assemble all subcomponents from a specified trestle model into a single JSON/YAML file under dist.
Source code in trestle/core/commands/assemble.py
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 | class AssembleCmd(CommandPlusDocs):
"""Assemble all subcomponents from a specified trestle model into a single JSON/YAML file under dist."""
name = 'assemble'
def _init_arguments(self) -> None:
self.add_argument('model', help='', choices=const.MODEL_TYPE_LIST)
self.add_argument('-n', '--name', help='Name of a single model to assemble.')
self.add_argument('-t', '--type', action='store_true', help='Assemble all models of the given type.')
self.add_argument(
'-x', '--extension', help='Type of file output.', choices=['json', 'yaml', 'yml'], default='json'
)
def _run(self, args: argparse.Namespace) -> int:
try:
return self.assemble_model(args.model, args)
except Exception as e: # pragma: no cover
return handle_generic_command_exception(e, logger, 'Error while assembling OSCAL model')
@classmethod
def assemble_model(cls, model_alias: str, args: argparse.Namespace) -> int:
"""Assemble a top level OSCAL model within the trestle dist directory."""
log.set_log_level_from_args(args)
logger.info(f'Assembling models of type {model_alias}.')
trestle_root = args.trestle_root # trestle root is set via command line in args. Default is cwd.
if not trestle_root or not file_utils.is_valid_project_root(args.trestle_root):
raise TrestleRootError(f'Given directory {trestle_root} is not a trestle project.')
model_names = []
if args.name:
model_names = [args.name]
logger.info(f'Assembling single model of type {model_alias}: {args.name}.')
else:
model_names = ModelUtils.get_models_of_type(model_alias, trestle_root)
nmodels = len(model_names)
logger.info(f'Assembling {nmodels} found models of type {model_alias}.')
if len(model_names) == 0:
logger.info(f'No models found to assemble of type {model_alias}.')
return CmdReturnCodes.SUCCESS.value
for model_name in model_names:
# contruct path to the model file name
root_model_dir = trestle_root / ModelUtils.model_type_to_model_dir(model_alias)
model_file_type = file_utils.get_contextual_file_type(root_model_dir / model_name)
model_file_name = f'{model_alias}{FileContentType.to_file_extension(model_file_type)}'
root_model_filepath = root_model_dir / model_name / model_file_name
if not root_model_filepath.exists():
raise TrestleError(f'No top level model file at {root_model_dir}')
assembled_model = load_validate_model_path(args.trestle_root, root_model_filepath)
plural_alias = ModelUtils.model_type_to_model_dir(model_alias)
assembled_model_dir = trestle_root / const.TRESTLE_DIST_DIR / plural_alias
assembled_model_filepath = assembled_model_dir / f'{model_name}.{args.extension}'
plan = Plan()
plan.add_action(CreatePathAction(assembled_model_filepath, True))
plan.add_action(
WriteFileAction(
assembled_model_filepath,
Element(assembled_model),
FileContentType.to_content_type(f'.{args.extension}')
)
)
plan.execute()
return CmdReturnCodes.SUCCESS.value
|
Attributes
name = 'assemble' class-attribute instance-attribute
Functions
assemble_model(model_alias, args) classmethod
Assemble a top level OSCAL model within the trestle dist directory.
Source code in trestle/core/commands/assemble.py
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 | @classmethod
def assemble_model(cls, model_alias: str, args: argparse.Namespace) -> int:
"""Assemble a top level OSCAL model within the trestle dist directory."""
log.set_log_level_from_args(args)
logger.info(f'Assembling models of type {model_alias}.')
trestle_root = args.trestle_root # trestle root is set via command line in args. Default is cwd.
if not trestle_root or not file_utils.is_valid_project_root(args.trestle_root):
raise TrestleRootError(f'Given directory {trestle_root} is not a trestle project.')
model_names = []
if args.name:
model_names = [args.name]
logger.info(f'Assembling single model of type {model_alias}: {args.name}.')
else:
model_names = ModelUtils.get_models_of_type(model_alias, trestle_root)
nmodels = len(model_names)
logger.info(f'Assembling {nmodels} found models of type {model_alias}.')
if len(model_names) == 0:
logger.info(f'No models found to assemble of type {model_alias}.')
return CmdReturnCodes.SUCCESS.value
for model_name in model_names:
# contruct path to the model file name
root_model_dir = trestle_root / ModelUtils.model_type_to_model_dir(model_alias)
model_file_type = file_utils.get_contextual_file_type(root_model_dir / model_name)
model_file_name = f'{model_alias}{FileContentType.to_file_extension(model_file_type)}'
root_model_filepath = root_model_dir / model_name / model_file_name
if not root_model_filepath.exists():
raise TrestleError(f'No top level model file at {root_model_dir}')
assembled_model = load_validate_model_path(args.trestle_root, root_model_filepath)
plural_alias = ModelUtils.model_type_to_model_dir(model_alias)
assembled_model_dir = trestle_root / const.TRESTLE_DIST_DIR / plural_alias
assembled_model_filepath = assembled_model_dir / f'{model_name}.{args.extension}'
plan = Plan()
plan.add_action(CreatePathAction(assembled_model_filepath, True))
plan.add_action(
WriteFileAction(
assembled_model_filepath,
Element(assembled_model),
FileContentType.to_content_type(f'.{args.extension}')
)
)
plan.execute()
return CmdReturnCodes.SUCCESS.value
|