Skip to content

Commit 0144777

Browse files
committed
docs: Add new example docs pages and example projects (layered, hexagonal, legacy migration)
- add examples section in docs with mermaid support - Add MkDocs nav entries and snippet base_path config - Enable Mermaid diagrams via superfences, mermaid.js, and extra CSS - Update snapshot storage layout docs and troubleshooting paths
1 parent f7af17d commit 0144777

41 files changed

Lines changed: 1285 additions & 75 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

docs/configuration.md

Lines changed: 9 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -270,15 +270,15 @@ Pacta stores data in a `.pacta/` directory at your repository root.
270270

271271
```
272272
.pacta/
273-
── snapshots/ # Content-addressed snapshot storage
274-
├── ab/ # First 2 chars of hash
275-
── cdef1234... # Snapshot data (JSON)
276-
── ...
277-
├── refs/ # Named references to snapshots
278-
── latest # Most recent snapshot
279-
├── baseline # Baseline for comparison
280-
── ...
281-
└── config.json # Optional local configuration
273+
── snapshots/
274+
├── objects/ # Content-addressed snapshot storage
275+
── a1b2c3d4.json # 8-char hash prefix filename
276+
── e5f6a7b8.json
277+
└── ...
278+
── refs/ # Named references to snapshots
279+
├── latest # Text file containing hash of most recent snapshot
280+
── baseline # Text file containing hash (created with --save-ref)
281+
└── ...
282282
```
283283
284284
### Snapshots
@@ -313,12 +313,3 @@ Add to `.gitignore` only if you don't need persistent baselines:
313313
# Ignore Pacta data (not recommended)
314314
.pacta/
315315
```
316-
317-
---
318-
319-
## Environment Variables
320-
321-
| Variable | Description | Default |
322-
|----------|-------------|---------|
323-
| `PACTA_NO_COLOR` | Disable colored output | `false` |
324-
| `PACTA_DATA_DIR` | Override `.pacta/` location | `.pacta/` |

docs/examples/hexagonal-app.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--8<-- "examples/hexagonal-app/README.md"

docs/examples/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--8<-- "examples/README.md"

docs/examples/legacy-migration.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--8<-- "examples/legacy-migration/README.md"
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
--8<-- "examples/simple-layered-app/README.md"

docs/stylesheets/extra.css

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
/* Mermaid diagram styling */
2+
.mermaid {
3+
text-align: center;
4+
margin: 1rem 0;
5+
}
6+
7+
/* Ensure mermaid diagrams are responsive */
8+
.mermaid svg {
9+
max-width: 100%;
10+
height: auto;
11+
}

docs/troubleshooting.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,8 @@ Error: Baseline 'baseline' not found
119119

120120
2. Check that `.pacta/` directory exists and contains snapshots:
121121
```bash
122-
ls -la .pacta/snapshots/
122+
ls -la .pacta/snapshots/objects/
123+
ls -la .pacta/snapshots/refs/
123124
```
124125

125126
3. If using CI, ensure the `.pacta/` directory is cached or committed
@@ -191,7 +192,10 @@ Coming soon:
191192

192193
### How do baselines work?
193194

194-
Baselines are content-addressed snapshots of your architecture at a point in time.
195+
Baselines are content-addressed snapshots of your architecture at a point in time. They're stored in `.pacta/snapshots/`:
196+
197+
- **Objects** (`.pacta/snapshots/objects/`) - Immutable snapshot files named by 8-char hash
198+
- **Refs** (`.pacta/snapshots/refs/`) - Named pointers (like `baseline`, `latest`) to object hashes
195199

196200
1. **Create baseline:** Saves current violations with a reference name
197201
```bash

examples/README.md

Lines changed: 24 additions & 53 deletions
Original file line numberDiff line numberDiff line change
@@ -1,64 +1,35 @@
1-
# Pacta Examples
1+
# Examples
22

3-
## simple-layered-app
3+
Pacta includes several example projects demonstrating different architectural patterns and use cases.
44

5-
A Python application demonstrating clean architecture with four layers:
5+
## Available Examples
66

