@makinzm/mille 0.0.12 → 0.0.13

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 (3) hide show
  1. package/README.md +96 -6
  2. package/mille.wasm +0 -0
  3. package/package.json +1 -1
package/README.md CHANGED
@@ -18,11 +18,12 @@ One TOML config. Rust-powered. CI-ready. Supports multiple languages from a sing
18
18
 
19
19
  ## What it checks
20
20
 
21
- | Check | Rust | Go | TypeScript | JavaScript | Python | Java | Kotlin |
22
- |---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
23
- | Layer dependency rules (`dependency_mode`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
24
- | External library rules (`external_mode`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
25
- | DI method call rules (`allow_call_patterns`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
21
+ | Check | Rust | Go | TypeScript | JavaScript | Python | Java | Kotlin | PHP |
22
+ |---|:---:|:---:|:---:|:---:|:---:|:---:|:---:|:---:|
23
+ | Layer dependency rules (`dependency_mode`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
24
+ | External library rules (`external_mode`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
25
+ | DI method call rules (`allow_call_patterns`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
26
+ | Naming convention rules (`name_deny`) | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
26
27
 
27
28
  ## Install
28
29
 
@@ -120,6 +121,8 @@ The generated config includes `allow` (inferred internal dependencies) and `exte
120
121
 
121
122
  **Python submodule imports**: `external_allow = ["matplotlib"]` correctly allows both `import matplotlib` and `import matplotlib.pyplot`.
122
123
 
124
+ **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.
125
+
123
126
  **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
127
 
125
128
  **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 +419,7 @@ Exit codes:
416
419
  |---|---|
417
420
  | `name` | Project name |
418
421
  | `root` | Root directory for analysis |
419
- | `languages` | Languages to check: `"rust"`, `"go"`, `"typescript"`, `"javascript"`, `"python"`, `"java"`, `"kotlin"` |
422
+ | `languages` | Languages to check: `"rust"`, `"go"`, `"typescript"`, `"javascript"`, `"python"`, `"java"`, `"kotlin"`, `"php"` |
420
423
 
421
424
  ### `[[layers]]`
422
425
 
@@ -430,6 +433,43 @@ Exit codes:
430
433
  | `external_mode` | `"opt-in"` or `"opt-out"` for external library usage |
431
434
  | `external_allow` | Allowed external packages (when `external_mode = "opt-in"`) |
432
435
  | `external_deny` | Forbidden external packages (when `external_mode = "opt-out"`) |
436
+ | `name_deny` | Forbidden keywords for naming convention check (case-insensitive partial match) |
437
+ | `name_allow` | Substrings to strip before `name_deny` check (e.g. `"category"` prevents `"go"` match inside it) |
438
+ | `name_targets` | Targets to check: `"file"`, `"symbol"`, `"variable"`, `"comment"` (default: all) |
439
+ | `name_deny_ignore` | Glob patterns for files to exclude from naming checks (e.g. `"**/test_*.rs"`) |
440
+
441
+ #### Naming Convention Check (`name_deny`)
442
+
443
+ Forbid infrastructure-specific keywords from appearing in a layer's names.
444
+
445
+ ```toml
446
+ [[layers]]
447
+ name = "usecase"
448
+ paths = ["src/usecase/**"]
449
+ dependency_mode = "opt-out"
450
+ deny = []
451
+ external_mode = "opt-out"
452
+ external_deny = []
453
+
454
+ # Usecase layer must not reference specific infrastructure technologies
455
+ name_deny = ["gcp", "aws", "azure", "mysql", "postgres"]
456
+ name_allow = ["category"] # "category" contains "go" but should not be flagged
457
+ name_targets = ["file", "symbol", "variable", "comment"] # default: all targets
458
+ name_deny_ignore = ["**/test_*.rs", "tests/**"] # exclude test files from naming checks
459
+ ```
460
+
461
+ **Rules:**
462
+ - Case-insensitive (`GCP` = `gcp` = `Gcp`)
463
+ - Partial match (`ManageGcp` also matches `gcp`)
464
+ - `name_allow` strips listed substrings before matching (e.g. `"category"` prevents false positive on `"go"`)
465
+ - `name_deny_ignore` excludes files matching glob patterns from naming checks entirely
466
+ - `name_targets` restricts which entity types are checked:
467
+ - `"file"`: file basename (e.g. `aws_client.rs`)
468
+ - `"symbol"`: function, class, struct, enum, trait, interface, type alias names
469
+ - `"variable"`: variable, const, let, static declaration names
470
+ - `"comment"`: inline comment content
471
+ - Supported languages: Rust, TypeScript, JavaScript, Python, Go, Java, Kotlin, PHP
472
+ - Severity is controlled by `severity.naming_violation` (default: `"error"`)
433
473
 
434
474
  ### `[[layers.allow_call_patterns]]`
435
475
 
@@ -470,6 +510,7 @@ Control the severity level of each violation type. Violations can be `"error"`,
470
510
  | `external_violation` | `"error"` | External library rule violated |
471
511
  | `call_pattern_violation` | `"error"` | DI entrypoint method call rule violated |
472
512
  | `unknown_import` | `"warning"` | Import that could not be classified |
513
+ | `naming_violation` | `"error"` | Naming convention rule violated (`name_deny`) |
473
514
 
474
515
  ```toml
475
516
  [severity]
@@ -477,6 +518,7 @@ dependency_violation = "warning" # treat as warning for gradual adoption
477
518
  external_violation = "error"
478
519
  call_pattern_violation = "error"
479
520
  unknown_import = "warning"
521
+ naming_violation = "warning" # treat as warning while rolling out naming rules
480
522
  ```
481
523
 
482
524
  Use `--fail-on warning` to exit 1 even for warnings when integrating into CI gradually.
@@ -536,6 +578,54 @@ Use `--fail-on warning` to exit 1 even for warnings when integrating into CI gra
536
578
 
537
579
  > Both regular and static imports are supported. Wildcard imports (`import java.util.*`) are not yet extracted by the parser.
538
580
 
581
+ ### `[resolve.php]`
582
+
583
+ | Key | Description |
584
+ |---|---|
585
+ | `namespace` | Base namespace of your project (e.g. `App`). Imports starting with this prefix are classified as Internal. |
586
+ | `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. |
587
+
588
+ **How PHP imports are classified:**
589
+
590
+ | Import | Classification |
591
+ |---|---|
592
+ | `use App\Models\User` (starts with `namespace`) | Internal |
593
+ | `use App\Services\{Auth, Logger}` (group use, expanded) | Internal |
594
+ | `use function App\Helpers\format_date` | Internal |
595
+ | `use DateTime`, `use PDO`, `use Exception` | Stdlib |
596
+ | `use Illuminate\Http\Request` | External |
597
+
598
+ > Supported use forms: simple, aliased (`as`), grouped (`{}`), `use function`, `use const`.
599
+ > PHP stdlib classes (DateTime, PDO, Exception, etc.) are automatically classified as Stdlib without any configuration.
600
+
601
+ **Example `mille.toml` for a Laravel project:**
602
+
603
+ ```toml
604
+ [project]
605
+ name = "my-laravel-app"
606
+ root = "."
607
+ languages = ["php"]
608
+
609
+ [[layers]]
610
+ name = "domain"
611
+ paths = ["app/Domain/**"]
612
+
613
+ [[layers]]
614
+ name = "application"
615
+ paths = ["app/Application/**"]
616
+ dependency_mode = "opt-in"
617
+ allow = ["domain"]
618
+
619
+ [[layers]]
620
+ name = "infrastructure"
621
+ paths = ["app/Infrastructure/**"]
622
+ dependency_mode = "opt-in"
623
+ allow = ["domain", "application"]
624
+
625
+ [resolve.php]
626
+ composer_json = "composer.json" # auto-detects "App\\" from autoload.psr-4
627
+ ```
628
+
539
629
  ## How it Works
540
630
 
541
631
  mille uses [tree-sitter](https://tree-sitter.github.io/) for AST-based import extraction — no regex heuristics.
package/mille.wasm CHANGED
Binary file
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@makinzm/mille",
3
- "version": "0.0.12",
3
+ "version": "0.0.13",
4
4
  "description": "Architecture Checker — Rust-based multi-language architecture linter",
5
5
  "main": "index.js",
6
6
  "bin": {