@intentius/chant-lexicon-gitlab 0.0.4 → 0.0.8
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 +9 -46
- package/dist/integrity.json +5 -5
- package/dist/manifest.json +1 -1
- package/dist/meta.json +5 -0
- package/dist/skills/chant-gitlab.md +59 -0
- package/dist/types/index.d.ts +13 -0
- package/package.json +2 -2
- package/src/codegen/docs.ts +87 -441
- package/src/codegen/generate-lexicon.ts +1 -1
- package/src/codegen/package.ts +2 -0
- package/src/codegen/parse.test.ts +5 -4
- package/src/codegen/parse.ts +8 -10
- package/src/codegen/snapshot.test.ts +3 -3
- package/src/generated/index.d.ts +13 -0
- package/src/generated/index.ts +1 -0
- package/src/generated/lexicon-gitlab.json +5 -0
- package/src/import/parser.test.ts +3 -3
- package/src/import/parser.ts +12 -26
- package/src/lsp/completions.ts +2 -0
- package/src/lsp/hover.ts +2 -0
- package/src/plugin.test.ts +6 -8
- package/src/plugin.ts +73 -101
- package/src/serializer.test.ts +6 -6
- package/src/serializer.ts +1 -9
- package/src/validate.test.ts +13 -22
- package/src/validate.ts +17 -108
- package/dist/skills/gitlab-ci.md +0 -37
- package/src/codegen/rollback.ts +0 -26
package/src/validate.test.ts
CHANGED
|
@@ -6,38 +6,29 @@ import { fileURLToPath } from "url";
|
|
|
6
6
|
const basePath = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
7
7
|
|
|
8
8
|
describe("validate", () => {
|
|
9
|
-
test("
|
|
9
|
+
test("runs validation checks on current generated artifacts", async () => {
|
|
10
10
|
const result = await validate({ basePath });
|
|
11
|
-
expect(result.success).toBe(true);
|
|
12
11
|
expect(result.checks.length).toBeGreaterThan(0);
|
|
13
12
|
});
|
|
14
13
|
|
|
15
|
-
test("checks
|
|
14
|
+
test("checks lexicon JSON exists and parses", async () => {
|
|
16
15
|
const result = await validate({ basePath });
|
|
17
|
-
const
|
|
18
|
-
expect(
|
|
19
|
-
expect(
|
|
20
|
-
expect(checkNames).toContain("resource Workflow present");
|
|
21
|
-
expect(checkNames).toContain("property Artifacts present");
|
|
22
|
-
expect(checkNames).toContain("property Cache present");
|
|
23
|
-
expect(checkNames).toContain("property Image present");
|
|
16
|
+
const jsonCheck = result.checks.find((c) => c.name === "lexicon-json-exists");
|
|
17
|
+
expect(jsonCheck).toBeDefined();
|
|
18
|
+
expect(jsonCheck?.ok).toBe(true);
|
|
24
19
|
});
|
|
25
20
|
|
|
26
|
-
test("checks
|
|
21
|
+
test("checks types exist", async () => {
|
|
27
22
|
const result = await validate({ basePath });
|
|
28
|
-
const
|
|
29
|
-
expect(
|
|
30
|
-
|
|
31
|
-
expect(check.ok).toBe(true);
|
|
32
|
-
}
|
|
23
|
+
const typesCheck = result.checks.find((c) => c.name === "types-exist");
|
|
24
|
+
expect(typesCheck).toBeDefined();
|
|
25
|
+
expect(typesCheck?.ok).toBe(true);
|
|
33
26
|
});
|
|
34
27
|
|
|
35
|
-
test("checks
|
|
28
|
+
test("checks required names are present", async () => {
|
|
36
29
|
const result = await validate({ basePath });
|
|
37
|
-
const
|
|
38
|
-
expect(
|
|
39
|
-
|
|
40
|
-
expect(check.ok).toBe(true);
|
|
41
|
-
}
|
|
30
|
+
const requiredCheck = result.checks.find((c) => c.name === "required-names");
|
|
31
|
+
expect(requiredCheck).toBeDefined();
|
|
32
|
+
expect(requiredCheck?.ok).toBe(true);
|
|
42
33
|
});
|
|
43
34
|
});
|
package/src/validate.ts
CHANGED
|
@@ -1,125 +1,34 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
2
|
+
* Validate generated lexicon-gitlab artifacts.
|
|
3
3
|
*
|
|
4
|
-
*
|
|
5
|
-
*
|
|
4
|
+
* Thin wrapper around the core validation framework
|
|
5
|
+
* with GitLab-specific configuration.
|
|
6
6
|
*/
|
|
7
7
|
|
|
8
|
-
import {
|
|
9
|
-
import { join, dirname } from "path";
|
|
8
|
+
import { dirname } from "path";
|
|
10
9
|
import { fileURLToPath } from "url";
|
|
10
|
+
import { validateLexiconArtifacts, type ValidateResult } from "@intentius/chant/codegen/validate";
|
|
11
11
|
|
|
12
|
-
export
|
|
13
|
-
name: string;
|
|
14
|
-
ok: boolean;
|
|
15
|
-
error?: string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
export interface ValidateResult {
|
|
19
|
-
success: boolean;
|
|
20
|
-
checks: ValidateCheck[];
|
|
21
|
-
}
|
|
12
|
+
export type { ValidateCheck, ValidateResult } from "@intentius/chant/codegen/validate";
|
|
22
13
|
|
|
23
|
-
const
|
|
24
|
-
|
|
25
|
-
"Artifacts", "Cache", "Image", "Rule", "Retry",
|
|
14
|
+
const REQUIRED_NAMES = [
|
|
15
|
+
"Job", "Default", "Workflow",
|
|
16
|
+
"Artifacts", "Cache", "Image", "Service", "Rule", "Retry",
|
|
26
17
|
"AllowFailure", "Parallel", "Include", "Release",
|
|
27
18
|
"Environment", "Trigger", "AutoCancel",
|
|
28
19
|
];
|
|
29
20
|
|
|
30
21
|
/**
|
|
31
|
-
* Validate lexicon artifacts.
|
|
22
|
+
* Validate the generated lexicon-gitlab artifacts.
|
|
23
|
+
*
|
|
24
|
+
* @param opts.basePath - Override the package directory (defaults to lexicon-gitlab package root)
|
|
32
25
|
*/
|
|
33
26
|
export async function validate(opts?: { basePath?: string }): Promise<ValidateResult> {
|
|
34
27
|
const basePath = opts?.basePath ?? dirname(dirname(fileURLToPath(import.meta.url)));
|
|
35
|
-
const generatedDir = join(basePath, "src", "generated");
|
|
36
|
-
const checks: ValidateCheck[] = [];
|
|
37
|
-
|
|
38
|
-
// Check files exist
|
|
39
|
-
for (const file of ["lexicon-gitlab.json", "index.d.ts", "index.ts", "runtime.ts"]) {
|
|
40
|
-
const path = join(generatedDir, file);
|
|
41
|
-
checks.push({
|
|
42
|
-
name: `${file} exists`,
|
|
43
|
-
ok: existsSync(path),
|
|
44
|
-
error: existsSync(path) ? undefined : `File not found: ${path}`,
|
|
45
|
-
});
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
// Validate lexicon JSON structure
|
|
49
|
-
const lexiconPath = join(generatedDir, "lexicon-gitlab.json");
|
|
50
|
-
if (existsSync(lexiconPath)) {
|
|
51
|
-
try {
|
|
52
|
-
const content = readFileSync(lexiconPath, "utf-8");
|
|
53
|
-
const registry = JSON.parse(content);
|
|
54
|
-
const entries = Object.keys(registry);
|
|
55
|
-
|
|
56
|
-
// Check expected count
|
|
57
|
-
const expectedCount = EXPECTED_RESOURCES.length + EXPECTED_PROPERTIES.length;
|
|
58
|
-
checks.push({
|
|
59
|
-
name: `lexicon-gitlab.json has ${expectedCount} entries`,
|
|
60
|
-
ok: entries.length === expectedCount,
|
|
61
|
-
error: entries.length !== expectedCount
|
|
62
|
-
? `Expected ${expectedCount} entries, found ${entries.length}`
|
|
63
|
-
: undefined,
|
|
64
|
-
});
|
|
65
|
-
|
|
66
|
-
// Check resource entities present
|
|
67
|
-
for (const name of EXPECTED_RESOURCES) {
|
|
68
|
-
const entry = registry[name];
|
|
69
|
-
const ok = entry !== undefined && entry.kind === "resource";
|
|
70
|
-
checks.push({
|
|
71
|
-
name: `resource ${name} present`,
|
|
72
|
-
ok,
|
|
73
|
-
error: ok ? undefined : `Missing or invalid resource entry: ${name}`,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
// Check property entities present
|
|
78
|
-
for (const name of EXPECTED_PROPERTIES) {
|
|
79
|
-
const entry = registry[name];
|
|
80
|
-
const ok = entry !== undefined && entry.kind === "property";
|
|
81
|
-
checks.push({
|
|
82
|
-
name: `property ${name} present`,
|
|
83
|
-
ok,
|
|
84
|
-
error: ok ? undefined : `Missing or invalid property entry: ${name}`,
|
|
85
|
-
});
|
|
86
|
-
}
|
|
87
|
-
|
|
88
|
-
// Check all entries have required fields
|
|
89
|
-
for (const [name, entry] of Object.entries(registry)) {
|
|
90
|
-
const e = entry as Record<string, unknown>;
|
|
91
|
-
const hasRequired = e.resourceType && e.kind && e.lexicon === "gitlab";
|
|
92
|
-
checks.push({
|
|
93
|
-
name: `${name} has required fields`,
|
|
94
|
-
ok: !!hasRequired,
|
|
95
|
-
error: hasRequired ? undefined : `Entry ${name} missing required fields`,
|
|
96
|
-
});
|
|
97
|
-
}
|
|
98
|
-
} catch (err) {
|
|
99
|
-
checks.push({
|
|
100
|
-
name: "lexicon-gitlab.json is valid JSON",
|
|
101
|
-
ok: false,
|
|
102
|
-
error: `Parse error: ${err}`,
|
|
103
|
-
});
|
|
104
|
-
}
|
|
105
|
-
}
|
|
106
|
-
|
|
107
|
-
// Validate index.d.ts has class declarations
|
|
108
|
-
const dtsPath = join(generatedDir, "index.d.ts");
|
|
109
|
-
if (existsSync(dtsPath)) {
|
|
110
|
-
const dts = readFileSync(dtsPath, "utf-8");
|
|
111
|
-
for (const name of [...EXPECTED_RESOURCES, ...EXPECTED_PROPERTIES]) {
|
|
112
|
-
const has = dts.includes(`export declare class ${name}`);
|
|
113
|
-
checks.push({
|
|
114
|
-
name: `index.d.ts declares ${name}`,
|
|
115
|
-
ok: has,
|
|
116
|
-
error: has ? undefined : `Missing class declaration: ${name}`,
|
|
117
|
-
});
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
28
|
|
|
121
|
-
return {
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
29
|
+
return validateLexiconArtifacts({
|
|
30
|
+
lexiconJsonFilename: "lexicon-gitlab.json",
|
|
31
|
+
requiredNames: REQUIRED_NAMES,
|
|
32
|
+
basePath,
|
|
33
|
+
});
|
|
125
34
|
}
|
package/dist/skills/gitlab-ci.md
DELETED
|
@@ -1,37 +0,0 @@
|
|
|
1
|
-
---
|
|
2
|
-
name: gitlab-ci
|
|
3
|
-
description: GitLab CI/CD best practices and common patterns
|
|
4
|
-
---
|
|
5
|
-
|
|
6
|
-
# GitLab CI/CD with Chant
|
|
7
|
-
|
|
8
|
-
## Common Entity Types
|
|
9
|
-
|
|
10
|
-
- `Job` — Pipeline job definition
|
|
11
|
-
- `Default` — Default settings inherited by all jobs
|
|
12
|
-
- `Workflow` — Pipeline-level configuration
|
|
13
|
-
- `Artifacts` — Job artifact configuration
|
|
14
|
-
- `Cache` — Cache configuration
|
|
15
|
-
- `Image` — Docker image for a job
|
|
16
|
-
- `Rule` — Conditional execution rule
|
|
17
|
-
- `Environment` — Deployment environment
|
|
18
|
-
- `Trigger` — Trigger downstream pipeline
|
|
19
|
-
- `Include` — Include external CI configuration
|
|
20
|
-
|
|
21
|
-
## Predefined Variables
|
|
22
|
-
|
|
23
|
-
- `CI.CommitBranch` — Current branch name
|
|
24
|
-
- `CI.CommitSha` — Current commit SHA
|
|
25
|
-
- `CI.PipelineSource` — What triggered the pipeline
|
|
26
|
-
- `CI.ProjectPath` — Project path (group/project)
|
|
27
|
-
- `CI.Registry` — Container registry URL
|
|
28
|
-
- `CI.MergeRequestIid` — MR internal ID
|
|
29
|
-
|
|
30
|
-
## Best Practices
|
|
31
|
-
|
|
32
|
-
1. **Use stages** — Organize jobs into logical stages (build, test, deploy)
|
|
33
|
-
2. **Cache dependencies** — Cache node_modules, pip packages, etc.
|
|
34
|
-
3. **Use rules** — Prefer `rules:` over `only:/except:` for conditional execution
|
|
35
|
-
4. **Minimize artifacts** — Only preserve files needed by later stages
|
|
36
|
-
5. **Use includes** — Share common configuration across projects
|
|
37
|
-
6. **Set timeouts** — Prevent stuck jobs from blocking pipelines
|
package/src/codegen/rollback.ts
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Rollback and snapshot management for GitLab CI lexicon.
|
|
3
|
-
*
|
|
4
|
-
* Wraps the core rollback module with GitLab-specific artifact names.
|
|
5
|
-
*/
|
|
6
|
-
|
|
7
|
-
export type { ArtifactSnapshot, SnapshotInfo } from "@intentius/chant/codegen/rollback";
|
|
8
|
-
export {
|
|
9
|
-
snapshotArtifacts,
|
|
10
|
-
saveSnapshot,
|
|
11
|
-
restoreSnapshot,
|
|
12
|
-
listSnapshots,
|
|
13
|
-
} from "@intentius/chant/codegen/rollback";
|
|
14
|
-
|
|
15
|
-
/**
|
|
16
|
-
* GitLab-specific artifact filenames to snapshot.
|
|
17
|
-
*/
|
|
18
|
-
export const GITLAB_ARTIFACT_NAMES = ["lexicon-gitlab.json", "index.d.ts", "index.ts"];
|
|
19
|
-
|
|
20
|
-
/**
|
|
21
|
-
* Snapshot GitLab lexicon artifacts.
|
|
22
|
-
*/
|
|
23
|
-
export function snapshotGitLabArtifacts(generatedDir: string) {
|
|
24
|
-
const { snapshotArtifacts } = require("@intentius/chant/codegen/rollback");
|
|
25
|
-
return snapshotArtifacts(generatedDir, GITLAB_ARTIFACT_NAMES);
|
|
26
|
-
}
|