Infer artifact dependencies from configured inputs
This commit is contained in:
123
internal/config/artifact_dependencies.go
Normal file
123
internal/config/artifact_dependencies.go
Normal file
@@ -0,0 +1,123 @@
|
||||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"sort"
|
||||
"strings"
|
||||
|
||||
"gitea.maximumdirect.net/eric/narratio/internal/artifactpolicy"
|
||||
)
|
||||
|
||||
type artifactDependencyOrigin struct {
|
||||
explicitIndex int
|
||||
inputName string
|
||||
family string
|
||||
}
|
||||
|
||||
func finalizeArtifactDependencies(cfg *PipelineConfig) {
|
||||
if cfg == nil || cfg.Scriptorium == nil {
|
||||
return
|
||||
}
|
||||
for artifactName, artifact := range cfg.Scriptorium.Artifacts {
|
||||
priorOrigins := artifact.dependencyOrigins
|
||||
origins := make(map[string][]artifactDependencyOrigin)
|
||||
dependencies := make(map[string]struct{})
|
||||
family := ""
|
||||
if member, ok := cfg.familyCatalog.Members[artifactName]; ok {
|
||||
family = member.Family
|
||||
}
|
||||
|
||||
for index, dependency := range artifact.DependsOn {
|
||||
dependency = strings.TrimSpace(dependency)
|
||||
if prior, finalized := priorOrigins[dependency]; finalized {
|
||||
explicit := explicitOrigins(prior)
|
||||
if len(explicit) > 0 {
|
||||
dependencies[dependency] = struct{}{}
|
||||
origins[dependency] = append(origins[dependency], explicit...)
|
||||
}
|
||||
continue
|
||||
}
|
||||
dependencies[dependency] = struct{}{}
|
||||
origins[dependency] = append(origins[dependency], artifactDependencyOrigin{
|
||||
explicitIndex: index,
|
||||
family: family,
|
||||
})
|
||||
}
|
||||
|
||||
inputNames := make([]string, 0, len(artifact.Inputs))
|
||||
for inputName := range artifact.Inputs {
|
||||
inputNames = append(inputNames, inputName)
|
||||
}
|
||||
sort.Strings(inputNames)
|
||||
for _, inputName := range inputNames {
|
||||
descriptor, err := artifactpolicy.DescribeScriptoriumInputSource(artifact.Inputs[inputName].Source)
|
||||
if err != nil || descriptor.Source.Kind != artifactpolicy.SourceKindConfiguredArtifact {
|
||||
continue
|
||||
}
|
||||
dependency := descriptor.Source.ConfiguredKey
|
||||
dependencies[dependency] = struct{}{}
|
||||
origins[dependency] = append(origins[dependency], artifactDependencyOrigin{
|
||||
explicitIndex: -1,
|
||||
inputName: inputName,
|
||||
family: family,
|
||||
})
|
||||
}
|
||||
|
||||
artifact.DependsOn = sortedDependencyKeys(dependencies)
|
||||
artifact.dependencyOrigins = origins
|
||||
cfg.Scriptorium.Artifacts[artifactName] = artifact
|
||||
}
|
||||
}
|
||||
|
||||
func explicitOrigins(origins []artifactDependencyOrigin) []artifactDependencyOrigin {
|
||||
result := make([]artifactDependencyOrigin, 0, len(origins))
|
||||
for _, origin := range origins {
|
||||
if origin.explicitIndex >= 0 {
|
||||
result = append(result, origin)
|
||||
}
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
func sortedDependencyKeys(dependencies map[string]struct{}) []string {
|
||||
result := make([]string, 0, len(dependencies))
|
||||
for dependency := range dependencies {
|
||||
result = append(result, dependency)
|
||||
}
|
||||
sort.Strings(result)
|
||||
return result
|
||||
}
|
||||
|
||||
func dependencyOriginField(artifactName, dependency string, artifact ScriptoriumArtifactConfig) string {
|
||||
origins := artifact.dependencyOrigins[dependency]
|
||||
for _, origin := range origins {
|
||||
if origin.explicitIndex < 0 {
|
||||
continue
|
||||
}
|
||||
if origin.family != "" {
|
||||
return fmt.Sprintf("pipeline.scriptorium.artifact_families.%s.member_dependencies[%d]", origin.family, origin.explicitIndex)
|
||||
}
|
||||
return fmt.Sprintf("pipeline.scriptorium.artifacts.%s.depends_on[%d]", artifactName, origin.explicitIndex)
|
||||
}
|
||||
for _, origin := range origins {
|
||||
if origin.inputName == "" {
|
||||
continue
|
||||
}
|
||||
if origin.family != "" {
|
||||
return fmt.Sprintf("pipeline.scriptorium.artifact_families.%s.inputs.%s.source", origin.family, origin.inputName)
|
||||
}
|
||||
return fmt.Sprintf("pipeline.scriptorium.artifacts.%s.inputs.%s.source", artifactName, origin.inputName)
|
||||
}
|
||||
return fmt.Sprintf("pipeline.scriptorium.artifacts.%s.depends_on", artifactName)
|
||||
}
|
||||
|
||||
func cloneDependencyOrigins(in map[string][]artifactDependencyOrigin) map[string][]artifactDependencyOrigin {
|
||||
if in == nil {
|
||||
return nil
|
||||
}
|
||||
out := make(map[string][]artifactDependencyOrigin, len(in))
|
||||
for dependency, origins := range in {
|
||||
out[dependency] = append([]artifactDependencyOrigin(nil), origins...)
|
||||
}
|
||||
return out
|
||||
}
|
||||
Reference in New Issue
Block a user