etcion 0.2.0__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.
- etcion-0.2.0/.coverage +0 -0
- etcion-0.2.0/.github/ISSUE_TEMPLATE/bug_report.md +31 -0
- etcion-0.2.0/.github/ISSUE_TEMPLATE/feature_request.md +23 -0
- etcion-0.2.0/.github/ISSUE_TEMPLATE/question.md +15 -0
- etcion-0.2.0/.github/workflows/ci.yml +55 -0
- etcion-0.2.0/.github/workflows/release.yml +39 -0
- etcion-0.2.0/CHANGELOG.md +67 -0
- etcion-0.2.0/CLAUDE.md +62 -0
- etcion-0.2.0/PKG-INFO +251 -0
- etcion-0.2.0/README.md +211 -0
- etcion-0.2.0/docs/adr/ADR-001-package-configuration.md +134 -0
- etcion-0.2.0/docs/adr/ADR-002-module-layout.md +217 -0
- etcion-0.2.0/docs/adr/ADR-003-conformance-profile.md +175 -0
- etcion-0.2.0/docs/adr/ADR-004-conformance-test-suite.md +172 -0
- etcion-0.2.0/docs/adr/ADR-005-undefined-type-guard.md +147 -0
- etcion-0.2.0/docs/adr/ADR-006-concept-abc.md +152 -0
- etcion-0.2.0/docs/adr/ADR-007-element-relationship-abcs.md +167 -0
- etcion-0.2.0/docs/adr/ADR-008-attribute-mixin.md +146 -0
- etcion-0.2.0/docs/adr/ADR-009-relationship-connector-abc.md +126 -0
- etcion-0.2.0/docs/adr/ADR-010-model-container.md +268 -0
- etcion-0.2.0/docs/adr/ADR-011-layer-enum-ratification.md +132 -0
- etcion-0.2.0/docs/adr/ADR-012-aspect-enum-ratification.md +130 -0
- etcion-0.2.0/docs/adr/ADR-013-notation-metadata.md +150 -0
- etcion-0.2.0/docs/adr/ADR-014-classification-metadata.md +151 -0
- etcion-0.2.0/docs/adr/ADR-015-nesting-rendering-hint.md +186 -0
- etcion-0.2.0/docs/adr/ADR-016-epic004-generic-metamodel.md +108 -0
- etcion-0.2.0/docs/adr/ADR-017-epic005-relationships.md +189 -0
- etcion-0.2.0/docs/adr/ADR-018-epic006-strategy-layer.md +133 -0
- etcion-0.2.0/docs/adr/ADR-019-epic007-business-layer.md +178 -0
- etcion-0.2.0/docs/adr/ADR-020-epic008-application-layer.md +172 -0
- etcion-0.2.0/docs/adr/ADR-021-epic009-technology-layer.md +189 -0
- etcion-0.2.0/docs/adr/ADR-022-epic010-physical-elements.md +111 -0
- etcion-0.2.0/docs/adr/ADR-023-epic011-motivation-elements.md +136 -0
- etcion-0.2.0/docs/adr/ADR-024-epic012-implementation-migration.md +160 -0
- etcion-0.2.0/docs/adr/ADR-025-epic013-cross-layer-rules.md +140 -0
- etcion-0.2.0/docs/adr/ADR-026-epic014-public-api-exports.md +88 -0
- etcion-0.2.0/docs/adr/ADR-027-epic015-validation-engine.md +137 -0
- etcion-0.2.0/docs/adr/ADR-028-epic016-declarative-permissions.md +140 -0
- etcion-0.2.0/docs/adr/ADR-029-epic017-viewpoint-mechanism.md +146 -0
- etcion-0.2.0/docs/adr/ADR-030-epic018-language-customization.md +128 -0
- etcion-0.2.0/docs/adr/ADR-031-epic019-serialization.md +189 -0
- etcion-0.2.0/docs/adr/ADR-032-epic020-conformance-cleanup.md +94 -0
- etcion-0.2.0/docs/adr/ADR-033-epic028-archi-interop.md +45 -0
- etcion-0.2.0/docs/adr/ADR-034-epic021-performance-optimization.md +97 -0
- etcion-0.2.0/docs/adr/ADR-035-epic022-predefined-viewpoint-catalogue.md +141 -0
- etcion-0.2.0/docs/adr/ADR-036-epic023-model-querying.md +110 -0
- etcion-0.2.0/docs/adr/ADR-037-epic024-model-comparison-diff.md +65 -0
- etcion-0.2.0/docs/adr/ADR-038-epic025-plugin-extension-system.md +63 -0
- etcion-0.2.0/docs/adr/ADR-039-epic026-documentation-api-reference.md +143 -0
- etcion-0.2.0/docs/adr/ADR-040-epic027-packaging-distribution-cicd.md +158 -0
- etcion-0.2.0/docs/adr/ADR-041-networkx-graph-conversion.md +102 -0
- etcion-0.2.0/docs/adr/ADR-042-pattern-gap-analysis.md +36 -0
- etcion-0.2.0/docs/adr/ADR-043-impact-analysis-engine.md +56 -0
- etcion-0.2.0/docs/adr/TEMPLATE.md +28 -0
- etcion-0.2.0/docs/api/comparison.md +3 -0
- etcion-0.2.0/docs/api/elements.md +17 -0
- etcion-0.2.0/docs/api/enums.md +3 -0
- etcion-0.2.0/docs/api/exceptions.md +3 -0
- etcion-0.2.0/docs/api/index.md +17 -0
- etcion-0.2.0/docs/api/model.md +3 -0
- etcion-0.2.0/docs/api/profiles.md +3 -0
- etcion-0.2.0/docs/api/querying.md +3 -0
- etcion-0.2.0/docs/api/relationships.md +3 -0
- etcion-0.2.0/docs/api/serialization.md +7 -0
- etcion-0.2.0/docs/api/validation.md +5 -0
- etcion-0.2.0/docs/api/viewpoints.md +5 -0
- etcion-0.2.0/docs/architecture/adr-index.md +53 -0
- etcion-0.2.0/docs/architecture/overview.md +78 -0
- etcion-0.2.0/docs/architecture/permission-matrix.md +185 -0
- etcion-0.2.0/docs/changelog.md +3 -0
- etcion-0.2.0/docs/examples/index.md +20 -0
- etcion-0.2.0/docs/getting-started.md +105 -0
- etcion-0.2.0/docs/index.md +64 -0
- etcion-0.2.0/docs/releasing.md +50 -0
- etcion-0.2.0/docs/user-guide/building-models.md +107 -0
- etcion-0.2.0/docs/user-guide/diffing.md +72 -0
- etcion-0.2.0/docs/user-guide/extending.md +69 -0
- etcion-0.2.0/docs/user-guide/profiles.md +80 -0
- etcion-0.2.0/docs/user-guide/querying.md +100 -0
- etcion-0.2.0/docs/user-guide/serialization.md +86 -0
- etcion-0.2.0/docs/user-guide/validation.md +79 -0
- etcion-0.2.0/docs/user-guide/viewpoints.md +75 -0
- etcion-0.2.0/examples/from_archi.archimate +57 -0
- etcion-0.2.0/examples/model_diff.py +61 -0
- etcion-0.2.0/examples/pet_shop-from_archi.xml +476 -0
- etcion-0.2.0/examples/pet_shop.py +342 -0
- etcion-0.2.0/examples/profile_extension.py +62 -0
- etcion-0.2.0/examples/query_builder.py +58 -0
- etcion-0.2.0/examples/quick_start.py +49 -0
- etcion-0.2.0/examples/validation_demo.py +57 -0
- etcion-0.2.0/examples/viewpoint_filter.py +50 -0
- etcion-0.2.0/examples/xml_roundtrip.py +52 -0
- etcion-0.2.0/mkdocs.yml +68 -0
- etcion-0.2.0/pyproject.toml +108 -0
- etcion-0.2.0/scripts/generate_adr_index.py +61 -0
- etcion-0.2.0/scripts/generate_permission_matrix.py +44 -0
- etcion-0.2.0/scripts/merge_tests.py +398 -0
- etcion-0.2.0/site/404.html +1359 -0
- etcion-0.2.0/site/api/comparison/index.html +2023 -0
- etcion-0.2.0/site/api/elements/index.html +1976 -0
- etcion-0.2.0/site/api/enums/index.html +2171 -0
- etcion-0.2.0/site/api/exceptions/index.html +1745 -0
- etcion-0.2.0/site/api/index.html +1421 -0
- etcion-0.2.0/site/api/model/index.html +3001 -0
- etcion-0.2.0/site/api/profiles/index.html +1612 -0
- etcion-0.2.0/site/api/querying/index.html +3001 -0
- etcion-0.2.0/site/api/relationships/index.html +2713 -0
- etcion-0.2.0/site/api/serialization/index.html +2682 -0
- etcion-0.2.0/site/api/validation/index.html +2202 -0
- etcion-0.2.0/site/api/viewpoints/index.html +2001 -0
- etcion-0.2.0/site/architecture/adr-index/index.html +1622 -0
- etcion-0.2.0/site/architecture/overview/index.html +1653 -0
- etcion-0.2.0/site/architecture/permission-matrix/index.html +2313 -0
- etcion-0.2.0/site/assets/_mkdocstrings.css +237 -0
- etcion-0.2.0/site/assets/images/favicon.png +0 -0
- etcion-0.2.0/site/assets/javascripts/bundle.79ae519e.min.js +16 -0
- etcion-0.2.0/site/assets/javascripts/bundle.79ae519e.min.js.map +7 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.ar.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.da.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.de.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.du.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.el.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.es.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.fi.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.fr.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.he.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.hi.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.hu.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.hy.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.it.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.ja.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.jp.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.kn.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.ko.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.multi.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.nl.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.no.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.pt.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.ro.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.ru.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.sa.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.stemmer.support.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.sv.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.ta.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.te.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.th.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.tr.min.js +18 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.vi.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/min/lunr.zh.min.js +1 -0
- etcion-0.2.0/site/assets/javascripts/lunr/tinyseg.js +206 -0
- etcion-0.2.0/site/assets/javascripts/lunr/wordcut.js +6708 -0
- etcion-0.2.0/site/assets/javascripts/workers/search.2c215733.min.js +42 -0
- etcion-0.2.0/site/assets/javascripts/workers/search.2c215733.min.js.map +7 -0
- etcion-0.2.0/site/assets/stylesheets/main.484c7ddc.min.css +1 -0
- etcion-0.2.0/site/assets/stylesheets/main.484c7ddc.min.css.map +1 -0
- etcion-0.2.0/site/assets/stylesheets/palette.ab4e12ef.min.css +1 -0
- etcion-0.2.0/site/assets/stylesheets/palette.ab4e12ef.min.css.map +1 -0
- etcion-0.2.0/site/changelog/index.html +1400 -0
- etcion-0.2.0/site/examples/index.html +1523 -0
- etcion-0.2.0/site/getting-started/index.html +1647 -0
- etcion-0.2.0/site/index.html +1605 -0
- etcion-0.2.0/site/objects.inv +0 -0
- etcion-0.2.0/site/search/search_index.json +1 -0
- etcion-0.2.0/site/sitemap.xml +3 -0
- etcion-0.2.0/site/sitemap.xml.gz +0 -0
- etcion-0.2.0/site/user-guide/building-models/index.html +1655 -0
- etcion-0.2.0/site/user-guide/diffing/index.html +1584 -0
- etcion-0.2.0/site/user-guide/extending/index.html +1570 -0
- etcion-0.2.0/site/user-guide/profiles/index.html +1616 -0
- etcion-0.2.0/site/user-guide/querying/index.html +1668 -0
- etcion-0.2.0/site/user-guide/serialization/index.html +1621 -0
- etcion-0.2.0/site/user-guide/validation/index.html +1629 -0
- etcion-0.2.0/site/user-guide/viewpoints/index.html +1594 -0
- etcion-0.2.0/src/etcion/__init__.py +350 -0
- etcion-0.2.0/src/etcion/comparison.py +152 -0
- etcion-0.2.0/src/etcion/conformance.py +136 -0
- etcion-0.2.0/src/etcion/derivation/__init__.py +19 -0
- etcion-0.2.0/src/etcion/derivation/engine.py +115 -0
- etcion-0.2.0/src/etcion/enums.py +117 -0
- etcion-0.2.0/src/etcion/exceptions.py +27 -0
- etcion-0.2.0/src/etcion/impact.py +590 -0
- etcion-0.2.0/src/etcion/metamodel/__init__.py +23 -0
- etcion-0.2.0/src/etcion/metamodel/application.py +162 -0
- etcion-0.2.0/src/etcion/metamodel/business.py +216 -0
- etcion-0.2.0/src/etcion/metamodel/concepts.py +129 -0
- etcion-0.2.0/src/etcion/metamodel/elements.py +112 -0
- etcion-0.2.0/src/etcion/metamodel/implementation_migration.py +99 -0
- etcion-0.2.0/src/etcion/metamodel/mixins.py +31 -0
- etcion-0.2.0/src/etcion/metamodel/model.py +374 -0
- etcion-0.2.0/src/etcion/metamodel/motivation.py +131 -0
- etcion-0.2.0/src/etcion/metamodel/notation.py +36 -0
- etcion-0.2.0/src/etcion/metamodel/physical.py +73 -0
- etcion-0.2.0/src/etcion/metamodel/profiles.py +68 -0
- etcion-0.2.0/src/etcion/metamodel/relationships.py +266 -0
- etcion-0.2.0/src/etcion/metamodel/strategy.py +72 -0
- etcion-0.2.0/src/etcion/metamodel/technology.py +210 -0
- etcion-0.2.0/src/etcion/metamodel/viewpoint_catalogue.py +1133 -0
- etcion-0.2.0/src/etcion/metamodel/viewpoints.py +83 -0
- etcion-0.2.0/src/etcion/patterns.py +1043 -0
- etcion-0.2.0/src/etcion/py.typed +0 -0
- etcion-0.2.0/src/etcion/serialization/__init__.py +1 -0
- etcion-0.2.0/src/etcion/serialization/json.py +92 -0
- etcion-0.2.0/src/etcion/serialization/registry.py +292 -0
- etcion-0.2.0/src/etcion/serialization/schema/archimate3_Diagram.xsd +554 -0
- etcion-0.2.0/src/etcion/serialization/schema/archimate3_Model.xsd +1340 -0
- etcion-0.2.0/src/etcion/serialization/schema/archimate3_View.xsd +321 -0
- etcion-0.2.0/src/etcion/serialization/xml.py +249 -0
- etcion-0.2.0/src/etcion/validation/__init__.py +20 -0
- etcion-0.2.0/src/etcion/validation/permissions.py +477 -0
- etcion-0.2.0/src/etcion/validation/rules.py +41 -0
- etcion-0.2.0/test/__init__.py +0 -0
- etcion-0.2.0/test/benchmarks/__init__.py +0 -0
- etcion-0.2.0/test/benchmarks/conftest.py +92 -0
- etcion-0.2.0/test/benchmarks/test_bench_construction.py +68 -0
- etcion-0.2.0/test/benchmarks/test_bench_import.py +49 -0
- etcion-0.2.0/test/benchmarks/test_bench_memory.py +58 -0
- etcion-0.2.0/test/benchmarks/test_bench_permissions.py +65 -0
- etcion-0.2.0/test/benchmarks/test_bench_serialization.py +68 -0
- etcion-0.2.0/test/benchmarks/test_bench_validation.py +35 -0
- etcion-0.2.0/test/conftest.py +32 -0
- etcion-0.2.0/test/derivation/__init__.py +0 -0
- etcion-0.2.0/test/derivation/test_engine.py +188 -0
- etcion-0.2.0/test/metamodel/__init__.py +0 -0
- etcion-0.2.0/test/metamodel/test_application.py +382 -0
- etcion-0.2.0/test/metamodel/test_business.py +487 -0
- etcion-0.2.0/test/metamodel/test_concepts.py +312 -0
- etcion-0.2.0/test/metamodel/test_elements.py +399 -0
- etcion-0.2.0/test/metamodel/test_graph.py +254 -0
- etcion-0.2.0/test/metamodel/test_implementation_migration.py +338 -0
- etcion-0.2.0/test/metamodel/test_model.py +814 -0
- etcion-0.2.0/test/metamodel/test_motivation.py +332 -0
- etcion-0.2.0/test/metamodel/test_notation.py +340 -0
- etcion-0.2.0/test/metamodel/test_physical.py +169 -0
- etcion-0.2.0/test/metamodel/test_profiles.py +537 -0
- etcion-0.2.0/test/metamodel/test_relationships.py +965 -0
- etcion-0.2.0/test/metamodel/test_strategy.py +158 -0
- etcion-0.2.0/test/metamodel/test_technology.py +363 -0
- etcion-0.2.0/test/metamodel/test_viewpoint_catalogue.py +830 -0
- etcion-0.2.0/test/metamodel/test_viewpoints.py +379 -0
- etcion-0.2.0/test/serialization/__init__.py +0 -0
- etcion-0.2.0/test/serialization/test_json.py +126 -0
- etcion-0.2.0/test/serialization/test_registry.py +104 -0
- etcion-0.2.0/test/serialization/test_xml.py +608 -0
- etcion-0.2.0/test/test_comparison.py +341 -0
- etcion-0.2.0/test/test_conformance.py +263 -0
- etcion-0.2.0/test/test_conformance_profile.py +214 -0
- etcion-0.2.0/test/test_docstring_coverage.py +214 -0
- etcion-0.2.0/test/test_enums.py +273 -0
- etcion-0.2.0/test/test_exports.py +136 -0
- etcion-0.2.0/test/test_impact.py +1653 -0
- etcion-0.2.0/test/test_module_layout.py +347 -0
- etcion-0.2.0/test/test_packaging.py +252 -0
- etcion-0.2.0/test/test_patterns.py +2420 -0
- etcion-0.2.0/test/test_scaffold.py +234 -0
- etcion-0.2.0/test/validation/__init__.py +0 -0
- etcion-0.2.0/test/validation/test_cross_layer.py +202 -0
- etcion-0.2.0/test/validation/test_permissions.py +1038 -0
- etcion-0.2.0/test/validation/test_rules.py +342 -0
etcion-0.2.0/.coverage
ADDED
|
Binary file
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Bug Report
|
|
3
|
+
about: Something isn't working as expected
|
|
4
|
+
title: ""
|
|
5
|
+
labels: bug
|
|
6
|
+
assignees: ""
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Describe the bug
|
|
10
|
+
|
|
11
|
+
A clear description of what the bug is.
|
|
12
|
+
|
|
13
|
+
## To reproduce
|
|
14
|
+
|
|
15
|
+
```python
|
|
16
|
+
# Minimal code that reproduces the issue
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## Expected behavior
|
|
20
|
+
|
|
21
|
+
What you expected to happen.
|
|
22
|
+
|
|
23
|
+
## Actual behavior
|
|
24
|
+
|
|
25
|
+
What actually happened. Include the full error message/traceback if applicable.
|
|
26
|
+
|
|
27
|
+
## Environment
|
|
28
|
+
|
|
29
|
+
- etcion version: (e.g., 0.1.0)
|
|
30
|
+
- Python version: (e.g., 3.12.3)
|
|
31
|
+
- OS: (e.g., Ubuntu 24.04, macOS 15, Windows 11)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Feature Request
|
|
3
|
+
about: Suggest a new capability or improvement
|
|
4
|
+
title: ""
|
|
5
|
+
labels: enhancement
|
|
6
|
+
assignees: ""
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Problem or use case
|
|
10
|
+
|
|
11
|
+
What are you trying to do? Why is the current behavior insufficient?
|
|
12
|
+
|
|
13
|
+
## Proposed solution
|
|
14
|
+
|
|
15
|
+
Describe what you'd like to happen.
|
|
16
|
+
|
|
17
|
+
## Alternatives considered
|
|
18
|
+
|
|
19
|
+
Any other approaches you've thought about.
|
|
20
|
+
|
|
21
|
+
## Additional context
|
|
22
|
+
|
|
23
|
+
Links to relevant ArchiMate spec sections, related issues, or examples from other tools.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: Question
|
|
3
|
+
about: Ask about usage, architecture, or the ArchiMate spec
|
|
4
|
+
title: ""
|
|
5
|
+
labels: question
|
|
6
|
+
assignees: ""
|
|
7
|
+
---
|
|
8
|
+
|
|
9
|
+
## Question
|
|
10
|
+
|
|
11
|
+
What would you like to know?
|
|
12
|
+
|
|
13
|
+
## Context
|
|
14
|
+
|
|
15
|
+
What are you trying to accomplish? Include code snippets if relevant.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
name: CI
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
branches: ["**"]
|
|
6
|
+
pull_request:
|
|
7
|
+
branches: ["**"]
|
|
8
|
+
|
|
9
|
+
concurrency:
|
|
10
|
+
group: ci-${{ github.ref }}
|
|
11
|
+
cancel-in-progress: true
|
|
12
|
+
|
|
13
|
+
jobs:
|
|
14
|
+
lint:
|
|
15
|
+
runs-on: ubuntu-latest
|
|
16
|
+
steps:
|
|
17
|
+
- uses: actions/checkout@v4
|
|
18
|
+
- uses: actions/setup-python@v5
|
|
19
|
+
with:
|
|
20
|
+
python-version: "3.12"
|
|
21
|
+
- run: pip install -e ".[dev]"
|
|
22
|
+
- run: ruff check src/ test/
|
|
23
|
+
|
|
24
|
+
format:
|
|
25
|
+
runs-on: ubuntu-latest
|
|
26
|
+
steps:
|
|
27
|
+
- uses: actions/checkout@v4
|
|
28
|
+
- uses: actions/setup-python@v5
|
|
29
|
+
with:
|
|
30
|
+
python-version: "3.12"
|
|
31
|
+
- run: pip install -e ".[dev]"
|
|
32
|
+
- run: ruff format --check src/ test/
|
|
33
|
+
|
|
34
|
+
typecheck:
|
|
35
|
+
runs-on: ubuntu-latest
|
|
36
|
+
steps:
|
|
37
|
+
- uses: actions/checkout@v4
|
|
38
|
+
- uses: actions/setup-python@v5
|
|
39
|
+
with:
|
|
40
|
+
python-version: "3.12"
|
|
41
|
+
- run: pip install -e ".[dev]"
|
|
42
|
+
- run: mypy src/
|
|
43
|
+
|
|
44
|
+
test:
|
|
45
|
+
runs-on: ubuntu-latest
|
|
46
|
+
strategy:
|
|
47
|
+
matrix:
|
|
48
|
+
python-version: ["3.12", "3.13"]
|
|
49
|
+
steps:
|
|
50
|
+
- uses: actions/checkout@v4
|
|
51
|
+
- uses: actions/setup-python@v5
|
|
52
|
+
with:
|
|
53
|
+
python-version: ${{ matrix.python-version }}
|
|
54
|
+
- run: pip install -e ".[dev]"
|
|
55
|
+
- run: pytest --cov=etcion --cov-report=term-missing --cov-fail-under=90
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
name: Release
|
|
2
|
+
|
|
3
|
+
on:
|
|
4
|
+
push:
|
|
5
|
+
tags: ["v*"]
|
|
6
|
+
|
|
7
|
+
permissions:
|
|
8
|
+
id-token: write
|
|
9
|
+
|
|
10
|
+
jobs:
|
|
11
|
+
build:
|
|
12
|
+
runs-on: ubuntu-latest
|
|
13
|
+
steps:
|
|
14
|
+
- uses: actions/checkout@v4
|
|
15
|
+
with:
|
|
16
|
+
fetch-depth: 0
|
|
17
|
+
- uses: actions/setup-python@v5
|
|
18
|
+
with:
|
|
19
|
+
python-version: "3.12"
|
|
20
|
+
- run: pip install build twine
|
|
21
|
+
- run: python -m build
|
|
22
|
+
- run: twine check dist/*
|
|
23
|
+
- uses: actions/upload-artifact@v4
|
|
24
|
+
with:
|
|
25
|
+
name: dist
|
|
26
|
+
path: dist/
|
|
27
|
+
|
|
28
|
+
publish:
|
|
29
|
+
needs: build
|
|
30
|
+
runs-on: ubuntu-latest
|
|
31
|
+
environment: pypi
|
|
32
|
+
permissions:
|
|
33
|
+
id-token: write
|
|
34
|
+
steps:
|
|
35
|
+
- uses: actions/download-artifact@v4
|
|
36
|
+
with:
|
|
37
|
+
name: dist
|
|
38
|
+
path: dist/
|
|
39
|
+
- uses: pypa/gh-action-pypi-publish@release/v1
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
All notable changes to this project will be documented in this file.
|
|
4
|
+
|
|
5
|
+
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
|
+
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
|
+
|
|
8
|
+
## [0.2.0] - 30 Mar 2026
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- **Pattern matching engine** -- define structural patterns with typed node
|
|
13
|
+
placeholders, relationship constraints, attribute filters (`.node(**kwargs)`),
|
|
14
|
+
lambda predicates (`.where()`), and cardinality constraints (`.min_edges()`,
|
|
15
|
+
`.max_edges()`). Find all matches (`pattern.match(model)`), check existence
|
|
16
|
+
(`pattern.exists(model)`), and identify gaps (`pattern.gaps(model, anchor=...)`).
|
|
17
|
+
- **Pattern composition** -- combine reusable pattern fragments via
|
|
18
|
+
`pattern_a.compose(pattern_b)`, with conflict detection on shared aliases.
|
|
19
|
+
- **Pattern serialization** -- `pattern.to_dict()` and `Pattern.from_dict(data)`
|
|
20
|
+
for JSON storage and sharing. Includes version field for forward compatibility.
|
|
21
|
+
- **Pattern validation rules** -- `PatternValidationRule` (pattern must exist),
|
|
22
|
+
`AntiPatternRule` (pattern must NOT exist), `RequiredPatternRule` (every
|
|
23
|
+
anchor-type element must participate). All integrate with `Model.validate()`.
|
|
24
|
+
- **Impact analysis (what-if modeling)** -- `analyze_impact()` computes the
|
|
25
|
+
blast radius of proposed changes: `remove`, `merge`, `replace`,
|
|
26
|
+
`add_relationship`, `remove_relationship`. Returns `ImpactResult` with
|
|
27
|
+
affected concepts (depth + path metadata), broken relationships, permission
|
|
28
|
+
violations, and an immutable result model.
|
|
29
|
+
- **Change chaining** -- `chain_impacts()` combines sequential operations with
|
|
30
|
+
ID-based deduplication. Feed `impact.resulting_model` into the next analysis
|
|
31
|
+
for multi-step migration planning.
|
|
32
|
+
- **Model querying** -- `elements_of_type()`, `elements_by_layer()`,
|
|
33
|
+
`elements_by_aspect()`, `elements_by_name()` (substring or regex),
|
|
34
|
+
`relationships_of_type()`, `connected_to()`, `sources_of()`, `targets_of()`.
|
|
35
|
+
- **networkx integration** -- `Model.to_networkx()` converts to a cached
|
|
36
|
+
`MultiDiGraph` with full element/relationship attributes. Optional dependency
|
|
37
|
+
via `pip install etcion[graph]`.
|
|
38
|
+
- **Viewpoint catalogue** -- 28 predefined standard viewpoints from the
|
|
39
|
+
ArchiMate specification, accessible via `VIEWPOINT_CATALOGUE["Organization"]`.
|
|
40
|
+
- **Model comparison** -- `diff_models()` with `ModelDiff`, `ConceptChange`,
|
|
41
|
+
`FieldChange` dataclasses. Supports `match_by="id"` and `match_by="type_name"`.
|
|
42
|
+
- **Plugin hooks** -- `register_element_type()`, `register_permission_rule()`,
|
|
43
|
+
`ValidationRule` protocol with `Model.add_validation_rule()`.
|
|
44
|
+
- **Permission cache warming** -- `warm_cache()` for deterministic startup
|
|
45
|
+
latency in performance-sensitive environments.
|
|
46
|
+
- **Performance benchmark suite** -- `test/benchmarks/` with import, construction,
|
|
47
|
+
validation, serialization, and memory benchmarks.
|
|
48
|
+
- **MkDocs documentation site** -- API reference (auto-generated), user guide,
|
|
49
|
+
architecture overview, ADR index, permission matrix.
|
|
50
|
+
- **CI/CD pipelines** -- GitHub Actions for lint, format, typecheck, test
|
|
51
|
+
(Python 3.12 + 3.13 matrix), and tag-triggered PyPI publishing.
|
|
52
|
+
- **Viewpoint-constrained patterns** -- optional `Pattern(viewpoint=vp)`
|
|
53
|
+
validates all node/edge types at construction time.
|
|
54
|
+
|
|
55
|
+
## [0.1.0] - 26 Mar 2026
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
|
|
59
|
+
- ArchiMate 3.2 metamodel: all element types across Business, Application,
|
|
60
|
+
Technology, Strategy, Motivation, Implementation & Migration, and Composite layers.
|
|
61
|
+
- Complete relationship type system with source/target validation matrix.
|
|
62
|
+
- Open Group Exchange Format XML serialization and deserialization.
|
|
63
|
+
- XSD validation against bundled ArchiMate 3.1 schemas.
|
|
64
|
+
- Conformance profiles (flag, standard, full).
|
|
65
|
+
- Opaque XML preservation for organizations and views during round-trip.
|
|
66
|
+
- Archi tool interoperability (import and export verified).
|
|
67
|
+
- PEP 561 `py.typed` marker for downstream type checking.
|
etcion-0.2.0/CLAUDE.md
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
# CLAUDE.md
|
|
2
|
+
|
|
3
|
+
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
|
4
|
+
|
|
5
|
+
## Project Overview
|
|
6
|
+
|
|
7
|
+
**etcion** is an early-stage Python library implementing the ArchiMate 3.2 metamodel.
|
|
8
|
+
|
|
9
|
+
- Python 3.12.3 via `.venv/`
|
|
10
|
+
- Source code goes in `src/etcion/`
|
|
11
|
+
- Tests go in `test/`
|
|
12
|
+
- Build system: `hatchling` via `pyproject.toml`
|
|
13
|
+
|
|
14
|
+
## Directory Layout
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
src/ # Main source code
|
|
18
|
+
test/ # Tests
|
|
19
|
+
etc/ # Configuration files
|
|
20
|
+
docs/ # Documentation
|
|
21
|
+
assets/ # Static assets / images
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
## Development Setup
|
|
25
|
+
|
|
26
|
+
Activate the virtual environment and install in editable mode with dev dependencies:
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
source .venv/bin/activate
|
|
30
|
+
pip install -e ".[dev]"
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
### Running Tests
|
|
34
|
+
|
|
35
|
+
```bash
|
|
36
|
+
pytest # Run all tests
|
|
37
|
+
pytest -x # Stop on first failure
|
|
38
|
+
pytest -m "not slow" # Skip slow tests
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
### Linting and Formatting
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
ruff check src/ test/ # Lint
|
|
45
|
+
ruff check src/ test/ --fix # Lint and auto-fix
|
|
46
|
+
ruff format src/ test/ # Format in place
|
|
47
|
+
ruff format --check src/ test/ # Check formatting without changing files
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
### Type Checking
|
|
51
|
+
|
|
52
|
+
```bash
|
|
53
|
+
mypy src/ # Type-check library source
|
|
54
|
+
mypy src/ test/ # Type-check library and tests
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
### Build
|
|
58
|
+
|
|
59
|
+
```bash
|
|
60
|
+
pip install -e ".[dev]" # Editable install with dev dependencies
|
|
61
|
+
pip install -e . # Editable install, runtime deps only
|
|
62
|
+
```
|
etcion-0.2.0/PKG-INFO
ADDED
|
@@ -0,0 +1,251 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: etcion
|
|
3
|
+
Version: 0.2.0
|
|
4
|
+
Summary: Architecture as code — build, query, validate, and analyze enterprise architecture models in Python
|
|
5
|
+
Project-URL: Homepage, https://github.com/korpodevs/etcion
|
|
6
|
+
Project-URL: Documentation, https://korpodevs.github.io/etcion/
|
|
7
|
+
Project-URL: Repository, https://github.com/korpodevs/etcion
|
|
8
|
+
Project-URL: Issues, https://github.com/korpodevs/etcion/issues
|
|
9
|
+
Project-URL: Changelog, https://github.com/korpodevs/etcion/blob/main/CHANGELOG.md
|
|
10
|
+
Author: etcion contributors
|
|
11
|
+
License-Expression: MIT
|
|
12
|
+
Keywords: archi,archimate,architecture-as-code,enterprise-architecture,metamodel,open-group
|
|
13
|
+
Classifier: Development Status :: 2 - Pre-Alpha
|
|
14
|
+
Classifier: Intended Audience :: Developers
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Classifier: Typing :: Typed
|
|
19
|
+
Requires-Python: >=3.12
|
|
20
|
+
Requires-Dist: pydantic<3.0,>=2.0
|
|
21
|
+
Provides-Extra: dev
|
|
22
|
+
Requires-Dist: build>=1.0; extra == 'dev'
|
|
23
|
+
Requires-Dist: lxml<6.0,>=5.0; extra == 'dev'
|
|
24
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
25
|
+
Requires-Dist: networkx<4.0,>=3.0; extra == 'dev'
|
|
26
|
+
Requires-Dist: pydantic<3.0,>=2.0; extra == 'dev'
|
|
27
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
30
|
+
Requires-Dist: twine>=5.0; extra == 'dev'
|
|
31
|
+
Provides-Extra: docs
|
|
32
|
+
Requires-Dist: mkdocs-material>=9.5; extra == 'docs'
|
|
33
|
+
Requires-Dist: mkdocs>=1.6; extra == 'docs'
|
|
34
|
+
Requires-Dist: mkdocstrings[python]>=0.25; extra == 'docs'
|
|
35
|
+
Provides-Extra: graph
|
|
36
|
+
Requires-Dist: networkx<4.0,>=3.0; extra == 'graph'
|
|
37
|
+
Provides-Extra: xml
|
|
38
|
+
Requires-Dist: lxml<6.0,>=5.0; extra == 'xml'
|
|
39
|
+
Description-Content-Type: text/markdown
|
|
40
|
+
|
|
41
|
+
# etcion
|
|
42
|
+
|
|
43
|
+
Architecture as code. Build, query, validate, and analyze enterprise architecture models in Python.
|
|
44
|
+
|
|
45
|
+
## Why etcion?
|
|
46
|
+
|
|
47
|
+
Enterprise architecture models are rich data structures — typed elements, directed relationships, cross-layer dependencies, governance rules. But most EA tooling treats them as static diagrams locked inside proprietary formats.
|
|
48
|
+
|
|
49
|
+
**etcion** turns your architecture into a first-class Python data structure. Once it's code, you can query it, validate it against rules, test what-if scenarios, diff versions, and integrate it with the rest of your analytical toolkit — pandas, networkx, Jupyter notebooks, CI/CD pipelines, or anything else Python touches.
|
|
50
|
+
|
|
51
|
+
Built on the [ArchiMate 3.2](https://pubs.opengroup.org/architecture/archimate32-doc/) metamodel. Compatible with [Archi](https://www.archimatetool.com/) via the Open Group Exchange Format.
|
|
52
|
+
|
|
53
|
+
## What you can do
|
|
54
|
+
|
|
55
|
+
**Build models programmatically**
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
from etcion import (
|
|
59
|
+
BusinessProcess, ApplicationService, ApplicationComponent,
|
|
60
|
+
Model, Serving, Assignment,
|
|
61
|
+
)
|
|
62
|
+
|
|
63
|
+
order_handling = BusinessProcess(name="Order Handling")
|
|
64
|
+
api = ApplicationService(name="Order API")
|
|
65
|
+
backend = ApplicationComponent(name="Order Service")
|
|
66
|
+
|
|
67
|
+
model = Model(concepts=[
|
|
68
|
+
order_handling, api, backend,
|
|
69
|
+
Serving(name="serves", source=api, target=order_handling),
|
|
70
|
+
Assignment(name="runs", source=backend, target=api),
|
|
71
|
+
])
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
**Query the model graph**
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
model.elements_by_layer(Layer.BUSINESS)
|
|
78
|
+
model.elements_by_name("Order", regex=False)
|
|
79
|
+
model.connected_to(backend)
|
|
80
|
+
model.sources_of(order_handling)
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
**Detect structural patterns**
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
from etcion.patterns import Pattern, RequiredPatternRule
|
|
87
|
+
|
|
88
|
+
# Every BusinessService must be backed by an ApplicationService
|
|
89
|
+
service_backing = (
|
|
90
|
+
Pattern()
|
|
91
|
+
.node("biz", BusinessService)
|
|
92
|
+
.node("app", ApplicationService)
|
|
93
|
+
.edge("app", "biz", Serving)
|
|
94
|
+
)
|
|
95
|
+
|
|
96
|
+
# Find services missing their backing
|
|
97
|
+
gaps = service_backing.gaps(model, anchor="biz")
|
|
98
|
+
|
|
99
|
+
# Enforce as a validation rule
|
|
100
|
+
model.add_validation_rule(RequiredPatternRule(
|
|
101
|
+
pattern=service_backing,
|
|
102
|
+
anchor="biz",
|
|
103
|
+
description="Every BusinessService must be served by an ApplicationService",
|
|
104
|
+
))
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
**Detect anti-patterns**
|
|
108
|
+
|
|
109
|
+
```python
|
|
110
|
+
from etcion.patterns import AntiPatternRule
|
|
111
|
+
|
|
112
|
+
# Technology should not directly serve Business (must go through Application)
|
|
113
|
+
bad_pattern = (
|
|
114
|
+
Pattern()
|
|
115
|
+
.node("tech", TechnologyService)
|
|
116
|
+
.node("biz", BusinessProcess)
|
|
117
|
+
.edge("tech", "biz", Serving)
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
model.add_validation_rule(AntiPatternRule(
|
|
121
|
+
pattern=bad_pattern,
|
|
122
|
+
description="Technology must not directly serve Business layer",
|
|
123
|
+
))
|
|
124
|
+
```
|
|
125
|
+
|
|
126
|
+
**Model what-if scenarios**
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
from etcion import analyze_impact, chain_impacts
|
|
130
|
+
|
|
131
|
+
# What breaks if we decommission the legacy CRM?
|
|
132
|
+
impact = analyze_impact(model, remove=legacy_crm, max_depth=3)
|
|
133
|
+
for item in impact.affected:
|
|
134
|
+
print(f" depth={item.depth} {item.concept.name}")
|
|
135
|
+
print(f"Broken relationships: {len(impact.broken_relationships)}")
|
|
136
|
+
|
|
137
|
+
# What happens if we consolidate three systems onto one platform?
|
|
138
|
+
impact = analyze_impact(model, merge=([sys_a, sys_b, sys_c], target_platform))
|
|
139
|
+
print(f"Permission violations: {len(impact.violations)}")
|
|
140
|
+
|
|
141
|
+
# Chain multiple changes and validate the result
|
|
142
|
+
i1 = analyze_impact(model, remove=old_system)
|
|
143
|
+
i2 = analyze_impact(i1.resulting_model, replace=(legacy_db, cloud_db))
|
|
144
|
+
errors = i2.resulting_model.validate()
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
**Validate against the spec**
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
errors = model.validate() # Collect all errors
|
|
151
|
+
model.validate(strict=True) # Raise on first error
|
|
152
|
+
|
|
153
|
+
from etcion import is_permitted, Serving, ApplicationService, BusinessProcess
|
|
154
|
+
is_permitted(Serving, ApplicationService, BusinessProcess) # True
|
|
155
|
+
```
|
|
156
|
+
|
|
157
|
+
**Exchange with Archi and other tools**
|
|
158
|
+
|
|
159
|
+
```python
|
|
160
|
+
from etcion.serialization.xml import write_model, read_model
|
|
161
|
+
|
|
162
|
+
write_model(model, "architecture.xml", model_name="My Architecture")
|
|
163
|
+
loaded = read_model("exported_from_archi.xml")
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
**Compare model versions**
|
|
167
|
+
|
|
168
|
+
```python
|
|
169
|
+
from etcion import diff_models
|
|
170
|
+
|
|
171
|
+
diff = diff_models(baseline_model, proposed_model)
|
|
172
|
+
print(diff.summary()) # "ModelDiff: 3 added, 1 removed, 2 modified"
|
|
173
|
+
```
|
|
174
|
+
|
|
175
|
+
## Installation
|
|
176
|
+
|
|
177
|
+
```bash
|
|
178
|
+
pip install etcion # Core library
|
|
179
|
+
pip install etcion[xml] # + XML serialization (lxml)
|
|
180
|
+
pip install etcion[graph] # + Pattern matching & impact analysis (networkx)
|
|
181
|
+
pip install etcion[xml,graph] # Both
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
Requires Python 3.12 or later.
|
|
185
|
+
|
|
186
|
+
## ArchiMate Coverage
|
|
187
|
+
|
|
188
|
+
58 concrete element types across all 7 layers, 11 relationship types, Junction, and 28 predefined viewpoints.
|
|
189
|
+
|
|
190
|
+
| Layer | Elements |
|
|
191
|
+
|-------|----------|
|
|
192
|
+
| Strategy | Resource, Capability, ValueStream, CourseOfAction |
|
|
193
|
+
| Business | BusinessActor, BusinessRole, BusinessCollaboration, BusinessInterface, BusinessProcess, BusinessFunction, BusinessInteraction, BusinessEvent, BusinessService, BusinessObject, Contract, Representation, Product |
|
|
194
|
+
| Application | ApplicationComponent, ApplicationCollaboration, ApplicationInterface, ApplicationFunction, ApplicationInteraction, ApplicationProcess, ApplicationEvent, ApplicationService, DataObject |
|
|
195
|
+
| Technology | Node, Device, SystemSoftware, TechnologyCollaboration, TechnologyInterface, Path, CommunicationNetwork, TechnologyFunction, TechnologyProcess, TechnologyInteraction, TechnologyEvent, TechnologyService, Artifact |
|
|
196
|
+
| Physical | Equipment, Facility, DistributionNetwork, Material |
|
|
197
|
+
| Motivation | Stakeholder, Driver, Assessment, Goal, Outcome, Principle, Requirement, Constraint, Meaning, Value |
|
|
198
|
+
| Implementation & Migration | WorkPackage, Deliverable, ImplementationEvent, Plateau, Gap |
|
|
199
|
+
|
|
200
|
+
## Archi Compatibility
|
|
201
|
+
|
|
202
|
+
etcion reads and writes the Open Group ArchiMate Exchange Format, verified against [Archi](https://www.archimatetool.com/).
|
|
203
|
+
|
|
204
|
+
**Import into Archi:** `File > Import > Open Exchange XML Model`
|
|
205
|
+
**Export from Archi:** `File > Export > Open Exchange XML Model`
|
|
206
|
+
|
|
207
|
+
Diagram layouts, folder organization, and visual styles survive round-trip as opaque XML.
|
|
208
|
+
|
|
209
|
+
## Extending
|
|
210
|
+
|
|
211
|
+
```python
|
|
212
|
+
# Custom validation rules
|
|
213
|
+
from etcion.validation.rules import ValidationRule
|
|
214
|
+
|
|
215
|
+
class RequireDocumentation:
|
|
216
|
+
def validate(self, model):
|
|
217
|
+
from etcion.exceptions import ValidationError
|
|
218
|
+
return [
|
|
219
|
+
ValidationError(f"'{e.name}' has no documentation")
|
|
220
|
+
for e in model.elements if not e.description
|
|
221
|
+
]
|
|
222
|
+
|
|
223
|
+
model.add_validation_rule(RequireDocumentation())
|
|
224
|
+
|
|
225
|
+
# Language customization via profiles
|
|
226
|
+
from etcion.metamodel.profiles import Profile
|
|
227
|
+
|
|
228
|
+
cloud_profile = Profile(
|
|
229
|
+
name="Cloud",
|
|
230
|
+
specializations={ApplicationComponent: ["Microservice", "Lambda", "Container"]},
|
|
231
|
+
)
|
|
232
|
+
model.apply_profile(cloud_profile)
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
## Development
|
|
236
|
+
|
|
237
|
+
```bash
|
|
238
|
+
git clone https://github.com/korpodevs/etcion.git
|
|
239
|
+
cd etcion
|
|
240
|
+
python -m venv .venv
|
|
241
|
+
source .venv/bin/activate
|
|
242
|
+
pip install -e ".[dev]"
|
|
243
|
+
pytest # 2685 tests
|
|
244
|
+
ruff check src/ test/ # Lint
|
|
245
|
+
mypy src/ # Type check
|
|
246
|
+
mkdocs serve # Local docs
|
|
247
|
+
```
|
|
248
|
+
|
|
249
|
+
## License
|
|
250
|
+
|
|
251
|
+
MIT
|