archunitpython 1.1.1__tar.gz → 1.1.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.
Files changed (132) hide show
  1. archunitpython-1.1.2/.github/CODEOWNERS +1 -0
  2. {archunitpython-1.1.1 → archunitpython-1.1.2}/.github/workflows/integrate.yaml +5 -1
  3. {archunitpython-1.1.1 → archunitpython-1.1.2}/.releaserc.json +1 -1
  4. {archunitpython-1.1.1 → archunitpython-1.1.2}/BACKLOG.md +4 -4
  5. {archunitpython-1.1.1 → archunitpython-1.1.2}/CHANGELOG.md +8 -0
  6. {archunitpython-1.1.1 → archunitpython-1.1.2}/PKG-INFO +8 -2
  7. {archunitpython-1.1.1 → archunitpython-1.1.2}/README.md +6 -1
  8. {archunitpython-1.1.1 → archunitpython-1.1.2}/pyproject.toml +2 -1
  9. archunitpython-1.1.2/scripts/bump_release_version.py +50 -0
  10. archunitpython-1.1.2/scripts/check_release_metadata.py +72 -0
  11. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/__init__.py +1 -1
  12. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/extraction/extract_graph.py +3 -1
  13. {archunitpython-1.1.1 → archunitpython-1.1.2}/.editorconfig +0 -0
  14. {archunitpython-1.1.1 → archunitpython-1.1.2}/.gitattributes +0 -0
  15. {archunitpython-1.1.1 → archunitpython-1.1.2}/.github/ISSUE_TEMPLATE/bug_report.md +0 -0
  16. {archunitpython-1.1.1 → archunitpython-1.1.2}/.github/ISSUE_TEMPLATE/documentation.md +0 -0
  17. {archunitpython-1.1.1 → archunitpython-1.1.2}/.github/ISSUE_TEMPLATE/feature_request.md +0 -0
  18. {archunitpython-1.1.1 → archunitpython-1.1.2}/.github/ISSUE_TEMPLATE/question.md +0 -0
  19. {archunitpython-1.1.1 → archunitpython-1.1.2}/.github/PAGES.md +0 -0
  20. {archunitpython-1.1.1 → archunitpython-1.1.2}/.github/dependabot.yml +0 -0
  21. {archunitpython-1.1.1 → archunitpython-1.1.2}/.github/pull_request_template.md +0 -0
  22. {archunitpython-1.1.1 → archunitpython-1.1.2}/.github/workflows/docs.yaml +0 -0
  23. {archunitpython-1.1.1 → archunitpython-1.1.2}/.github/workflows/stale.yaml +0 -0
  24. {archunitpython-1.1.1 → archunitpython-1.1.2}/.gitignore +0 -0
  25. {archunitpython-1.1.1 → archunitpython-1.1.2}/CONTRIBUTING.md +0 -0
  26. {archunitpython-1.1.1 → archunitpython-1.1.2}/LICENSE +0 -0
  27. {archunitpython-1.1.1 → archunitpython-1.1.2}/assets/logo-rounded.png +0 -0
  28. {archunitpython-1.1.1 → archunitpython-1.1.2}/research/product-direction/architecture-testing-landscape.md +0 -0
  29. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/__init__.py +0 -0
  30. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/assertion/__init__.py +0 -0
  31. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/assertion/violation.py +0 -0
  32. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/error/__init__.py +0 -0
  33. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/error/errors.py +0 -0
  34. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/extraction/__init__.py +0 -0
  35. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/extraction/graph.py +0 -0
  36. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/fluentapi/__init__.py +0 -0
  37. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/fluentapi/checkable.py +0 -0
  38. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/logging/__init__.py +0 -0
  39. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/logging/types.py +0 -0
  40. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/pattern_matching.py +0 -0
  41. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/projection/__init__.py +0 -0
  42. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/projection/cycles/__init__.py +0 -0
  43. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/projection/cycles/cycle_utils.py +0 -0
  44. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/projection/cycles/cycles.py +0 -0
  45. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/projection/cycles/johnsons_apsp.py +0 -0
  46. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/projection/cycles/model.py +0 -0
  47. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/projection/cycles/tarjan_scc.py +0 -0
  48. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/projection/edge_projections.py +0 -0
  49. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/projection/project_cycles.py +0 -0
  50. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/projection/project_edges.py +0 -0
  51. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/projection/project_nodes.py +0 -0
  52. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/projection/types.py +0 -0
  53. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/regex_factory.py +0 -0
  54. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/types.py +0 -0
  55. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/util/__init__.py +0 -0
  56. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/util/declaration_detector.py +0 -0
  57. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/common/util/logger.py +0 -0
  58. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/files/__init__.py +0 -0
  59. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/files/assertion/__init__.py +0 -0
  60. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/files/assertion/custom_file_logic.py +0 -0
  61. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/files/assertion/cycle_free.py +0 -0
  62. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/files/assertion/depend_on_external_modules.py +0 -0
  63. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/files/assertion/depend_on_files.py +0 -0
  64. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/files/assertion/matching_files.py +0 -0
  65. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/files/fluentapi/__init__.py +0 -0
  66. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/files/fluentapi/files.py +0 -0
  67. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/__init__.py +0 -0
  68. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/assertion/__init__.py +0 -0
  69. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/assertion/metric_thresholds.py +0 -0
  70. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/calculation/__init__.py +0 -0
  71. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/calculation/count.py +0 -0
  72. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/calculation/distance.py +0 -0
  73. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/calculation/lcom.py +0 -0
  74. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/common/__init__.py +0 -0
  75. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/common/types.py +0 -0
  76. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/extraction/__init__.py +0 -0
  77. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/extraction/extract_class_info.py +0 -0
  78. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/fluentapi/__init__.py +0 -0
  79. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/fluentapi/export_utils.py +0 -0
  80. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/fluentapi/metrics.py +0 -0
  81. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/metrics/projection/__init__.py +0 -0
  82. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/py.typed +0 -0
  83. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/slices/__init__.py +0 -0
  84. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/slices/assertion/__init__.py +0 -0
  85. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/slices/assertion/admissible_edges.py +0 -0
  86. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/slices/fluentapi/__init__.py +0 -0
  87. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/slices/fluentapi/slices.py +0 -0
  88. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/slices/projection/__init__.py +0 -0
  89. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/slices/projection/slicing_projections.py +0 -0
  90. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/slices/uml/__init__.py +0 -0
  91. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/slices/uml/export_diagram.py +0 -0
  92. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/slices/uml/generate_rules.py +0 -0
  93. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/testing/__init__.py +0 -0
  94. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/testing/assertion.py +0 -0
  95. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/testing/common/__init__.py +0 -0
  96. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/testing/common/color_utils.py +0 -0
  97. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/testing/common/violation_factory.py +0 -0
  98. {archunitpython-1.1.1 → archunitpython-1.1.2}/src/archunitpython/testing/pytest_plugin/__init__.py +0 -0
  99. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/__init__.py +0 -0
  100. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/common/__init__.py +0 -0
  101. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/common/test_core_types.py +0 -0
  102. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/common/test_cycles.py +0 -0
  103. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/common/test_declaration_detector.py +0 -0
  104. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/common/test_extract_graph.py +0 -0
  105. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/common/test_logger.py +0 -0
  106. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/common/test_pattern_matching.py +0 -0
  107. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/common/test_projection.py +0 -0
  108. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/files/__init__.py +0 -0
  109. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/files/test_file_assertions.py +0 -0
  110. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/files/test_files_fluentapi.py +0 -0
  111. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/fixtures/metrics_project/service.py +0 -0
  112. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/fixtures/sample_project/__init__.py +0 -0
  113. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/fixtures/sample_project/architecture.puml +0 -0
  114. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/fixtures/sample_project/controllers/__init__.py +0 -0
  115. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/fixtures/sample_project/controllers/controller.py +0 -0
  116. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/fixtures/sample_project/models/__init__.py +0 -0
  117. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/fixtures/sample_project/models/model.py +0 -0
  118. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/fixtures/sample_project/services/__init__.py +0 -0
  119. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/fixtures/sample_project/services/service.py +0 -0
  120. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/fixtures/sample_project/services/service_a.py +0 -0
  121. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/fixtures/sample_project/services/service_b.py +0 -0
  122. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/fixtures/sample_project/utils/__init__.py +0 -0
  123. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/fixtures/sample_project/utils/helpers.py +0 -0
  124. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/integration/__init__.py +0 -0
  125. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/integration/test_e2e.py +0 -0
  126. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/metrics/__init__.py +0 -0
  127. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/metrics/test_export.py +0 -0
  128. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/metrics/test_metrics.py +0 -0
  129. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/metrics/test_metrics_fluentapi.py +0 -0
  130. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/slices/__init__.py +0 -0
  131. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/slices/test_slices.py +0 -0
  132. {archunitpython-1.1.1 → archunitpython-1.1.2}/tests/test_setup.py +0 -0
