phasegate 0.139.0 → 0.140.0
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/CHANGELOG.md +8 -0
- package/package.json +1 -1
- package/scripts/harness/biome-ast-engine/application/usecases/resolve-enabled-rules-usecase.ts +1 -0
- package/scripts/harness/biome-ast-engine/domain/ports/rule-config-provider-port.ts +4 -0
- package/scripts/harness/biome-ast-engine/domain/services/lint-runner.ts +2 -2
- package/scripts/harness/biome-ast-engine/domain/value-objects/architecture-spec.ts +22 -1
- package/scripts/harness/biome-ast-engine/infrastructure/adapters/harness-config-provider-adapter.ts +4 -0
- package/scripts/harness/biome-ast-engine/infrastructure/adapters/typescript-source-module-analyzer-adapter.ts +3 -3
- package/scripts/harness/biome-ast-engine/infrastructure/parsers/layer-comment-parser.ts +11 -3
- package/scripts/harness/biome-ast-engine/infrastructure/parsers/unit-comment-parser.ts +12 -4
- package/scripts/harness/main.ts +1 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,14 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
7
7
|
|
|
8
8
|
## [Unreleased]
|
|
9
9
|
|
|
10
|
+
## [0.140.0] - 2026-05-09
|
|
11
|
+
|
|
12
|
+
### Added
|
|
13
|
+
|
|
14
|
+
- **WI-024 — configurable L1 metadata tag names** — `architecture.metadataTags.unit` / `architecture.metadataTags.layer` を biome-ast-engine の L1 parser / analyzer / runner に反映し、`@module` / `@tier` などのプロジェクト語彙を単一の有効タグ名として使えるようにした。
|
|
15
|
+
- 既定値は従来通り `@unit` / `@layer`。
|
|
16
|
+
- カスタムタグ設定時は旧タグを alias として扱わず、欠落メッセージも設定タグ名を表示する。
|
|
17
|
+
|
|
10
18
|
## [0.139.0] - 2026-05-09
|
|
11
19
|
|
|
12
20
|
### Added
|
package/package.json
CHANGED
package/scripts/harness/biome-ast-engine/application/usecases/resolve-enabled-rules-usecase.ts
CHANGED
|
@@ -60,6 +60,7 @@ export class ResolveEnabledRulesUseCase {
|
|
|
60
60
|
const architectureSpec = freezeArchitectureSpec({
|
|
61
61
|
layers: architecture.layers,
|
|
62
62
|
allowedDependencies: architecture.allowedDependencies,
|
|
63
|
+
metadataTags: architecture.metadataTags,
|
|
63
64
|
});
|
|
64
65
|
|
|
65
66
|
return toResolveEnabledRulesOutput(
|
|
@@ -16,6 +16,10 @@ export interface ArchitectureProviderInfo {
|
|
|
16
16
|
readonly preset: ArchitecturePresetIdValue;
|
|
17
17
|
readonly layers: readonly string[];
|
|
18
18
|
readonly allowedDependencies: Readonly<Record<string, readonly string[]>>;
|
|
19
|
+
readonly metadataTags?: {
|
|
20
|
+
readonly unit?: string;
|
|
21
|
+
readonly layer?: string;
|
|
22
|
+
};
|
|
19
23
|
}
|
|
20
24
|
|
|
21
25
|
export interface RuleConfigProviderPort {
|
|
@@ -75,7 +75,7 @@ export class LintRunner {
|
|
|
75
75
|
line: 1,
|
|
76
76
|
column: 1,
|
|
77
77
|
ruleName: rule.name,
|
|
78
|
-
message:
|
|
78
|
+
message: `${architecture.metadataTags.unit}コメントが必要です`,
|
|
79
79
|
severity: rule.severity,
|
|
80
80
|
})
|
|
81
81
|
);
|
|
@@ -92,7 +92,7 @@ export class LintRunner {
|
|
|
92
92
|
line: 1,
|
|
93
93
|
column: 1,
|
|
94
94
|
ruleName: rule.name,
|
|
95
|
-
message:
|
|
95
|
+
message: `${architecture.metadataTags.layer}コメントが必要です`,
|
|
96
96
|
severity: rule.severity,
|
|
97
97
|
})
|
|
98
98
|
);
|
|
@@ -6,8 +6,25 @@
|
|
|
6
6
|
export type ArchitectureSpec = {
|
|
7
7
|
readonly layers: readonly string[];
|
|
8
8
|
readonly allowedDependencies: Readonly<Record<string, readonly string[]>>;
|
|
9
|
+
readonly metadataTags: ArchitectureMetadataTags;
|
|
9
10
|
};
|
|
10
11
|
|
|
12
|
+
export type ArchitectureMetadataTags = {
|
|
13
|
+
readonly unit: string;
|
|
14
|
+
readonly layer: string;
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
export type ArchitectureSpecInput = {
|
|
18
|
+
readonly layers: readonly string[];
|
|
19
|
+
readonly allowedDependencies: Readonly<Record<string, readonly string[]>>;
|
|
20
|
+
readonly metadataTags?: Partial<ArchitectureMetadataTags>;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export const DEFAULT_METADATA_TAGS: ArchitectureMetadataTags = Object.freeze({
|
|
24
|
+
unit: '@unit',
|
|
25
|
+
layer: '@layer',
|
|
26
|
+
});
|
|
27
|
+
|
|
11
28
|
const freezeDependencyMap = (
|
|
12
29
|
map: Record<string, readonly string[]>
|
|
13
30
|
): Readonly<Record<string, readonly string[]>> => {
|
|
@@ -20,10 +37,14 @@ const freezeDependencyMap = (
|
|
|
20
37
|
return Object.freeze(frozen);
|
|
21
38
|
};
|
|
22
39
|
|
|
23
|
-
export const freezeArchitectureSpec = (spec:
|
|
40
|
+
export const freezeArchitectureSpec = (spec: ArchitectureSpecInput): ArchitectureSpec => {
|
|
24
41
|
return Object.freeze({
|
|
25
42
|
layers: Object.freeze([...spec.layers]),
|
|
26
43
|
allowedDependencies: freezeDependencyMap({ ...spec.allowedDependencies }),
|
|
44
|
+
metadataTags: Object.freeze({
|
|
45
|
+
...DEFAULT_METADATA_TAGS,
|
|
46
|
+
...spec.metadataTags,
|
|
47
|
+
}),
|
|
27
48
|
});
|
|
28
49
|
};
|
|
29
50
|
|
package/scripts/harness/biome-ast-engine/infrastructure/adapters/harness-config-provider-adapter.ts
CHANGED
|
@@ -29,6 +29,10 @@ const DEFAULT_ARCHITECTURE: ArchitectureConfigInput = Object.freeze({
|
|
|
29
29
|
infrastructure: Object.freeze(['infrastructure', 'application', 'domain']),
|
|
30
30
|
presentation: Object.freeze(['presentation', 'application', 'domain']),
|
|
31
31
|
}),
|
|
32
|
+
metadataTags: Object.freeze({
|
|
33
|
+
unit: '@unit',
|
|
34
|
+
layer: '@layer',
|
|
35
|
+
}),
|
|
32
36
|
});
|
|
33
37
|
|
|
34
38
|
/**
|
|
@@ -56,8 +56,8 @@ export class TypeScriptSourceModuleAnalyzerAdapter implements SourceModuleAnalyz
|
|
|
56
56
|
}
|
|
57
57
|
|
|
58
58
|
const sourceText = sourceFile.getFullText();
|
|
59
|
-
const unitResult = parseUnitComment(sourceText);
|
|
60
|
-
const layerResult = parseLayerComment(sourceText);
|
|
59
|
+
const unitResult = parseUnitComment(sourceText, architecture?.metadataTags.unit);
|
|
60
|
+
const layerResult = parseLayerComment(sourceText, architecture?.metadataTags.layer);
|
|
61
61
|
const densityResult = parseCommentDensity(sourceText);
|
|
62
62
|
const imports = this.extractImports(sourceFile, filePath);
|
|
63
63
|
const anyCount = this.countAnyTypes(sourceFile);
|
|
@@ -69,7 +69,7 @@ export class TypeScriptSourceModuleAnalyzerAdapter implements SourceModuleAnalyz
|
|
|
69
69
|
SourceModuleSnapshot.create(
|
|
70
70
|
{
|
|
71
71
|
filePath,
|
|
72
|
-
declaredUnit: unitResult.unitNames[0],
|
|
72
|
+
declaredUnit: unitResult.unitNames[0] ?? null,
|
|
73
73
|
declaredLayer: layerResult.layerName,
|
|
74
74
|
imports,
|
|
75
75
|
anyTypeCount: anyCount,
|
|
@@ -1,14 +1,22 @@
|
|
|
1
1
|
// @unit biome-ast-engine
|
|
2
2
|
// @layer infrastructure
|
|
3
3
|
|
|
4
|
-
const
|
|
4
|
+
const DEFAULT_LAYER_TAG = '@layer';
|
|
5
|
+
|
|
6
|
+
const escapeRegExp = (value: string): string => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
7
|
+
|
|
8
|
+
const createLayerCommentPattern = (tagName: string): RegExp =>
|
|
9
|
+
new RegExp(`^\\s*(?:\\/\\/|\\/\\*\\*?\\s*|\\*)\\s*${escapeRegExp(tagName)}\\s+(\\S+)`, 'm');
|
|
5
10
|
|
|
6
11
|
export type LayerCommentResult = {
|
|
7
12
|
readonly layerName: string | null;
|
|
8
13
|
};
|
|
9
14
|
|
|
10
|
-
export const parseLayerComment = (
|
|
11
|
-
|
|
15
|
+
export const parseLayerComment = (
|
|
16
|
+
sourceCode: string,
|
|
17
|
+
tagName: string = DEFAULT_LAYER_TAG
|
|
18
|
+
): LayerCommentResult => {
|
|
19
|
+
const match = sourceCode.match(createLayerCommentPattern(tagName));
|
|
12
20
|
|
|
13
21
|
if (!match) {
|
|
14
22
|
return { layerName: null };
|
|
@@ -1,15 +1,23 @@
|
|
|
1
1
|
// @unit biome-ast-engine
|
|
2
2
|
// @layer infrastructure
|
|
3
3
|
|
|
4
|
-
// カンマ区切り複数ユニット対応 + 複数行の
|
|
5
|
-
const
|
|
4
|
+
// カンマ区切り複数ユニット対応 + 複数行の metadata unit tag を収集、重複除去。
|
|
5
|
+
const DEFAULT_UNIT_TAG = '@unit';
|
|
6
|
+
|
|
7
|
+
const escapeRegExp = (value: string): string => value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
8
|
+
|
|
9
|
+
const createUnitCommentPattern = (tagName: string): RegExp =>
|
|
10
|
+
new RegExp(`^\\s*(?:\\/\\/|\\/\\*\\*?\\s*|\\*)\\s*${escapeRegExp(tagName)}\\s+(.+)`, 'gm');
|
|
6
11
|
|
|
7
12
|
export type UnitCommentResult = {
|
|
8
13
|
readonly unitNames: readonly string[];
|
|
9
14
|
};
|
|
10
15
|
|
|
11
|
-
export const parseUnitComment = (
|
|
12
|
-
|
|
16
|
+
export const parseUnitComment = (
|
|
17
|
+
sourceCode: string,
|
|
18
|
+
tagName: string = DEFAULT_UNIT_TAG
|
|
19
|
+
): UnitCommentResult => {
|
|
20
|
+
const matches = sourceCode.matchAll(createUnitCommentPattern(tagName));
|
|
13
21
|
const names: string[] = [];
|
|
14
22
|
|
|
15
23
|
for (const match of matches) {
|
package/scripts/harness/main.ts
CHANGED
|
@@ -490,6 +490,7 @@ function toArchitectureInput(resolvedConfig: HarnessConfigV2) {
|
|
|
490
490
|
preset: resolvedConfig.architecture.preset,
|
|
491
491
|
layers: resolvedConfig.architecture.layers,
|
|
492
492
|
allowedDependencies: resolvedConfig.architecture.allowedDependencies,
|
|
493
|
+
metadataTags: resolvedConfig.architecture.metadataTags,
|
|
493
494
|
};
|
|
494
495
|
}
|
|
495
496
|
|