Centralize Scriptorium input source policy across config, analyze, and previous-cache
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package artifactpolicy
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"regexp"
|
||||
"strings"
|
||||
@@ -19,6 +20,11 @@ const (
|
||||
var configuredSourceRE = regexp.MustCompile(`^narratio\.artifact\.([a-z][a-z0-9_]*)$`)
|
||||
var previousSourceRE = regexp.MustCompile(`^narratio\.previous_session\.artifact\.([a-z][a-z0-9_]*)$`)
|
||||
|
||||
var (
|
||||
ErrUnsupportedScriptoriumInputSource = errors.New("unsupported scriptorium input source")
|
||||
ErrInvalidPreviousSessionSource = errors.New("invalid previous-session source format")
|
||||
)
|
||||
|
||||
type SourceKind string
|
||||
|
||||
const (
|
||||
@@ -34,6 +40,28 @@ type Source struct {
|
||||
ConfiguredKey string
|
||||
}
|
||||
|
||||
// ScriptoriumInputSourceDescriptor describes one validated Scriptorium input source.
|
||||
type ScriptoriumInputSourceDescriptor struct {
|
||||
Source Source
|
||||
PreviousSession *PreviousSessionSourceDescriptor
|
||||
}
|
||||
|
||||
// PreviousSessionSourceDescriptor describes one canonical previous-session input source.
|
||||
type PreviousSessionSourceDescriptor struct {
|
||||
SourceID string
|
||||
ConfiguredKey string
|
||||
ConfiguredSourceID string
|
||||
}
|
||||
|
||||
// UnknownConfiguredArtifactError reports a source that references an undefined configured artifact key.
|
||||
type UnknownConfiguredArtifactError struct {
|
||||
ConfiguredKey string
|
||||
}
|
||||
|
||||
func (e *UnknownConfiguredArtifactError) Error() string {
|
||||
return fmt.Sprintf("references unknown artifact %q", e.ConfiguredKey)
|
||||
}
|
||||
|
||||
// ConfiguredSourceID converts a configured artifact key into source id form.
|
||||
func ConfiguredSourceID(key string) string {
|
||||
return configuredSourcePrefix + strings.TrimSpace(key)
|
||||
@@ -83,6 +111,70 @@ func ClassifySource(source string) (Source, error) {
|
||||
return Source{}, fmt.Errorf("unsupported artifact source %q", source)
|
||||
}
|
||||
|
||||
// DescribeScriptoriumInputSource classifies one input source and returns descriptor
|
||||
// metadata used by config validation, analyze input resolution, and previous-cache planning.
|
||||
func DescribeScriptoriumInputSource(source string) (ScriptoriumInputSourceDescriptor, error) {
|
||||
trimmed := strings.TrimSpace(source)
|
||||
if trimmed == "" {
|
||||
return ScriptoriumInputSourceDescriptor{}, ErrUnsupportedScriptoriumInputSource
|
||||
}
|
||||
if strings.HasPrefix(trimmed, "narratio.previous_session.artifact") {
|
||||
descriptor, err := DescribePreviousSessionSource(trimmed)
|
||||
if err != nil {
|
||||
return ScriptoriumInputSourceDescriptor{}, err
|
||||
}
|
||||
return ScriptoriumInputSourceDescriptor{
|
||||
Source: Source{
|
||||
ID: descriptor.SourceID,
|
||||
Kind: SourceKindPreviousArtifact,
|
||||
ConfiguredKey: descriptor.ConfiguredKey,
|
||||
},
|
||||
PreviousSession: &descriptor,
|
||||
}, nil
|
||||
}
|
||||
|
||||
classified, err := ClassifySource(trimmed)
|
||||
if err != nil {
|
||||
return ScriptoriumInputSourceDescriptor{}, ErrUnsupportedScriptoriumInputSource
|
||||
}
|
||||
return ScriptoriumInputSourceDescriptor{Source: classified}, nil
|
||||
}
|
||||
|
||||
// DescribePreviousSessionSource validates a canonical previous-session source id
|
||||
// and returns both previous and configured-source vocabulary descriptors.
|
||||
func DescribePreviousSessionSource(source string) (PreviousSessionSourceDescriptor, error) {
|
||||
configuredKey, ok := ParsePreviousSessionSource(source)
|
||||
if !ok {
|
||||
return PreviousSessionSourceDescriptor{}, ErrInvalidPreviousSessionSource
|
||||
}
|
||||
return PreviousSessionSourceDescriptor{
|
||||
SourceID: PreviousSessionSourceID(configuredKey),
|
||||
ConfiguredKey: configuredKey,
|
||||
ConfiguredSourceID: ConfiguredSourceID(configuredKey),
|
||||
}, nil
|
||||
}
|
||||
|
||||
// PreviousSessionSourceDescriptorForConfiguredKey derives a previous-session source descriptor
|
||||
// from a configured artifact key.
|
||||
func PreviousSessionSourceDescriptorForConfiguredKey(configuredKey string) (PreviousSessionSourceDescriptor, error) {
|
||||
return DescribePreviousSessionSource(PreviousSessionSourceID(configuredKey))
|
||||
}
|
||||
|
||||
// ValidateInputConfiguredReference checks that configured/previous-session sources
|
||||
// reference configured artifacts known to the current Scriptorium config.
|
||||
func ValidateInputConfiguredReference(
|
||||
descriptor ScriptoriumInputSourceDescriptor,
|
||||
configured map[string]struct{},
|
||||
) error {
|
||||
switch descriptor.Source.Kind {
|
||||
case SourceKindConfiguredArtifact, SourceKindPreviousArtifact:
|
||||
if _, ok := configured[descriptor.Source.ConfiguredKey]; !ok {
|
||||
return &UnknownConfiguredArtifactError{ConfiguredKey: descriptor.Source.ConfiguredKey}
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// ValidatePublishSource validates that a source is publish-compatible and references a known configured artifact.
|
||||
func ValidatePublishSource(source string, configured map[string]string) (Source, error) {
|
||||
classified, err := ClassifySource(source)
|
||||
|
||||
Reference in New Issue
Block a user