Files
narratio/internal/config/artifact_dependencies.go

124 lines
3.7 KiB
Go

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
}