@@ -0,0 +1 @@
1
+ * @LukasNiessen
@@ -26,12 +26,16 @@ jobs:
26
26
  pip-${{ runner.os }}-${{ matrix.python-version }}-
27
27
  - name: Install dependencies
28
28
  run: pip install -e ".[dev]"
29
+ - name: Check release metadata
30
+ run: python scripts/check_release_metadata.py
29
31
  - name: Lint
30
- run: ruff check src/
32
+ run: ruff check src/ scripts/
31
33
  - name: Type check
32
34
  run: mypy src/archunitpython/ --ignore-missing-imports
33
35
  - name: Test
34
36
  run: pytest --tb=short -q
37
+ - name: Build package
38
+ run: python -m build
35
39
 
36
40
  publish:
37
41
  if: github.ref == 'refs/heads/main' && github.event_name == 'push'
@@ -12,7 +12,7 @@
12
12
  [
13
13
  "@semantic-release/exec",
14
14
  {
15
- "prepareCmd": "python -c \"import re, pathlib; files=[('pyproject.toml', r'(?m)^version = \\\"[^\\\"]+\\\"$', 'version = \\\"${nextRelease.version}\\\"'), ('src/archunitpython/__init__.py', r'(?m)^__version__ = \\\"[^\\\"]+\\\"$', '__version__ = \\\"${nextRelease.version}\\\"')]; [pathlib.Path(path).write_text(re.sub(pattern, replacement, pathlib.Path(path).read_text())) for path, pattern, replacement in files]\""
15
+ "prepareCmd": "python scripts/bump_release_version.py ${nextRelease.version}"
16
16
  }
17
17
  ],
