Add versioned analysis fingerprint reconciliation
This commit is contained in:
@@ -761,7 +761,7 @@ func validateScriptorium(cfg *ScriptoriumConfig, notarius *NotariusConfig) error
|
||||
}
|
||||
}
|
||||
|
||||
if err := validateEnabledArtifactDependencyCycles(cfg.Artifacts); err != nil {
|
||||
if err := ValidateScriptoriumArtifactDependencies(cfg.Artifacts); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -983,38 +983,47 @@ func validatePathWithinRoot(fieldName, value, root string) error {
|
||||
return fmt.Errorf("%s must be under %s/", fieldName, normalizedRoot)
|
||||
}
|
||||
|
||||
func validateEnabledArtifactDependencyCycles(artifacts map[string]ScriptoriumArtifactConfig) error {
|
||||
// ValidateScriptoriumArtifactDependencies validates the configured dependency
|
||||
// graph independently of execution selection. Disabled artifacts remain valid
|
||||
// prerequisites for explicit selections and therefore participate in cycles.
|
||||
func ValidateScriptoriumArtifactDependencies(artifacts map[string]ScriptoriumArtifactConfig) error {
|
||||
if len(artifacts) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
enabled := make(map[string]struct{}, len(artifacts))
|
||||
graph := make(map[string][]string, len(artifacts))
|
||||
for name, cfg := range artifacts {
|
||||
if !cfg.Enabled {
|
||||
continue
|
||||
}
|
||||
enabled[name] = struct{}{}
|
||||
}
|
||||
for name, cfg := range artifacts {
|
||||
if !cfg.Enabled {
|
||||
continue
|
||||
if !artifactpolicy.IsConfiguredKey(name) {
|
||||
return fmt.Errorf("pipeline.scriptorium.artifacts keys must match ^[a-z][a-z0-9_]*$")
|
||||
}
|
||||
seen := make(map[string]struct{}, len(cfg.DependsOn))
|
||||
for _, dep := range cfg.DependsOn {
|
||||
trimmedDep := strings.TrimSpace(dep)
|
||||
if _, ok := enabled[trimmedDep]; ok {
|
||||
graph[name] = append(graph[name], trimmedDep)
|
||||
if trimmedDep == "" {
|
||||
return fmt.Errorf("pipeline.scriptorium.artifacts.%s.depends_on entries must be non-empty", name)
|
||||
}
|
||||
if _, ok := artifacts[trimmedDep]; !ok {
|
||||
return fmt.Errorf("pipeline.scriptorium.artifacts.%s dependency %q is not configured", name, dep)
|
||||
}
|
||||
if trimmedDep == name {
|
||||
return fmt.Errorf("pipeline.scriptorium.artifacts.%s.depends_on must not include itself", name)
|
||||
}
|
||||
if _, duplicate := seen[trimmedDep]; duplicate {
|
||||
continue
|
||||
}
|
||||
seen[trimmedDep] = struct{}{}
|
||||
graph[name] = append(graph[name], trimmedDep)
|
||||
}
|
||||
sort.Strings(graph[name])
|
||||
}
|
||||
|
||||
visiting := make(map[string]bool, len(enabled))
|
||||
visited := make(map[string]bool, len(enabled))
|
||||
visiting := make(map[string]bool, len(artifacts))
|
||||
visited := make(map[string]bool, len(artifacts))
|
||||
|
||||
var visit func(node string) error
|
||||
visit = func(node string) error {
|
||||
if visiting[node] {
|
||||
return fmt.Errorf("pipeline.scriptorium.artifacts enabled dependencies must not contain cycles")
|
||||
return fmt.Errorf("pipeline.scriptorium.artifacts dependencies must not contain cycles")
|
||||
}
|
||||
if visited[node] {
|
||||
return nil
|
||||
@@ -1030,7 +1039,12 @@ func validateEnabledArtifactDependencyCycles(artifacts map[string]ScriptoriumArt
|
||||
return nil
|
||||
}
|
||||
|
||||
for node := range enabled {
|
||||
nodes := make([]string, 0, len(artifacts))
|
||||
for node := range artifacts {
|
||||
nodes = append(nodes, node)
|
||||
}
|
||||
sort.Strings(nodes)
|
||||
for _, node := range nodes {
|
||||
if err := visit(node); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user