archi-cli 0.2.1__tar.gz → 0.2.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {archi_cli-0.2.1 → archi_cli-0.2.2}/PKG-INFO +1 -1
- {archi_cli-0.2.1 → archi_cli-0.2.2}/pyproject.toml +2 -5
- {archi_cli-0.2.1 → archi_cli-0.2.2}/tools/archi_tool/cli.py +165 -85
- {archi_cli-0.2.1 → archi_cli-0.2.2}/tools/archi_tool/discovery.py +12 -9
- {archi_cli-0.2.1 → archi_cli-0.2.2}/tools/archi_tool/engine.py +127 -76
- {archi_cli-0.2.1 → archi_cli-0.2.2}/tools/archi_tool/links.py +21 -12
- {archi_cli-0.2.1 → archi_cli-0.2.2}/tools/archi_tool/model.py +146 -63
- {archi_cli-0.2.1 → archi_cli-0.2.2}/tools/archi_tool/normalize.py +26 -9
- {archi_cli-0.2.1 → archi_cli-0.2.2}/tools/archi_tool/render.py +35 -15
- {archi_cli-0.2.1 → archi_cli-0.2.2}/tools/archi_tool/render_html.py +229 -135
- {archi_cli-0.2.1 → archi_cli-0.2.2}/tools/archi_tool/render_slides.py +173 -114
- {archi_cli-0.2.1 → archi_cli-0.2.2}/tools/archi_tool/validate.py +53 -29
- {archi_cli-0.2.1 → archi_cli-0.2.2}/tools/archi_tool/views.py +99 -49
- {archi_cli-0.2.1 → archi_cli-0.2.2}/.gitignore +0 -0
- {archi_cli-0.2.1 → archi_cli-0.2.2}/LICENSE +0 -0
- {archi_cli-0.2.1 → archi_cli-0.2.2}/NOTICE +0 -0
- {archi_cli-0.2.1 → archi_cli-0.2.2}/README.md +0 -0
- {archi_cli-0.2.1 → archi_cli-0.2.2}/tools/archi_tool/__init__.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: archi-cli
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.2
|
|
4
4
|
Summary: ar·cli·mate — de CLI in je ArchiMate: deterministisch native .archimate-modellen inspecteren, muteren, valideren en renderen
|
|
5
5
|
Project-URL: Homepage, https://github.com/BureauArchitectuurDigitaleOverheid/ai-assisted-architecting
|
|
6
6
|
Project-URL: Repository, https://github.com/BureauArchitectuurDigitaleOverheid/ai-assisted-architecting
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[project]
|
|
2
2
|
name = "archi-cli"
|
|
3
|
-
version = "0.2.
|
|
3
|
+
version = "0.2.2"
|
|
4
4
|
description = "ar·cli·mate — de CLI in je ArchiMate: deterministisch native .archimate-modellen inspecteren, muteren, valideren en renderen"
|
|
5
5
|
readme = "README.md"
|
|
6
6
|
license = "EUPL-1.2"
|
|
@@ -56,10 +56,7 @@ dev = ["pytest>=8", "pre-commit>=4"]
|
|
|
56
56
|
target-version = "py312"
|
|
57
57
|
|
|
58
58
|
[tool.ruff.lint]
|
|
59
|
-
|
|
60
|
-
# separate PR once the open feature branches have landed, so this one does
|
|
61
|
-
# not cause merge conflicts in every file.
|
|
62
|
-
select = ["E", "F", "W", "B"]
|
|
59
|
+
select = ["E", "F", "W", "B", "I"]
|
|
63
60
|
ignore = [
|
|
64
61
|
"E501", # line length is left to the formatter
|
|
65
62
|
"B008", # Typer declares options as call defaults by design
|
|
@@ -5,6 +5,7 @@ Mutating subcommands validate the model in memory and refuse to save when
|
|
|
5
5
|
validation errors are found. Run `archi normalize` before committing so the
|
|
6
6
|
serialization stays Archi-canonical.
|
|
7
7
|
"""
|
|
8
|
+
|
|
8
9
|
from __future__ import annotations
|
|
9
10
|
|
|
10
11
|
import sys
|
|
@@ -42,7 +43,8 @@ def report_validation(model, model_path) -> bool:
|
|
|
42
43
|
# anchor conventions discovery at the model, not the working directory, so
|
|
43
44
|
# validating a model from another project uses that project's conventions
|
|
44
45
|
allowed_keys, _ = discover_conventions(
|
|
45
|
-
model_path, start=Path(model_path).resolve().parent
|
|
46
|
+
model_path, start=Path(model_path).resolve().parent
|
|
47
|
+
)
|
|
46
48
|
# validation runs after every mutation: a broken links file must not
|
|
47
49
|
# block modelling (ADR 0010), so here it degrades to a warning; render
|
|
48
50
|
# and slides, which actually use the links, still fail on it
|
|
@@ -75,6 +77,7 @@ def describe(model, node) -> str:
|
|
|
75
77
|
|
|
76
78
|
# --- subcommand implementations ---------------------------------------------
|
|
77
79
|
|
|
80
|
+
|
|
78
81
|
def cmd_stats(model, args):
|
|
79
82
|
print(f"Model: {model.name}")
|
|
80
83
|
counts = Counter(xsi_type(e) for e in model.elements())
|
|
@@ -115,8 +118,9 @@ def cmd_show(model, args):
|
|
|
115
118
|
node_id = node.get("id")
|
|
116
119
|
index = model.id_index()
|
|
117
120
|
for rel in model.relations_of(node_id):
|
|
118
|
-
other_id = (
|
|
119
|
-
|
|
121
|
+
other_id = (
|
|
122
|
+
rel.get("target") if rel.get("source") == node_id else rel.get("source")
|
|
123
|
+
)
|
|
120
124
|
other = index.get(other_id)
|
|
121
125
|
direction = "->" if rel.get("source") == node_id else "<-"
|
|
122
126
|
other_name = other.get("name") if other is not None else other_id
|
|
@@ -129,8 +133,11 @@ def cmd_tree(model, args):
|
|
|
129
133
|
children = folder.findall("element")
|
|
130
134
|
indent = " " * depth
|
|
131
135
|
folder_type = folder.get("type")
|
|
132
|
-
label = (
|
|
133
|
-
|
|
136
|
+
label = (
|
|
137
|
+
f"{folder.get('name')} ({folder_type})"
|
|
138
|
+
if folder_type
|
|
139
|
+
else folder.get("name")
|
|
140
|
+
)
|
|
134
141
|
print(f"{indent}{label}: {len(children)} item(s)")
|
|
135
142
|
for el in children:
|
|
136
143
|
if is_element(el) or el.get("name"):
|
|
@@ -151,11 +158,15 @@ def cmd_validate(model, args):
|
|
|
151
158
|
|
|
152
159
|
|
|
153
160
|
def cmd_add_element(model, args):
|
|
154
|
-
el = model.add_element(
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
161
|
+
el = model.add_element(
|
|
162
|
+
args.type,
|
|
163
|
+
args.name,
|
|
164
|
+
folder_type=args.folder,
|
|
165
|
+
properties=parse_properties(args.property),
|
|
166
|
+
documentation=args.documentation,
|
|
167
|
+
subfolder=args.subfolder,
|
|
168
|
+
create_subfolder=args.create_subfolder,
|
|
169
|
+
)
|
|
159
170
|
status = save_validated(model, args)
|
|
160
171
|
if status == 0:
|
|
161
172
|
print(f"Toegevoegd: {describe(model, el)}")
|
|
@@ -163,13 +174,20 @@ def cmd_add_element(model, args):
|
|
|
163
174
|
|
|
164
175
|
|
|
165
176
|
def cmd_add_relation(model, args):
|
|
166
|
-
rel = model.add_relation(
|
|
167
|
-
|
|
168
|
-
|
|
177
|
+
rel = model.add_relation(
|
|
178
|
+
args.type,
|
|
179
|
+
args.source,
|
|
180
|
+
args.target,
|
|
181
|
+
name=args.name,
|
|
182
|
+
subfolder=args.subfolder,
|
|
183
|
+
create_subfolder=args.create_subfolder,
|
|
184
|
+
)
|
|
169
185
|
status = save_validated(model, args)
|
|
170
186
|
if status == 0:
|
|
171
|
-
print(
|
|
172
|
-
|
|
187
|
+
print(
|
|
188
|
+
f"Toegevoegd: {rel.get('id')} [{xsi_type(rel)}] "
|
|
189
|
+
f"{args.source} -> {args.target}"
|
|
190
|
+
)
|
|
173
191
|
return status
|
|
174
192
|
|
|
175
193
|
|
|
@@ -185,8 +203,9 @@ def cmd_set_property(model, args):
|
|
|
185
203
|
|
|
186
204
|
|
|
187
205
|
def cmd_move(model, args):
|
|
188
|
-
target = model.move(
|
|
189
|
-
|
|
206
|
+
target = model.move(
|
|
207
|
+
args.ref, args.subfolder, create_subfolder=args.create_subfolder
|
|
208
|
+
)
|
|
190
209
|
status = save_validated(model, args)
|
|
191
210
|
if status == 0:
|
|
192
211
|
print(f"Verplaatst: '{args.ref}' naar folder '{target.get('name')}'")
|
|
@@ -237,21 +256,26 @@ def cmd_add_view(model, args):
|
|
|
237
256
|
extra = [model.resolve(ref) for ref in (args.element or [])]
|
|
238
257
|
for node in extra:
|
|
239
258
|
if not is_element(node):
|
|
240
|
-
raise ModelError(
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
259
|
+
raise ModelError(f"'{node.get('name') or node.get('id')}' is geen element")
|
|
260
|
+
diagram = add_view(
|
|
261
|
+
model,
|
|
262
|
+
args.name,
|
|
263
|
+
layout=args.layout,
|
|
264
|
+
element_types=set(args.type) if args.type else None,
|
|
265
|
+
relation_types=(set(args.relation) if args.relation else None),
|
|
266
|
+
prop=args.property,
|
|
267
|
+
root=args.root,
|
|
268
|
+
related=args.related,
|
|
269
|
+
extra_elements=extra or None,
|
|
270
|
+
)
|
|
249
271
|
status = save_validated(model, args)
|
|
250
272
|
if status == 0:
|
|
251
273
|
objects = len(diagram.findall("child"))
|
|
252
274
|
connections = len(list(diagram.iter("sourceConnection")))
|
|
253
|
-
print(
|
|
254
|
-
|
|
275
|
+
print(
|
|
276
|
+
f"View '{args.name}' aangemaakt: {objects} objecten, "
|
|
277
|
+
f"{connections} verbindingen"
|
|
278
|
+
)
|
|
255
279
|
return status
|
|
256
280
|
|
|
257
281
|
|
|
@@ -263,6 +287,7 @@ def cmd_normalize(model, args):
|
|
|
263
287
|
|
|
264
288
|
def cmd_setup(model, args):
|
|
265
289
|
from .engine import download_engine, find_or_none
|
|
290
|
+
|
|
266
291
|
existing = find_or_none()
|
|
267
292
|
if existing:
|
|
268
293
|
print(f"Archi al beschikbaar: {existing}")
|
|
@@ -278,15 +303,22 @@ def cmd_render(model, args):
|
|
|
278
303
|
html_dir = Path(args.out) / "html"
|
|
279
304
|
html_written, html_removed = render_all_html(model, html_dir, links=links)
|
|
280
305
|
deck_written, deck_removed = render_all_slides(
|
|
281
|
-
model, Path(args.decks), html_dir / "slides", links=links
|
|
306
|
+
model, Path(args.decks), html_dir / "slides", links=links
|
|
307
|
+
)
|
|
282
308
|
for path in written + html_written + deck_written:
|
|
283
309
|
print(f"Geschreven: {path}")
|
|
284
310
|
for path in removed + html_removed:
|
|
285
311
|
print(f"Verwijderd (view bestaat niet meer): {path}")
|
|
286
312
|
for path in deck_removed:
|
|
287
313
|
print(f"Verwijderd (deck bestaat niet meer): {path}")
|
|
288
|
-
if not (
|
|
289
|
-
|
|
314
|
+
if not (
|
|
315
|
+
written
|
|
316
|
+
or removed
|
|
317
|
+
or html_written
|
|
318
|
+
or html_removed
|
|
319
|
+
or deck_written
|
|
320
|
+
or deck_removed
|
|
321
|
+
):
|
|
290
322
|
print("Views zijn al actueel.")
|
|
291
323
|
view_files = set(view_stems(model).values())
|
|
292
324
|
for warning in check_link_files(links, args.out, html_dir, view_files):
|
|
@@ -302,13 +334,13 @@ def cmd_slides(model, args):
|
|
|
302
334
|
deck = load_deck(Path(deck_path), model)
|
|
303
335
|
path = Path(args.out) / f"{deck['slug']}.html"
|
|
304
336
|
path.parent.mkdir(parents=True, exist_ok=True)
|
|
305
|
-
if write_if_changed(path, render_deck_html(model, deck,
|
|
306
|
-
links=links)):
|
|
337
|
+
if write_if_changed(path, render_deck_html(model, deck, links=links)):
|
|
307
338
|
written.append(path)
|
|
308
339
|
removed = []
|
|
309
340
|
else:
|
|
310
341
|
written, removed = render_all_slides(
|
|
311
|
-
model, Path(args.decks), Path(args.out), links=links
|
|
342
|
+
model, Path(args.decks), Path(args.out), links=links
|
|
343
|
+
)
|
|
312
344
|
for path in written:
|
|
313
345
|
print(f"Geschreven: {path}")
|
|
314
346
|
for path in removed:
|
|
@@ -333,16 +365,21 @@ de serialisatie Archi-canoniek blijft.
|
|
|
333
365
|
"""
|
|
334
366
|
|
|
335
367
|
app = typer.Typer(
|
|
336
|
-
help=HELP,
|
|
337
|
-
|
|
368
|
+
help=HELP,
|
|
369
|
+
no_args_is_help=True,
|
|
370
|
+
add_completion=True,
|
|
371
|
+
context_settings={"help_option_names": ["-h", "--help"]},
|
|
372
|
+
)
|
|
338
373
|
|
|
339
374
|
# the global --model, shared by every command through the app callback
|
|
340
375
|
_state = SimpleNamespace(model=None)
|
|
341
376
|
|
|
342
377
|
ModelOption = typer.Option(
|
|
343
|
-
None,
|
|
378
|
+
None,
|
|
379
|
+
"--model",
|
|
344
380
|
help="pad naar het .archimate-bestand; standaard gevonden via archi.toml "
|
|
345
|
-
|
|
381
|
+
"of het enige .archimate-bestand in de huidige map",
|
|
382
|
+
)
|
|
346
383
|
|
|
347
384
|
|
|
348
385
|
@app.callback()
|
|
@@ -375,7 +412,8 @@ def _run(command_fn, *, load_model=True, need_model=True, **fields) -> None:
|
|
|
375
412
|
|
|
376
413
|
# Repeated options declared once; Typer reads the default value + help here.
|
|
377
414
|
PropertyFilter = typer.Option(
|
|
378
|
-
None, "--property", help="filter op property, key=value (herhaalbaar)"
|
|
415
|
+
None, "--property", help="filter op property, key=value (herhaalbaar)"
|
|
416
|
+
)
|
|
379
417
|
|
|
380
418
|
|
|
381
419
|
@app.command(help="aantallen per type, relaties en views")
|
|
@@ -386,7 +424,8 @@ def stats():
|
|
|
386
424
|
@app.command("list", help="elementen tonen, optioneel gefilterd")
|
|
387
425
|
def list_elements(
|
|
388
426
|
type: Optional[str] = typer.Option(
|
|
389
|
-
None, help="filter op elementtype (bv. Capability)"
|
|
427
|
+
None, help="filter op elementtype (bv. Capability)"
|
|
428
|
+
),
|
|
390
429
|
property: Optional[list[str]] = PropertyFilter,
|
|
391
430
|
):
|
|
392
431
|
_run(cmd_list, type=type, property=property)
|
|
@@ -410,9 +449,11 @@ def validate_command():
|
|
|
410
449
|
@app.command("normalize", help="serialisatie canoniek maken via de Archi CLI")
|
|
411
450
|
def normalize_command(
|
|
412
451
|
no_download: bool = typer.Option(
|
|
413
|
-
False,
|
|
452
|
+
False,
|
|
453
|
+
"--no-download",
|
|
414
454
|
help="haal de Archi-engine niet automatisch op; faal als hij "
|
|
415
|
-
|
|
455
|
+
"ontbreekt (voor CI en luchtdichte omgevingen)",
|
|
456
|
+
),
|
|
416
457
|
):
|
|
417
458
|
_run(cmd_normalize, load_model=False, no_download=no_download)
|
|
418
459
|
|
|
@@ -427,51 +468,68 @@ def add_element(
|
|
|
427
468
|
type: str = typer.Option(..., help="elementtype (bv. Capability)"),
|
|
428
469
|
name: str = typer.Option(..., help="naam van het element"),
|
|
429
470
|
folder: Optional[str] = typer.Option(
|
|
430
|
-
None, help="folder-type; default volgt uit het type"
|
|
471
|
+
None, help="folder-type; default volgt uit het type"
|
|
472
|
+
),
|
|
431
473
|
property: Optional[list[str]] = typer.Option(
|
|
432
|
-
None, "--property", help="key=value (herhaalbaar)"
|
|
474
|
+
None, "--property", help="key=value (herhaalbaar)"
|
|
475
|
+
),
|
|
433
476
|
documentation: Optional[str] = typer.Option(None),
|
|
434
477
|
subfolder: Optional[str] = typer.Option(
|
|
435
|
-
None, help="submap binnen de laagfolder, geneste mappen met '/'"
|
|
478
|
+
None, help="submap binnen de laagfolder, geneste mappen met '/'"
|
|
479
|
+
),
|
|
436
480
|
create_subfolder: bool = typer.Option(
|
|
437
|
-
False, "--create-subfolder",
|
|
438
|
-
|
|
481
|
+
False, "--create-subfolder", help="ontbrekende submap aanmaken (anders: fout)"
|
|
482
|
+
),
|
|
439
483
|
):
|
|
440
|
-
_run(
|
|
441
|
-
|
|
442
|
-
|
|
484
|
+
_run(
|
|
485
|
+
cmd_add_element,
|
|
486
|
+
type=type,
|
|
487
|
+
name=name,
|
|
488
|
+
folder=folder,
|
|
489
|
+
property=property,
|
|
490
|
+
documentation=documentation,
|
|
491
|
+
subfolder=subfolder,
|
|
492
|
+
create_subfolder=create_subfolder,
|
|
493
|
+
)
|
|
443
494
|
|
|
444
495
|
|
|
445
496
|
@app.command("add-relation", help="relatie toevoegen")
|
|
446
497
|
def add_relation(
|
|
447
|
-
type: str = typer.Option(
|
|
448
|
-
..., help="bv. Aggregation of AggregationRelationship"),
|
|
498
|
+
type: str = typer.Option(..., help="bv. Aggregation of AggregationRelationship"),
|
|
449
499
|
source: str = typer.Option(..., help="id of unieke naam"),
|
|
450
500
|
target: str = typer.Option(..., help="id of unieke naam"),
|
|
451
501
|
name: Optional[str] = typer.Option(None, help="NL-label op de relatie"),
|
|
452
502
|
subfolder: Optional[str] = typer.Option(
|
|
453
|
-
None, help="submap binnen Relations, geneste mappen met '/'"
|
|
503
|
+
None, help="submap binnen Relations, geneste mappen met '/'"
|
|
504
|
+
),
|
|
454
505
|
create_subfolder: bool = typer.Option(
|
|
455
|
-
False, "--create-subfolder",
|
|
456
|
-
|
|
506
|
+
False, "--create-subfolder", help="ontbrekende submap aanmaken (anders: fout)"
|
|
507
|
+
),
|
|
457
508
|
):
|
|
458
|
-
_run(
|
|
459
|
-
|
|
460
|
-
|
|
509
|
+
_run(
|
|
510
|
+
cmd_add_relation,
|
|
511
|
+
type=type,
|
|
512
|
+
source=source,
|
|
513
|
+
target=target,
|
|
514
|
+
name=name,
|
|
515
|
+
subfolder=subfolder,
|
|
516
|
+
create_subfolder=create_subfolder,
|
|
517
|
+
)
|
|
461
518
|
|
|
462
519
|
|
|
463
520
|
@app.command(help="element, relatie of view naar een submap verplaatsen")
|
|
464
521
|
def move(
|
|
465
522
|
ref: str = typer.Argument(help="id of (unieke) naam"),
|
|
466
523
|
subfolder: str = typer.Option(
|
|
467
|
-
...,
|
|
468
|
-
|
|
524
|
+
...,
|
|
525
|
+
help="submap binnen de huidige laagfolder, geneste mappen met "
|
|
526
|
+
"'/'; leeg ('') = terug naar de laagfolder zelf",
|
|
527
|
+
),
|
|
469
528
|
create_subfolder: bool = typer.Option(
|
|
470
|
-
False, "--create-subfolder",
|
|
471
|
-
|
|
529
|
+
False, "--create-subfolder", help="ontbrekende submap aanmaken (anders: fout)"
|
|
530
|
+
),
|
|
472
531
|
):
|
|
473
|
-
_run(cmd_move, ref=ref, subfolder=subfolder,
|
|
474
|
-
create_subfolder=create_subfolder)
|
|
532
|
+
_run(cmd_move, ref=ref, subfolder=subfolder, create_subfolder=create_subfolder)
|
|
475
533
|
|
|
476
534
|
|
|
477
535
|
@app.command("set-property", help="property zetten of bijwerken")
|
|
@@ -510,8 +568,8 @@ def set_documentation(
|
|
|
510
568
|
def remove(
|
|
511
569
|
ref: str = typer.Argument(help="id of (unieke) naam"),
|
|
512
570
|
cascade: bool = typer.Option(
|
|
513
|
-
False, help="verwijder ook relaties en view-objecten die ernaar "
|
|
514
|
-
|
|
571
|
+
False, help="verwijder ook relaties en view-objecten die ernaar verwijzen"
|
|
572
|
+
),
|
|
515
573
|
):
|
|
516
574
|
_run(cmd_remove, ref=ref, cascade=cascade)
|
|
517
575
|
|
|
@@ -524,9 +582,11 @@ def set_model_name(name: str = typer.Argument(help="nieuwe modelnaam")):
|
|
|
524
582
|
@app.command(help="views renderen naar Mermaid, NLDD-HTML en slidedecks")
|
|
525
583
|
def render(
|
|
526
584
|
out: str = typer.Option(
|
|
527
|
-
"views", help="doelmap voor de markdown-bestanden (default: views)"
|
|
585
|
+
"views", help="doelmap voor de markdown-bestanden (default: views)"
|
|
586
|
+
),
|
|
528
587
|
decks: str = typer.Option(
|
|
529
|
-
"decks", help="map met deckdefinities in TOML (default: decks)"
|
|
588
|
+
"decks", help="map met deckdefinities in TOML (default: decks)"
|
|
589
|
+
),
|
|
530
590
|
):
|
|
531
591
|
_run(cmd_render, out=out, decks=decks)
|
|
532
592
|
|
|
@@ -534,12 +594,15 @@ def render(
|
|
|
534
594
|
@app.command(help="slidedecks renderen naar zelfstandige HTML")
|
|
535
595
|
def slides(
|
|
536
596
|
deck: Optional[list[str]] = typer.Option(
|
|
537
|
-
None,
|
|
538
|
-
|
|
597
|
+
None,
|
|
598
|
+
"--deck",
|
|
599
|
+
help="specifiek deckbestand (.toml); herhaalbaar; "
|
|
600
|
+
"default: alle decks in de decks-map",
|
|
601
|
+
),
|
|
539
602
|
decks: str = typer.Option(
|
|
540
|
-
"decks", help="map met deckdefinities in TOML (default: decks)"
|
|
541
|
-
|
|
542
|
-
|
|
603
|
+
"decks", help="map met deckdefinities in TOML (default: decks)"
|
|
604
|
+
),
|
|
605
|
+
out: str = typer.Option("views/html/slides", help="doelmap voor de HTML-bestanden"),
|
|
543
606
|
):
|
|
544
607
|
_run(cmd_slides, deck=deck, decks=decks, out=out)
|
|
545
608
|
|
|
@@ -549,27 +612,44 @@ def add_view_command(
|
|
|
549
612
|
name: str = typer.Option(..., help="naam van de nieuwe view"),
|
|
550
613
|
layout: str = typer.Option("grid", help="grid of cluster"),
|
|
551
614
|
type: Optional[list[str]] = typer.Option(
|
|
552
|
-
None, help="elementtype in de selectie (herhaalbaar)"
|
|
615
|
+
None, help="elementtype in de selectie (herhaalbaar)"
|
|
616
|
+
),
|
|
553
617
|
relation: Optional[list[str]] = typer.Option(
|
|
554
|
-
None, help="relatietype in de selectie (herhaalbaar)"
|
|
618
|
+
None, help="relatietype in de selectie (herhaalbaar)"
|
|
619
|
+
),
|
|
555
620
|
property: Optional[str] = typer.Option(
|
|
556
|
-
None, "--property", help="selectiefilter, key=value"
|
|
621
|
+
None, "--property", help="selectiefilter, key=value"
|
|
622
|
+
),
|
|
557
623
|
root: Optional[str] = typer.Option(
|
|
558
|
-
None,
|
|
559
|
-
|
|
624
|
+
None,
|
|
625
|
+
help="element (id of naam): dit element plus alles wat het "
|
|
626
|
+
"aggregeert of composeert",
|
|
627
|
+
),
|
|
560
628
|
related: bool = typer.Option(
|
|
561
|
-
False,
|
|
562
|
-
|
|
629
|
+
False,
|
|
630
|
+
help="voeg ook direct gerelateerde elementen toe (één stap, "
|
|
631
|
+
"alleen samen met --root zinvol)",
|
|
632
|
+
),
|
|
563
633
|
element: Optional[list[str]] = typer.Option(
|
|
564
|
-
None,
|
|
565
|
-
|
|
634
|
+
None,
|
|
635
|
+
"--element",
|
|
636
|
+
help="element (id of unieke naam) toevoegen aan de selectie (herhaalbaar)",
|
|
637
|
+
),
|
|
566
638
|
):
|
|
567
639
|
if layout not in ("grid", "cluster"):
|
|
568
640
|
typer.echo("FOUT: --layout moet grid of cluster zijn", err=True)
|
|
569
641
|
raise typer.Exit(1)
|
|
570
|
-
_run(
|
|
571
|
-
|
|
572
|
-
|
|
642
|
+
_run(
|
|
643
|
+
cmd_add_view,
|
|
644
|
+
name=name,
|
|
645
|
+
layout=layout,
|
|
646
|
+
type=type,
|
|
647
|
+
relation=relation,
|
|
648
|
+
property=property,
|
|
649
|
+
root=root,
|
|
650
|
+
related=related,
|
|
651
|
+
element=element,
|
|
652
|
+
)
|
|
573
653
|
|
|
574
654
|
|
|
575
655
|
def main(argv=None) -> int:
|
|
@@ -17,6 +17,7 @@ Resolution order for the conventions list:
|
|
|
17
17
|
3. the built-in default set, so the property-key check stays meaningful even
|
|
18
18
|
without a project list
|
|
19
19
|
"""
|
|
20
|
+
|
|
20
21
|
from __future__ import annotations
|
|
21
22
|
|
|
22
23
|
import tomllib
|
|
@@ -78,8 +79,7 @@ def discover_model(explicit=None, start=None):
|
|
|
78
79
|
# a relative path in config is relative to the config file's directory
|
|
79
80
|
path = (config_path.parent / table["model"]).resolve()
|
|
80
81
|
if not path.exists():
|
|
81
|
-
raise ModelError(
|
|
82
|
-
f"Modelpad uit {config_path.name} bestaat niet: {path}")
|
|
82
|
+
raise ModelError(f"Modelpad uit {config_path.name} bestaat niet: {path}")
|
|
83
83
|
return path
|
|
84
84
|
|
|
85
85
|
candidates = sorted(start.glob("*.archimate"))
|
|
@@ -88,12 +88,14 @@ def discover_model(explicit=None, start=None):
|
|
|
88
88
|
if not candidates:
|
|
89
89
|
raise ModelError(
|
|
90
90
|
"Geen modelbestand gevonden. Geef --model <pad>, of zet "
|
|
91
|
-
|
|
92
|
-
"met precies één .archimate-bestand."
|
|
91
|
+
'`[tool.archi] model = "..."` in archi.toml, of draai in een map '
|
|
92
|
+
"met precies één .archimate-bestand."
|
|
93
|
+
)
|
|
93
94
|
names = ", ".join(c.name for c in candidates)
|
|
94
95
|
raise ModelError(
|
|
95
96
|
f"Meerdere .archimate-bestanden gevonden ({names}). Kies er één met "
|
|
96
|
-
"--model <pad> of leg het vast in archi.toml."
|
|
97
|
+
"--model <pad> of leg het vast in archi.toml."
|
|
98
|
+
)
|
|
97
99
|
|
|
98
100
|
|
|
99
101
|
def discover_links(model_path, start=None):
|
|
@@ -109,8 +111,7 @@ def discover_links(model_path, start=None):
|
|
|
109
111
|
return None
|
|
110
112
|
path = (config_path.parent / table["links"]).resolve()
|
|
111
113
|
if not path.exists():
|
|
112
|
-
raise ModelError(
|
|
113
|
-
f"Linkspad uit {config_path.name} bestaat niet: {path}")
|
|
114
|
+
raise ModelError(f"Linkspad uit {config_path.name} bestaat niet: {path}")
|
|
114
115
|
return path
|
|
115
116
|
|
|
116
117
|
|
|
@@ -131,11 +132,13 @@ def discover_conventions(model_path, start=None):
|
|
|
131
132
|
path = (config_path.parent / table["conventions"]).resolve()
|
|
132
133
|
if not path.exists():
|
|
133
134
|
raise ModelError(
|
|
134
|
-
f"Conventiepad uit {config_path.name} bestaat niet: {path}"
|
|
135
|
+
f"Conventiepad uit {config_path.name} bestaat niet: {path}"
|
|
136
|
+
)
|
|
135
137
|
keys = allowed_property_keys(path)
|
|
136
138
|
if not keys:
|
|
137
139
|
raise ModelError(
|
|
138
|
-
f"Conventiebestand {path} bevat geen Property-keys-sectie."
|
|
140
|
+
f"Conventiebestand {path} bevat geen Property-keys-sectie."
|
|
141
|
+
)
|
|
139
142
|
return keys, str(path)
|
|
140
143
|
|
|
141
144
|
model_dir = Path(model_path).resolve().parent
|