@makinzm/mille 0.0.12 → 0.0.14
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.
- package/README.md +129 -16
- package/mille.wasm +0 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -2,27 +2,20 @@
|
|
|
2
2
|
|
|
3
3
|
> Like a mille crêpe — your architecture, one clean layer at a time.
|
|
4
4
|
|
|
5
|
-
```
|
|
6
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ presentation
|
|
7
|
-
· · · · · · · · · · · · · · · · · · (deps only flow inward)
|
|
8
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ infrastructure
|
|
9
|
-
· · · · · · · · · · · · · · · · · ·
|
|
10
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ usecase
|
|
11
|
-
· · · · · · · · · · · · · · · · · ·
|
|
12
|
-
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ domain
|
|
13
|
-
```
|
|
14
|
-
|
|
15
5
|
`mille` is a static analysis CLI that enforces **dependency rules for layered architectures** — Clean Architecture, Onion Architecture, Hexagonal Architecture, and more.
|
|
16
6
|
|
|
17
7
|
One TOML config. Rust-powered. CI-ready. Supports multiple languages from a single config file.
|
|
18
8
|
|
|
19
9
|
## What it checks
|
|
20
10
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
|
24
|
-
|
|
25
|
-
|
|
|
11
|
+
**Languages:** Rust, Go, TypeScript, JavaScript, Python, Java, Kotlin, PHP, C
|
|
12
|
+
|
|
13
|
+
| Check | Description |
|
|
14
|
+
|---|---|
|
|
15
|
+
| `dependency_mode` | Layer dependency rules — control which layers can import from which |
|
|
16
|
+
| `external_mode` | External library rules — restrict third-party package usage per layer |
|
|
17
|
+
| `allow_call_patterns` | DI method call rules — limit which methods may be called on injected types |
|
|
18
|
+
| `name_deny` | Naming convention rules — forbid infrastructure keywords in domain/usecase |
|
|
26
19
|
|
|
27
20
|
## Install
|
|
28
21
|
|
|
@@ -120,6 +113,8 @@ The generated config includes `allow` (inferred internal dependencies) and `exte
|
|
|
120
113
|
|
|
121
114
|
**Python submodule imports**: `external_allow = ["matplotlib"]` correctly allows both `import matplotlib` and `import matplotlib.pyplot`.
|
|
122
115
|
|
|
116
|
+
**Python `src/` layout (namespace packages)**: When your project uses a `src/` layout and imports like `from src.domain.entity import Foo`, `mille init` detects that `src` is used as a top-level import prefix and automatically adds it to `package_names`. This means `from src.domain...` is classified as Internal and `src` does not appear in `external_allow`. Cross-layer imports like `from src.domain.entity import Foo` (written in `src/infrastructure/`) are correctly resolved to the `src/domain` layer and appear as an `allow` dependency in the generated `mille.toml`. Files at the project root of a sub-tree (e.g. `src/main.py`) are included in the `src` layer rather than being silently skipped.
|
|
117
|
+
|
|
123
118
|
**Go projects**: `mille init` reads `go.mod` and generates `[resolve.go] module_name` automatically — internal module imports are classified correctly during `mille check`. External packages appear in `external_allow` with their full import paths (e.g. `"github.com/cilium/ebpf"`, `"fmt"`, `"net/http"`).
|
|
124
119
|
|
|
125
120
|
**TypeScript/JavaScript subpath imports**: `external_allow = ["vitest"]` correctly allows both `import "vitest"` and `import "vitest/config"`. Scoped packages (`@scope/name/sub`) are matched by `"@scope/name"`.
|
|
@@ -416,7 +411,7 @@ Exit codes:
|
|
|
416
411
|
|---|---|
|
|
417
412
|
| `name` | Project name |
|
|
418
413
|
| `root` | Root directory for analysis |
|
|
419
|
-
| `languages` | Languages to check: `"rust"`, `"go"`, `"typescript"`, `"javascript"`, `"python"`, `"java"`, `"kotlin"` |
|
|
414
|
+
| `languages` | Languages to check: `"rust"`, `"go"`, `"typescript"`, `"javascript"`, `"python"`, `"java"`, `"kotlin"`, `"php"`, `"c"` |
|
|
420
415
|
|
|
421
416
|
### `[[layers]]`
|
|
422
417
|
|
|
@@ -430,6 +425,45 @@ Exit codes:
|
|
|
430
425
|
| `external_mode` | `"opt-in"` or `"opt-out"` for external library usage |
|
|
431
426
|
| `external_allow` | Allowed external packages (when `external_mode = "opt-in"`) |
|
|
432
427
|
| `external_deny` | Forbidden external packages (when `external_mode = "opt-out"`) |
|
|
428
|
+
| `name_deny` | Forbidden keywords for naming convention check (case-insensitive partial match) |
|
|
429
|
+
| `name_allow` | Substrings to strip before `name_deny` check (e.g. `"category"` prevents `"go"` match inside it) |
|
|
430
|
+
| `name_targets` | Targets to check: `"file"`, `"symbol"`, `"variable"`, `"comment"`, `"string_literal"`, `"identifier"` (default: all) |
|
|
431
|
+
| `name_deny_ignore` | Glob patterns for files to exclude from naming checks (e.g. `"**/test_*.rs"`) |
|
|
432
|
+
|
|
433
|
+
#### Naming Convention Check (`name_deny`)
|
|
434
|
+
|
|
435
|
+
Forbid infrastructure-specific keywords from appearing in a layer's names.
|
|
436
|
+
|
|
437
|
+
```toml
|
|
438
|
+
[[layers]]
|
|
439
|
+
name = "usecase"
|
|
440
|
+
paths = ["src/usecase/**"]
|
|
441
|
+
dependency_mode = "opt-out"
|
|
442
|
+
deny = []
|
|
443
|
+
external_mode = "opt-out"
|
|
444
|
+
external_deny = []
|
|
445
|
+
|
|
446
|
+
# Usecase layer must not reference specific infrastructure technologies
|
|
447
|
+
name_deny = ["gcp", "aws", "azure", "mysql", "postgres"]
|
|
448
|
+
name_allow = ["category"] # "category" contains "go" but should not be flagged
|
|
449
|
+
name_targets = ["file", "symbol", "variable", "comment", "string_literal", "identifier"] # default: all targets
|
|
450
|
+
name_deny_ignore = ["**/test_*.rs", "tests/**"] # exclude test files from naming checks
|
|
451
|
+
```
|
|
452
|
+
|
|
453
|
+
**Rules:**
|
|
454
|
+
- Case-insensitive (`GCP` = `gcp` = `Gcp`)
|
|
455
|
+
- Partial match (`ManageGcp` also matches `gcp`)
|
|
456
|
+
- `name_allow` strips listed substrings before matching (e.g. `"category"` prevents false positive on `"go"`)
|
|
457
|
+
- `name_deny_ignore` excludes files matching glob patterns from naming checks entirely
|
|
458
|
+
- `name_targets` restricts which entity types are checked:
|
|
459
|
+
- `"file"`: file basename (e.g. `aws_client.rs`)
|
|
460
|
+
- `"symbol"`: function, class, struct, enum, trait, interface, type alias names
|
|
461
|
+
- `"variable"`: variable, const, let, static declaration names
|
|
462
|
+
- `"comment"`: inline comment content
|
|
463
|
+
- `"string_literal"`: string literal content
|
|
464
|
+
- `"identifier"`: attribute/field access identifiers (e.g. `gcp` in `cfg.gcp.bucket`)
|
|
465
|
+
- Supported languages: Rust, TypeScript, JavaScript, Python, Go, Java, Kotlin, PHP, C
|
|
466
|
+
- Severity is controlled by `severity.naming_violation` (default: `"error"`)
|
|
433
467
|
|
|
434
468
|
### `[[layers.allow_call_patterns]]`
|
|
435
469
|
|
|
@@ -470,6 +504,7 @@ Control the severity level of each violation type. Violations can be `"error"`,
|
|
|
470
504
|
| `external_violation` | `"error"` | External library rule violated |
|
|
471
505
|
| `call_pattern_violation` | `"error"` | DI entrypoint method call rule violated |
|
|
472
506
|
| `unknown_import` | `"warning"` | Import that could not be classified |
|
|
507
|
+
| `naming_violation` | `"error"` | Naming convention rule violated (`name_deny`) |
|
|
473
508
|
|
|
474
509
|
```toml
|
|
475
510
|
[severity]
|
|
@@ -477,6 +512,7 @@ dependency_violation = "warning" # treat as warning for gradual adoption
|
|
|
477
512
|
external_violation = "error"
|
|
478
513
|
call_pattern_violation = "error"
|
|
479
514
|
unknown_import = "warning"
|
|
515
|
+
naming_violation = "warning" # treat as warning while rolling out naming rules
|
|
480
516
|
```
|
|
481
517
|
|
|
482
518
|
Use `--fail-on warning` to exit 1 even for warnings when integrating into CI gradually.
|
|
@@ -536,6 +572,83 @@ Use `--fail-on warning` to exit 1 even for warnings when integrating into CI gra
|
|
|
536
572
|
|
|
537
573
|
> Both regular and static imports are supported. Wildcard imports (`import java.util.*`) are not yet extracted by the parser.
|
|
538
574
|
|
|
575
|
+
### `[resolve.php]`
|
|
576
|
+
|
|
577
|
+
| Key | Description |
|
|
578
|
+
|---|---|
|
|
579
|
+
| `namespace` | Base namespace of your project (e.g. `App`). Imports starting with this prefix are classified as Internal. |
|
|
580
|
+
| `composer_json` | Path to `composer.json` (relative to `mille.toml`). The first PSR-4 key in `autoload.psr-4` is used as the base namespace when `namespace` is not set. |
|
|
581
|
+
|
|
582
|
+
**How PHP imports are classified:**
|
|
583
|
+
|
|
584
|
+
| Import | Classification |
|
|
585
|
+
|---|---|
|
|
586
|
+
| `use App\Models\User` (starts with `namespace`) | Internal |
|
|
587
|
+
| `use App\Services\{Auth, Logger}` (group use, expanded) | Internal |
|
|
588
|
+
| `use function App\Helpers\format_date` | Internal |
|
|
589
|
+
| `use DateTime`, `use PDO`, `use Exception` | Stdlib |
|
|
590
|
+
| `use Illuminate\Http\Request` | External |
|
|
591
|
+
|
|
592
|
+
> Supported use forms: simple, aliased (`as`), grouped (`{}`), `use function`, `use const`.
|
|
593
|
+
> PHP stdlib classes (DateTime, PDO, Exception, etc.) are automatically classified as Stdlib without any configuration.
|
|
594
|
+
|
|
595
|
+
**Example `mille.toml` for a Laravel project:**
|
|
596
|
+
|
|
597
|
+
```toml
|
|
598
|
+
[project]
|
|
599
|
+
name = "my-laravel-app"
|
|
600
|
+
root = "."
|
|
601
|
+
languages = ["php"]
|
|
602
|
+
|
|
603
|
+
[[layers]]
|
|
604
|
+
name = "domain"
|
|
605
|
+
paths = ["app/Domain/**"]
|
|
606
|
+
|
|
607
|
+
[[layers]]
|
|
608
|
+
name = "application"
|
|
609
|
+
paths = ["app/Application/**"]
|
|
610
|
+
dependency_mode = "opt-in"
|
|
611
|
+
allow = ["domain"]
|
|
612
|
+
|
|
613
|
+
[[layers]]
|
|
614
|
+
name = "infrastructure"
|
|
615
|
+
paths = ["app/Infrastructure/**"]
|
|
616
|
+
dependency_mode = "opt-in"
|
|
617
|
+
allow = ["domain", "application"]
|
|
618
|
+
|
|
619
|
+
[resolve.php]
|
|
620
|
+
composer_json = "composer.json" # auto-detects "App\\" from autoload.psr-4
|
|
621
|
+
```
|
|
622
|
+
|
|
623
|
+
### C
|
|
624
|
+
|
|
625
|
+
> `#include "..."` is classified as Internal (project header). `#include <...>` is classified as Stdlib (standard/POSIX headers) or External (third-party libraries).
|
|
626
|
+
|
|
627
|
+
**Example `mille.toml` for a C project:**
|
|
628
|
+
|
|
629
|
+
```toml
|
|
630
|
+
[project]
|
|
631
|
+
name = "my-c-app"
|
|
632
|
+
root = "."
|
|
633
|
+
languages = ["c"]
|
|
634
|
+
|
|
635
|
+
[[layers]]
|
|
636
|
+
name = "domain"
|
|
637
|
+
paths = ["src/domain/**"]
|
|
638
|
+
|
|
639
|
+
[[layers]]
|
|
640
|
+
name = "usecase"
|
|
641
|
+
paths = ["src/usecase/**"]
|
|
642
|
+
dependency_mode = "opt-in"
|
|
643
|
+
allow = ["domain"]
|
|
644
|
+
|
|
645
|
+
[[layers]]
|
|
646
|
+
name = "infrastructure"
|
|
647
|
+
paths = ["src/infrastructure/**"]
|
|
648
|
+
dependency_mode = "opt-in"
|
|
649
|
+
allow = ["domain"]
|
|
650
|
+
```
|
|
651
|
+
|
|
539
652
|
## How it Works
|
|
540
653
|
|
|
541
654
|
mille uses [tree-sitter](https://tree-sitter.github.io/) for AST-based import extraction — no regex heuristics.
|
package/mille.wasm
CHANGED
|
Binary file
|