feat(cli)!: subcommand CLI, graph tree mode, local include resolution

BREAKING CHANGES:
- `glint <file>` removed; use `glint check <file>`
- `--graph <mode>` removed; use `glint graph [mode]`
- `--graph-out` renamed to `--out` on `glint graph`

feat(cli): ruff-style subcommands — `glint check` and `glint graph [mode]`
feat(graph): `glint graph tree` — terminal job tree with context annotations
feat(graph): context flags (--branch/--tag/--source/--var) on `glint graph`
feat(resolver): recursive local include resolution from disk
fix(resolver): extends unknown base emits warning instead of fatal error
fix(model): script/before_script/after_script accept block scalar string form
test(linter): Samba project CI fixtures as integration tests
chore(build): fix .gitignore to not exclude cmd/glint/ directory
docs: update CHANGELOG, README, ROADMAP for v0.2.0

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-06-11 00:27:28 +02:00
parent aca37de2b1
commit 88f20165db
23 changed files with 1772 additions and 258 deletions
+13 -1
View File
@@ -88,7 +88,7 @@ func checkJob(name string, job model.Job, stageSet map[string]bool) []Finding {
// After extends resolution, a job with no script/run is an error.
// Exceptions: trigger jobs, pages jobs (use pages: keyword), and template jobs.
hasScript := len(job.Script) > 0 || job.Run != nil
hasScript := scriptNonEmpty(job.Script) || job.Run != nil
if !isTemplate && !isTrigger && job.Pages == nil && !hasScript {
findings = append(findings, Finding{
Severity: Error,
@@ -139,3 +139,15 @@ func checkJob(name string, job model.Job, stageSet map[string]bool) []Finding {
return findings
}
// scriptNonEmpty reports whether a script/before_script/after_script field
// (which may be a []any list or a plain string) is non-empty.
func scriptNonEmpty(v any) bool {
switch s := v.(type) {
case []any:
return len(s) > 0
case string:
return s != ""
}
return false
}