|
4 | 4 |
|
5 | 5 | <p align="center"> |
6 | 6 | <a href="LICENSE"><img src="https://img.shields.io/badge/license-MIT-blue.svg" alt="License: MIT"></a> |
7 | | - <a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.10+-blue.svg" alt="Python 3.10+"></a> |
8 | | - <a href="https://www.python.org/"><img src="https://img.shields.io/badge/status-alpha%200.0.1a2-orange.svg" alt="Status Alpha"></a> |
| 7 | + <a href="https://www.python.org/"><img src="https://img.shields.io/badge/python-3.12+-blue.svg" alt="Python 3.12+"></a> |
| 8 | + <a href="https://github.com/mspitb/pyarchrules"><img src="https://img.shields.io/badge/status-beta%200.1.0b0-orange.svg" alt="Status: Beta"></a> |
9 | 9 | </p> |
10 | 10 |
|
| 11 | +**PyArchRules** enforces architecture rules in Python projects: |
11 | 12 |
|
12 | | -## Features |
13 | | - |
14 | | -- 🏗️ **Structure validation** - enforce directory tree requirements |
15 | | -- 🔗 **Dependency rules** - control module imports (e.g., `api -> domain`) |
16 | | -- 🎯 **DSL & Config** - use Python DSL or TOML configuration |
17 | | -- 🚀 **Zero setup** - works with `pyproject.toml` |
18 | | -- 🔍 **CLI & API** - integrate into CI/CD or use programmatically |
| 13 | +- 🏗️ **Folder structure** — require exact directory layouts per service |
| 14 | +- 🔗 **Dependency rules** — control which internal packages may import from which |
| 15 | +- 🛡️ **Service isolation** — prevent cross-service imports in monorepos |
| 16 | +- 🐍 **Python DSL** — write rules in Python inside your test suite |
| 17 | +- ⚙️ **Zero extra config** — everything lives in `pyproject.toml` |
| 18 | +- 🚀 **CI-ready** — exit code `1` on any violation |
19 | 19 |
|
20 | 20 | ## Installation |
21 | 21 |
|
22 | 22 | ```bash |
23 | 23 | pip install pyarchrules |
24 | 24 | ``` |
25 | 25 |
|
26 | | -## Quick Start |
| 26 | +## Quick start |
27 | 27 |
|
28 | 28 | ```bash |
29 | | -# Initialize |
| 29 | +# 1. Add [tool.pyarchrules] to pyproject.toml |
30 | 30 | pyarchrules init-project |
31 | 31 |
|
32 | | -# Check architecture |
| 32 | +# 2. Register a service |
| 33 | +pyarchrules add-service backend src/backend |
| 34 | + |
| 35 | +# 3. Run the check |
33 | 36 | pyarchrules check |
34 | 37 | ``` |
35 | 38 |
|
36 | | -## Configuration Example |
| 39 | +## TOML configuration |
37 | 40 |
|
38 | 41 | ```toml |
39 | 42 | [tool.pyarchrules] |
40 | | -project_name = "myapp" |
| 43 | +project_name = "myapp" |
| 44 | +description = "Architecture rules for this project" |
| 45 | +root = "." |
| 46 | +validate_paths = true |
| 47 | +isolate_services = true |
41 | 48 |
|
42 | 49 | [tool.pyarchrules.services.backend] |
43 | | -path = "src/backend" |
44 | | - |
45 | | -# Enforce directory structure |
46 | | -tree = ["api", "domain", "infra"] |
47 | | -tree_strict = true |
48 | | - |
49 | | -# Control dependencies (api can import from domain) |
50 | | -dependencies = ["api -> domain", "domain -> infra"] |
| 50 | +path = "src/backend" |
| 51 | +tree = ["api", "domain", "infra"] |
| 52 | +tree_strict = true |
| 53 | +dependencies = ["api -> domain", "domain -> infra", "* -> utils"] |
51 | 54 | ``` |
52 | 55 |
|
53 | | -## Python API |
| 56 | +## Python DSL |
54 | 57 |
|
55 | 58 | ```python |
| 59 | +# tests/test_architecture.py |
56 | 60 | from pyarchrules import PyArchRules |
57 | 61 |
|
58 | | -rules = PyArchRules() |
59 | | - |
60 | | -# DSL validation |
61 | | -rules.for_service("backend") \ |
62 | | - .must_contain_folders(["api", "domain"]) |
63 | | - |
64 | | -result = rules.validate() |
| 62 | +def test_architecture(): |
| 63 | + rules = PyArchRules() |
| 64 | + rules.for_service("backend") \ |
| 65 | + .must_contain_folders(["api", "domain", "infra"], allow_extra=False) \ |
| 66 | + .no_wildcard_imports() \ |
| 67 | + .no_circular_imports() |
| 68 | + rules.validate() |
65 | 69 | ``` |
66 | 70 |
|
67 | | -## CLI Commands |
| 71 | +## CLI commands |
68 | 72 |
|
69 | 73 | | Command | Description | |
70 | 74 | |---------|-------------| |
71 | | -| `pyarchrules init-project` | Initialize configuration | |
72 | | -| `pyarchrules check` | Validate architecture | |
73 | | -| `pyarchrules add-service NAME PATH` | Add service | |
74 | | -| `pyarchrules list-services` | List all services | |
| 75 | +| `init-project` | Initialise `[tool.pyarchrules]` in `pyproject.toml` | |
| 76 | +| `add-service NAME PATH` | Register a service | |
| 77 | +| `remove-service NAME` | Remove a service | |
| 78 | +| `list-services` | Show all configured services | |
| 79 | +| `check` | Validate architecture | |
75 | 80 |
|
76 | | -## Use Cases |
77 | | - |
78 | | -**Monorepos** - enforce boundaries between services |
79 | | -```toml |
80 | | -[tool.pyarchrules.services.auth] |
81 | | -path = "services/auth" |
82 | | -dependencies = ["auth -> shared"] |
83 | | -``` |
| 81 | +## Documentation |
84 | 82 |
|
85 | | -**Clean Architecture** - validate layer dependencies |
86 | | -```toml |
87 | | -dependencies = [ |
88 | | - "api -> application", |
89 | | - "application -> domain" |
90 | | -] |
91 | | -``` |
| 83 | +Full documentation: <https://mspitb.github.io/pyarchrules> |
92 | 84 |
|
93 | | -**Microservices** - ensure consistent structure |
94 | | -```toml |
95 | | -tree = ["api", "domain", "infrastructure"] |
96 | | -tree_strict = true |
97 | | -``` |
| 85 | +## Contributing |
98 | 86 |
|
99 | | -## Development |
| 87 | +Contributions are welcome. Please open an issue before submitting a pull request for non-trivial changes. |
100 | 88 |
|
101 | 89 | ```bash |
102 | | -uv pip install -e ".[dev]" |
| 90 | +git clone https://github.com/mspitb/pyarchrules |
| 91 | +cd pyarchrules |
| 92 | +uv sync --all-extras |
103 | 93 | make test |
104 | 94 | make lint |
105 | 95 | ``` |
106 | 96 |
|
107 | | -## Status |
108 | | - |
109 | | -⚠️ **Alpha** - API may change before 1.0 release |
110 | | - |
111 | 97 | ## License |
112 | 98 |
|
113 | 99 | MIT |
114 | | - |
0 commit comments