99 lines
3.1 KiB
Go
99 lines
3.1 KiB
Go
package artifacts
|
|
|
|
import (
|
|
"fmt"
|
|
"sort"
|
|
"strings"
|
|
|
|
"gitea.maximumdirect.net/eric/narratio/internal/artifactpolicy"
|
|
"gitea.maximumdirect.net/eric/narratio/internal/config"
|
|
)
|
|
|
|
// EffectiveArtifactSet is the resolved set of configured artifacts that an
|
|
// analyze invocation will execute.
|
|
type EffectiveArtifactSet struct {
|
|
keys []string
|
|
resolved bool
|
|
}
|
|
|
|
// ResolveEffectiveArtifactSet applies an explicit artifact selection when one
|
|
// is supplied; otherwise it selects the configured enabled artifacts.
|
|
func ResolveEffectiveArtifactSet(
|
|
configured map[string]ConfiguredArtifactDefinition,
|
|
selected []string,
|
|
) (EffectiveArtifactSet, error) {
|
|
configuredKeys := make(map[string]ConfiguredArtifactDefinition, len(configured))
|
|
for key, definition := range configured {
|
|
trimmed := strings.TrimSpace(key)
|
|
if !artifactpolicy.IsConfiguredKey(trimmed) {
|
|
return EffectiveArtifactSet{}, fmt.Errorf("configured artifact key %q must match ^[a-z][a-z0-9_]*$", key)
|
|
}
|
|
configuredKeys[trimmed] = definition
|
|
}
|
|
|
|
if len(selected) > 0 {
|
|
set := make(map[string]struct{}, len(selected))
|
|
for _, key := range selected {
|
|
trimmed := strings.TrimSpace(key)
|
|
if !artifactpolicy.IsConfiguredKey(trimmed) {
|
|
return EffectiveArtifactSet{}, fmt.Errorf("selected artifact key %q must match ^[a-z][a-z0-9_]*$", key)
|
|
}
|
|
if _, ok := configuredKeys[trimmed]; !ok {
|
|
return EffectiveArtifactSet{}, fmt.Errorf("selected artifact %q is not configured", trimmed)
|
|
}
|
|
set[trimmed] = struct{}{}
|
|
}
|
|
return newEffectiveArtifactSet(set), nil
|
|
}
|
|
|
|
set := make(map[string]struct{}, len(configuredKeys))
|
|
for key, definition := range configuredKeys {
|
|
if definition.Enabled {
|
|
set[key] = struct{}{}
|
|
}
|
|
}
|
|
return newEffectiveArtifactSet(set), nil
|
|
}
|
|
|
|
// ConfiguredArtifactDefinitions converts Scriptorium configuration into the
|
|
// definition form used by the runtime catalog.
|
|
func ConfiguredArtifactDefinitions(items map[string]config.ScriptoriumArtifactConfig) map[string]ConfiguredArtifactDefinition {
|
|
if len(items) == 0 {
|
|
return nil
|
|
}
|
|
definitions := make(map[string]ConfiguredArtifactDefinition, len(items))
|
|
for key, item := range items {
|
|
definitions[key] = ConfiguredArtifactDefinition{
|
|
Enabled: item.Enabled,
|
|
OutputPath: item.OutputPath,
|
|
}
|
|
}
|
|
return definitions
|
|
}
|
|
|
|
// Keys returns the selected configured artifact keys in deterministic order.
|
|
func (s EffectiveArtifactSet) Keys() []string {
|
|
return append([]string(nil), s.keys...)
|
|
}
|
|
|
|
// Includes reports whether a configured artifact belongs to the effective set.
|
|
func (s EffectiveArtifactSet) Includes(key string) bool {
|
|
trimmed := strings.TrimSpace(key)
|
|
index := sort.SearchStrings(s.keys, trimmed)
|
|
return index < len(s.keys) && s.keys[index] == trimmed
|
|
}
|
|
|
|
// Resolved reports whether the set was created by ResolveEffectiveArtifactSet.
|
|
func (s EffectiveArtifactSet) Resolved() bool {
|
|
return s.resolved
|
|
}
|
|
|
|
func newEffectiveArtifactSet(set map[string]struct{}) EffectiveArtifactSet {
|
|
keys := make([]string, 0, len(set))
|
|
for key := range set {
|
|
keys = append(keys, key)
|
|
}
|
|
sort.Strings(keys)
|
|
return EffectiveArtifactSet{keys: keys, resolved: true}
|
|
}
|