7-
```
8-
src/
9-
├── ui/ # Controllers, API endpoints
10-
├── application/ # Use cases, services
11-
├── domain/ # Business logic, models
12-
└── infra/ # Repositories, database
13-
```
14-
15-
### Files
16-
17-
- `architecture.yml` - Defines layers and their file patterns
18-
- `rules.pacta.yml` - Architectural rules (e.g., domain cannot depend on infra)
19-
20-
### Try it
7+
| Example | Description | Best For |
8+
|---------|-------------|----------|
9+
| [Simple Layered App](simple-layered-app.md) | Classic N-tier architecture | Teams familiar with layered architecture |
10+
| [Hexagonal Architecture](hexagonal-app.md) | Ports and Adapters pattern | Domain-driven design, high testability |
11+
| [Legacy Migration](legacy-migration.md) | Baseline workflow for brownfield | Existing codebases, incremental adoption |
2112

22-
```bash
23-
cd simple-layered-app
24-
25-
# Scan for violations
26-
pacta scan src \
27-
--model architecture.yml \
28-
--rules rules.pacta.yml
13+
## Quick Start
2914

30-
# Quiet mode (summary only)
31-
pacta scan src \
32-
--model architecture.yml \
33-
--rules rules.pacta.yml -q
15+
Each example includes:
3416

35-
# Verbose mode (all details)
36-
pacta scan src \
37-
--model architecture.yml \
38-
--rules rules.pacta.yml -v
17+
- `architecture.yml` - System and layer definitions
18+
- `rules.pacta.yml` - Architectural constraints
19+
- `src/` - Sample Python code demonstrating the architecture
3920

40-
# Save a baseline
41-
pacta scan src \
42-
--model architecture.yml \
43-
--rules rules.pacta.yml \
44-
--save-ref baseline
21+
To run any example:
4522

46-
# Compare against baseline
47-
pacta scan src \
48-
--model architecture.yml \
49-
--rules rules.pacta.yml \
50-
--baseline baseline
23+
```bash
24+
cd examples/<example-name>
25+
pacta scan . --model architecture.yml --rules rules.pacta.yml
26+
```
5127

52-
# Save architecture snapshot (without running rules)
53-
pacta snapshot save src \
54-
--model architecture.yml \
55-
--ref v1
28+
## Creating Your Own
5629

57-
# Save another snapshot
58-
pacta snapshot save src \
59-
--model architecture.yml \
60-
--ref v2
30+
1. Copy the example closest to your needs
31+
2. Modify `architecture.yml` to match your directory structure
32+
3. Adjust `rules.pacta.yml` for your constraints
33+
4. Run `pacta scan` and iterate
6134

62-
# Compare two snapshots
63-
pacta diff src --from v1 --to v2
64-
```
35+
See the [Configuration Reference](../configuration.md) for full schema documentation.

