115 lines
3.0 KiB
Go
115 lines
3.0 KiB
Go
package artifacts
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
|
|
"gitea.maximumdirect.net/eric/narratio/internal/artifactpolicy"
|
|
"gitea.maximumdirect.net/eric/narratio/internal/config"
|
|
)
|
|
|
|
// PreviousArtifactRequirement describes one previous-session artifact dependency.
|
|
type PreviousArtifactRequirement struct {
|
|
Name string
|
|
Required bool
|
|
Sources []string
|
|
}
|
|
|
|
// CollectPreviousArtifactRequirements scans enabled Scriptorium artifacts and returns
|
|
// deduplicated previous-session artifact requirements in deterministic order.
|
|
func CollectPreviousArtifactRequirements(
|
|
artifactsCfg map[string]config.ScriptoriumArtifactConfig,
|
|
) []PreviousArtifactRequirement {
|
|
if len(artifactsCfg) == 0 {
|
|
return nil
|
|
}
|
|
|
|
artifactNames := sortedScriptoriumArtifactNames(artifactsCfg)
|
|
byName := map[string]PreviousArtifactRequirement{}
|
|
|
|
for _, artifactName := range artifactNames {
|
|
artifactCfg := artifactsCfg[artifactName]
|
|
if !artifactCfg.Enabled {
|
|
continue
|
|
}
|
|
|
|
inputNames := sortedScriptoriumInputKeys(artifactCfg.Inputs)
|
|
for _, inputName := range inputNames {
|
|
inputCfg := artifactCfg.Inputs[inputName]
|
|
descriptor, err := artifactpolicy.DescribeScriptoriumInputSource(inputCfg.Source)
|
|
if err != nil || descriptor.PreviousSession == nil {
|
|
continue
|
|
}
|
|
previousName := descriptor.PreviousSession.ConfiguredKey
|
|
|
|
location := fmt.Sprintf(
|
|
"pipeline.scriptorium.artifacts.%s.inputs.%s.source",
|
|
artifactName,
|
|
inputName,
|
|
)
|
|
requirement := byName[previousName]
|
|
requirement.Name = previousName
|
|
requirement.Required = requirement.Required || inputCfg.Required
|
|
requirement.Sources = append(requirement.Sources, location)
|
|
byName[previousName] = requirement
|
|
}
|
|
}
|
|
|
|
if len(byName) == 0 {
|
|
return nil
|
|
}
|
|
|
|
requirements := make([]PreviousArtifactRequirement, 0, len(byName))
|
|
for _, requirement := range byName {
|
|
requirement.Sources = dedupeAndSortStrings(requirement.Sources)
|
|
requirements = append(requirements, requirement)
|
|
}
|
|
sort.Slice(requirements, func(i, j int) bool {
|
|
return requirements[i].Name < requirements[j].Name
|
|
})
|
|
return requirements
|
|
}
|
|
|
|
func sortedScriptoriumArtifactNames(artifactsCfg map[string]config.ScriptoriumArtifactConfig) []string {
|
|
names := make([]string, 0, len(artifactsCfg))
|
|
for name := range artifactsCfg {
|
|
names = append(names, name)
|
|
}
|
|
sort.Strings(names)
|
|
return names
|
|
}
|
|
|
|
func sortedScriptoriumInputKeys(inputs map[string]config.ScriptoriumInputConfig) []string {
|
|
if len(inputs) == 0 {
|
|
return nil
|
|
}
|
|
names := make([]string, 0, len(inputs))
|
|
for name := range inputs {
|
|
names = append(names, name)
|
|
}
|
|
sort.Strings(names)
|
|
return names
|
|
}
|
|
|
|
func dedupeAndSortStrings(values []string) []string {
|
|
if len(values) == 0 {
|
|
return nil
|
|
}
|
|
seen := map[string]struct{}{}
|
|
out := make([]string, 0, len(values))
|
|
for _, value := range values {
|
|
trimmed := strings.TrimSpace(value)
|
|
if trimmed == "" {
|
|
continue
|
|
}
|
|
if _, ok := seen[trimmed]; ok {
|
|
continue
|
|
}
|
|
seen[trimmed] = struct{}{}
|
|
out = append(out, trimmed)
|
|
}
|
|
sort.Strings(out)
|
|
return out
|
|
}
|