a303f63a5e
Every finding now carries the source file and exact line number of the job key in its YAML file. Format: [ERROR] job "name" (file.yml:12): message. Pipeline-level findings (workflow rules, no stages) reference p.SourceFile. Cross-file include jobs (local, project, component) carry the include source as their File, set via Pipeline.SetJobOrigin after each ParseBytes call in the resolver. Line numbers come from the yaml.Node key node (exact job-name line) in a new document-level first pass in ParseBytes, replacing the previous map[string]yaml.Node approach which only gave value-node lines. Also: jobs that declare extends: but have no script after resolution now emit WARNING instead of ERROR. The script may come from a base in a remote include that was not fetched (no token, offline), making the error a false positive in common project setups. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
49 lines
1.2 KiB
Go
49 lines
1.2 KiB
Go
package linter
|
|
|
|
import (
|
|
"fmt"
|
|
|
|
"git.k3nny.fr/glint/internal/model"
|
|
)
|
|
|
|
func checkDependencies(p *model.Pipeline) []Finding {
|
|
stageIndex := make(map[string]int, len(p.Stages))
|
|
for i, s := range p.Stages {
|
|
stageIndex[s] = i
|
|
}
|
|
|
|
var findings []Finding
|
|
for name, job := range p.Jobs {
|
|
if len(job.Dependencies) == 0 {
|
|
continue
|
|
}
|
|
jobStageIdx, jobHasStage := stageIndex[job.Stage]
|
|
for _, dep := range job.Dependencies {
|
|
depJob, exists := p.Jobs[dep]
|
|
if !exists {
|
|
findings = append(findings, Finding{
|
|
Severity: Error,
|
|
Job: name,
|
|
File: job.File,
|
|
Line: job.Line,
|
|
Message: fmt.Sprintf("'dependencies' references unknown job %q", dep),
|
|
})
|
|
continue
|
|
}
|
|
if len(p.Stages) > 0 && jobHasStage && depJob.Stage != "" {
|
|
depIdx, depHasStage := stageIndex[depJob.Stage]
|
|
if depHasStage && depIdx >= jobStageIdx {
|
|
findings = append(findings, Finding{
|
|
Severity: Error,
|
|
Job: name,
|
|
File: job.File,
|
|
Line: job.Line,
|
|
Message: fmt.Sprintf("'dependencies' job %q must be in an earlier stage (in %q, current job is in %q)", dep, depJob.Stage, job.Stage),
|
|
})
|
|
}
|
|
}
|
|
}
|
|
}
|
|
return findings
|
|
}
|