examples/hexagonal-app/README.md

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,95 @@
1+
# Hexagonal Architecture Example
2+
3+
This example demonstrates how to use Pacta to enforce [Hexagonal Architecture](https://alistair.cockburn.us/hexagonal-architecture/) (also known as Ports and Adapters).
4+
5+
## Architecture Overview
6+
7+
```mermaid
8+
flowchart TB
9+
subgraph Driving["Driving Side (Primary)"]
10+
PA[Primary Adapters<br/>Controllers, CLI, Event Handlers]
11+
end
12+
13+
subgraph Application["Application Core"]
14+
IP[Inbound Ports<br/>Use Case Interfaces]
15+
subgraph Domain["DOMAIN"]
16+
D[Entities<br/>Domain Services]
17+
end
18+
OP[Outbound Ports<br/>Repository Interfaces]
19+
end
20+
21+
subgraph Driven["Driven Side (Secondary)"]
22+
SA[Secondary Adapters<br/>Database, APIs, Queues]
23+
end
24+
25+
PA -->|uses| IP
26+
IP -->|calls| D
27+
D -->|uses| OP
28+
SA -.->|implements| OP
29+
30+
style Domain fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
31+
style D fill:#bbdefb,stroke:#1565c0
32+
style IP fill:#fff8e1,stroke:#f57f17
33+
style OP fill:#fff8e1,stroke:#f57f17
34+
style PA fill:#f3e5f5,stroke:#7b1fa2
35+
style SA fill:#e8f5e9,stroke:#2e7d32
36+
```
37+
38+
## Directory Structure
39+
40+
```
41+
src/
42+
├── domain/ # Core business logic (center of hexagon)
43+
│ ├── product.py # Domain entity
44+
│ └── product_service.py # Domain service
45+
46+
├── ports/
47+
│ ├── inbound/ # Driving ports (use case interfaces)
48+
│ │ └── catalog_use_case.py
49+
│ └── outbound/ # Driven ports (repository interfaces)
50+
│ └── product_repository.py
51+
52+
└── adapters/
53+
├── primary/ # Driving adapters (controllers, CLI)
54+
│ └── api_controller.py
55+
└── secondary/ # Driven adapters (database, APIs)
56+
└── postgres_product_repository.py
57+
```
58+
59+
## Key Rules
60+
61+
| Rule | Description |
62+
|------|-------------|
63+
| Domain → Adapters | **Forbidden** - Domain must not know about adapters |
64+
| Domain → Outbound Ports | **Allowed** - Domain uses repository interfaces |
65+
| Ports → Adapters | **Forbidden** - Ports are interfaces, adapters implement them |
66+
| Primary Adapters → Domain | **Warning** - Should go through inbound ports |
67+
| Secondary Adapters → Outbound Ports | **Allowed** - Implements the interface |
68+
| Adapters → Adapters | **Forbidden** - Adapters should be independent |
69+
70+
## Usage
71+
72+
```bash
73+
# Run architecture check
74+
pacta scan . --model architecture.yml --rules rules.pacta.yml
75+
76+
# Expected output (clean architecture):
77+
# ✓ 0 violations
78+
```
79+
80+
## Dependency Flow
81+
82+
Dependencies always point **inward** toward the domain:
83+
84+
```mermaid
85+
flowchart LR
86+
PA[Primary<br/>Adapters] --> IP[Inbound<br/>Ports] --> D((DOMAIN))
87+
SA[Secondary<br/>Adapters] --> OP[Outbound<br/>Ports] --> D
88+
89+
style D fill:#e3f2fd,stroke:#1565c0,stroke-width:2px
90+
```
91+
92+
This ensures:
93+
- Domain is isolated and testable
94+
- Adapters can be swapped without changing business logic
95+
- The application is framework-agnostic
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
version: 1
2+
system:
3+
id: hexagonal-app
4+
name: Hexagonal Architecture Example
5+
6+
containers:
7+
main-app:
8+
name: Main Application
9+
description: |
10+
Demonstrates Hexagonal Architecture (Ports and Adapters).
11+
The domain is at the center, ports define boundaries,
12+
and adapters connect to the outside world.
13+
code:
14+
roots:
15+
- src
16+
layers:
17+
# Core business logic - the heart of the hexagon
18+
domain:
19+
name: Domain
20+
description: Core business logic, entities, and domain services
21+
patterns:
22+
- src/domain/**
23+
24+
# Ports - interfaces that define how the domain communicates
25+
ports-inbound:
26+
name: Inbound Ports
27+
description: Use case interfaces (driving/primary ports)
28+
patterns:
29+
- src/ports/inbound/**
30+
31+
ports-outbound:
32+
name: Outbound Ports
33+
description: Repository and external service interfaces (driven/secondary ports)
34+
patterns:
35+
- src/ports/outbound/**
36+
37+
# Adapters - implementations that connect to the outside world
38+
adapters-primary:
39+
name: Primary Adapters
40+
description: Controllers, CLI, event handlers (driving adapters)
41+
patterns:
42+
- src/adapters/primary/**
43+
44+
adapters-secondary:
45+
name: Secondary Adapters
46+
description: Repository implementations, external API clients (driven adapters)
47+
patterns:
48+
- src/adapters/secondary/**
49+
50+
contexts: {}

0 commit comments

Comments
 (0)