18
18
  [
@@ -4,10 +4,10 @@ This backlog collects product and maintenance ideas from project research.
4
4
 
5
5
  ## P0 - Maintenance And Correctness
6
6
 
7
- - Keep package metadata synchronized across `pyproject.toml`, `CHANGELOG.md`, and `src/archunitpython/__init__.py`.
8
- - Keep tool configuration valid for the supported Python range, especially mypy and Ruff target versions.
9
- - Add a release metadata check that fails when the exported `__version__` differs from the project version.
10
- - Add CI jobs that run tests, Ruff, mypy, and a package build from a clean checkout.
7
+ - [x] Keep package metadata synchronized across `pyproject.toml`, `CHANGELOG.md`, and `src/archunitpython/__init__.py`.
8
+ - [x] Keep tool configuration valid for the supported Python range, especially mypy and Ruff target versions.
9
+ - [x] Add a release metadata check that fails when the exported `__version__` differs from the project version.
10
+ - [x] Add CI jobs that run tests, Ruff, mypy, and a package build from a clean checkout.
11
11
 
12
12
  ## P1 - Adoption Workflow
13
13
 
@@ -1,3 +1,11 @@
1
+ ## [1.1.2](https://github.com/LukasNiessen/ArchUnitPython/compare/v1.1.1...v1.1.2) (2026-06-23)
2
+
3
+
4
+ ### Bug Fixes
5
+
6
+ * fixed the duplicate key issue ([283e8e3](https://github.com/LukasNiessen/ArchUnitPython/commit/283e8e3aa959d235f331912e33a72bdbd62f3d31))
7
+ * wrap long line in extract_graph to pass ruff E501 ([f291181](https://github.com/LukasNiessen/ArchUnitPython/commit/f291181336bacdd7a913187d2d26f1125f1b2a11))
8
+
1
9
  ## [1.1.1](https://github.com/LukasNiessen/ArchUnitPython/compare/v1.1.0...v1.1.1) (2026-05-24)
2
10
 
3
11
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: archunitpython
3
- Version: 1.1.1
3
+ Version: 1.1.2
4
4
  Summary: Architecture testing library for Python projects. Enforce dependency rules, detect cycles, validate metrics.
5
5
  Project-URL: Homepage, https://github.com/LukasNiessen/ArchUnitPython
6
6
  Project-URL: Repository, https://github.com/LukasNiessen/ArchUnitPython.git
@@ -24,6 +24,7 @@ Classifier: Topic :: Software Development :: Testing
24
24
  Classifier: Typing :: Typed
25
25
  Requires-Python: >=3.10
26
26
  Provides-Extra: dev
27
+ Requires-Dist: build>=1.0; extra == 'dev'
27
28
  Requires-Dist: mypy>=1.0; extra == 'dev'
28
29
  Requires-Dist: pytest-cov>=4.0; extra == 'dev'
29
30
  Requires-Dist: pytest>=7.0; extra == 'dev'
@@ -599,7 +600,12 @@ We use ourselves to ensure the architectural rules for this repository.
599
600
 
600
601
  ## 🦊 Contributing
601
602
 
602
- We highly appreciate contributions. We use GitHub Flow, meaning that we use feature branches. As soon as something is merged or pushed to `main` it gets deployed. Versioning is automated via [Conventional Commits](https://www.conventionalcommits.org/). See more in [Contributing](CONTRIBUTING.md).
603
+ We highly appreciate contributions. See [Contributing](CONTRIBUTING.md) for the full workflow.
604
+
605
+ - Use feature branches and open pull requests against `main`.
606
+ - Use [Conventional Commits](https://www.conventionalcommits.org/) so releases can be versioned automatically.
607
+ - Do not bump versions manually for normal feature or fix work; semantic-release updates `pyproject.toml`, `src/archunitpython/__init__.py`, and `CHANGELOG.md`.
608
+ - CI checks linting, typing, tests, package builds, and release metadata sync.
603
609
 
604
610
  ## ℹ️ FAQ
605
611
 
@@ -567,7 +567,12 @@ We use ourselves to ensure the architectural rules for this repository.
567
567
 
568
568
  ## 🦊 Contributing
569
569
 
570
- We highly appreciate contributions. We use GitHub Flow, meaning that we use feature branches. As soon as something is merged or pushed to `main` it gets deployed. Versioning is automated via [Conventional Commits](https://www.conventionalcommits.org/). See more in [Contributing](CONTRIBUTING.md).
570
+ We highly appreciate contributions. See [Contributing](CONTRIBUTING.md) for the full workflow.
571
+
572
+ - Use feature branches and open pull requests against `main`.
573
+ - Use [Conventional Commits](https://www.conventionalcommits.org/) so releases can be versioned automatically.
574
+ - Do not bump versions manually for normal feature or fix work; semantic-release updates `pyproject.toml`, `src/archunitpython/__init__.py`, and `CHANGELOG.md`.
575
+ - CI checks linting, typing, tests, package builds, and release metadata sync.
571
576
 
572
577
  ## ℹ️ FAQ
573
578
 
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "archunitpython"
7
- version = "1.1.1"
7
+ version = "1.1.2"
8
8
  description = "Architecture testing library for Python projects. Enforce dependency rules, detect cycles, validate metrics."
9
9
  readme = "README.md"
10
10
  license = "MIT"
@@ -54,6 +54,7 @@ Changelog = "https://github.com/LukasNiessen/ArchUnitPython/blob/main/CHANGELOG.
54
54
 
55
55
  [project.optional-dependencies]
56
56
  dev = [
57
+ "build>=1.0",
57
58
  "pytest>=7.0",
58
59
  "pytest-cov>=4.0",
59
60
  "mypy>=1.0",
@@ -0,0 +1,50 @@
1
+ """Synchronize release version metadata for semantic-release."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import re
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ ROOT = Path(__file__).resolve().parents[1]
10
+ PYPROJECT = ROOT / "pyproject.toml"
11
+ PACKAGE_INIT = ROOT / "src" / "archunitpython" / "__init__.py"
12
+
13
+
14
+ def replace_once(pattern: str, replacement: str, content: str, path: Path) -> str:
15
+ updated, count = re.subn(pattern, replacement, content, count=1, flags=re.MULTILINE)
16
+ if count != 1:
17
+ raise RuntimeError(f"Could not update version in {path}")
18
+ return updated
19
+
20
+
21
+ def bump_version(version: str) -> None:
22
+ pyproject = PYPROJECT.read_text(encoding="utf-8")
23
+ PYPROJECT.write_text(
24
+ replace_once(r'^version = "[^"]+"$', f'version = "{version}"', pyproject, PYPROJECT),
25
+ encoding="utf-8",
26
+ )
27
+
28
+ package_init = PACKAGE_INIT.read_text(encoding="utf-8")
29
+ PACKAGE_INIT.write_text(
30
+ replace_once(
31
+ r'^__version__ = "[^"]+"$',
32
+ f'__version__ = "{version}"',
33
+ package_init,
34
+ PACKAGE_INIT,
35
+ ),
36
+ encoding="utf-8",
37
+ )
38
+
39
+
40
+ def main() -> int:
41
+ if len(sys.argv) != 2:
42
+ print("Usage: python scripts/bump_release_version.py <version>", file=sys.stderr)
43
+ return 2
44
+
45
+ bump_version(sys.argv[1])
46
+ return 0
47
+
48
+
49
+ if __name__ == "__main__":
50
+ raise SystemExit(main())
@@ -0,0 +1,72 @@
1
+ """Check that release metadata stays synchronized."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import ast
6
+ import re
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ ROOT = Path(__file__).resolve().parents[1]
11
+ PYPROJECT = ROOT / "pyproject.toml"
12
+ PACKAGE_INIT = ROOT / "src" / "archunitpython" / "__init__.py"
13
+ CHANGELOG = ROOT / "CHANGELOG.md"
14
+
15
+
16
+ def read_project_version() -> str:
17
+ content = PYPROJECT.read_text(encoding="utf-8")
18
+ match = re.search(r'^version = "([^"]+)"$', content, re.MULTILINE)
19
+ if match is None:
20
+ raise RuntimeError("Could not find project.version in pyproject.toml")
21
+ return match.group(1)
22
+
23
+
24
+ def read_package_version() -> str:
25
+ module = ast.parse(PACKAGE_INIT.read_text(encoding="utf-8"))
26
+ for statement in module.body:
27
+ if (
28
+ isinstance(statement, ast.Assign)
29
+ and len(statement.targets) == 1
30
+ and isinstance(statement.targets[0], ast.Name)
31
+ and statement.targets[0].id == "__version__"
32
+ and isinstance(statement.value, ast.Constant)
33
+ and isinstance(statement.value.value, str)
34
+ ):
35
+ return statement.value.value
36
+ raise RuntimeError("Could not find __version__ in src/archunitpython/__init__.py")
37
+
38
+
39
+ def changelog_contains_version(version: str) -> bool:
40
+ content = CHANGELOG.read_text(encoding="utf-8")
41
+ heading_pattern = re.compile(
42
+ rf"^#+\s+(?:\[)?{re.escape(version)}(?:\])?(?:\s|\(|$)",
43
+ re.MULTILINE,
44
+ )
45
+ return heading_pattern.search(content) is not None
46
+
47
+
48
+ def main() -> int:
49
+ project_version = read_project_version()
50
+ package_version = read_package_version()
51
+
52
+ errors = []
53
+ if package_version != project_version:
54
+ errors.append(
55
+ f"Package __version__ ({package_version}) does not match "
56
+ f"pyproject.toml version ({project_version})."
57
+ )
58
+ if not changelog_contains_version(project_version):
59
+ errors.append(f"CHANGELOG.md does not contain a heading for version {project_version}.")
60
+
61
+ if errors:
62
+ print("Release metadata check failed:", file=sys.stderr)
63
+ for error in errors:
64
+ print(f"- {error}", file=sys.stderr)
65
+ return 1
66
+
67
+ print(f"Release metadata is synchronized for version {project_version}.")
68
+ return 0
69
+
70
+
71
+ if __name__ == "__main__":
72
+ raise SystemExit(main())
@@ -1,6 +1,6 @@
1
1
  """ArchUnitPython - Architecture testing library for Python projects."""
2
2
 
3
- __version__ = "1.1.1"
3
+ __version__ = "1.1.2"
4
4
 
5
5
  # Files API
6
6
  # Common
@@ -58,7 +58,9 @@ def extract_graph(
58
58
  project_path = os.getcwd()
59
59
 
60
60
  project_path = os.path.abspath(project_path)
61
- excludes = list(exclude_patterns) if exclude_patterns is not None else list(_DEFAULT_EXCLUDE)
61
+ excludes = (
62
+ list(set(exclude_patterns)) if exclude_patterns is not None else list(_DEFAULT_EXCLUDE)
63
+ )
62
64
  ignore_type_checking_imports = bool(
63
65
  options and options.ignore_type_checking_imports
64
66
  )
File without changes