Clarify pipeline composition envelope handling
This commit is contained in:
@@ -180,14 +180,24 @@ func splitPipelineCompositionEnvelope(document *compositionDocument) (*compositi
|
||||
if err := validateCompositionDocument(document, "root pipeline"); err != nil {
|
||||
return nil, pipelineCompositionEnvelope{}, err
|
||||
}
|
||||
root := cloneCompositionNode(document.root)
|
||||
envelope, fieldIndex, err := decodePipelineCompositionEnvelope(document.root)
|
||||
if err != nil {
|
||||
return nil, pipelineCompositionEnvelope{}, err
|
||||
}
|
||||
if err := validatePipelineCompositionEnvelope(envelope); err != nil {
|
||||
return nil, pipelineCompositionEnvelope{}, err
|
||||
}
|
||||
return pipelineBodyWithoutComposition(document, fieldIndex), envelope, nil
|
||||
}
|
||||
|
||||
func decodePipelineCompositionEnvelope(root *compositionNode) (pipelineCompositionEnvelope, int, error) {
|
||||
index := compositionFieldIndex(root.fields, "composition")
|
||||
if index < 0 {
|
||||
return &compositionDocument{root: root, sources: append([]string(nil), document.sources...)}, pipelineCompositionEnvelope{}, nil
|
||||
return pipelineCompositionEnvelope{}, -1, nil
|
||||
}
|
||||
envelopeNode := root.fields[index].value
|
||||
if envelopeNode.kind != yaml.MappingNode {
|
||||
return nil, pipelineCompositionEnvelope{}, fmt.Errorf(
|
||||
return pipelineCompositionEnvelope{}, -1, fmt.Errorf(
|
||||
"configuration source %s at composition: expected a mapping, got %s",
|
||||
formatCompositionSources(envelopeNode.sources), yamlKindName(envelopeNode.kind),
|
||||
)
|
||||
@@ -198,14 +208,14 @@ func splitPipelineCompositionEnvelope(document *compositionDocument) (*compositi
|
||||
switch field.key {
|
||||
case "imports":
|
||||
if field.value.kind != yaml.SequenceNode {
|
||||
return nil, pipelineCompositionEnvelope{}, fmt.Errorf(
|
||||
return pipelineCompositionEnvelope{}, -1, fmt.Errorf(
|
||||
"configuration source %s at composition.imports: expected a list, got %s",
|
||||
formatCompositionSources(field.value.sources), yamlKindName(field.value.kind),
|
||||
)
|
||||
}
|
||||
for itemIndex, item := range field.value.items {
|
||||
if item.kind != yaml.ScalarNode || item.tag != "!!str" {
|
||||
return nil, pipelineCompositionEnvelope{}, fmt.Errorf(
|
||||
return pipelineCompositionEnvelope{}, -1, fmt.Errorf(
|
||||
"configuration source %s at composition.imports[%d]: expected a string path",
|
||||
formatCompositionSources(item.sources), itemIndex,
|
||||
)
|
||||
@@ -214,54 +224,62 @@ func splitPipelineCompositionEnvelope(document *compositionDocument) (*compositi
|
||||
}
|
||||
case "default_profile":
|
||||
if field.value.kind != yaml.ScalarNode || field.value.tag != "!!str" {
|
||||
return nil, pipelineCompositionEnvelope{}, fmt.Errorf(
|
||||
return pipelineCompositionEnvelope{}, -1, fmt.Errorf(
|
||||
"configuration source %s at composition.default_profile: expected a string profile name",
|
||||
formatCompositionSources(field.value.sources),
|
||||
)
|
||||
}
|
||||
name, err := normalizePipelineProfileName(field.value.value, "composition.default_profile")
|
||||
if err != nil {
|
||||
return nil, pipelineCompositionEnvelope{}, err
|
||||
return pipelineCompositionEnvelope{}, -1, err
|
||||
}
|
||||
envelope.defaultProfile = &name
|
||||
case "profiles":
|
||||
if field.value.kind != yaml.MappingNode {
|
||||
return nil, pipelineCompositionEnvelope{}, fmt.Errorf(
|
||||
return pipelineCompositionEnvelope{}, -1, fmt.Errorf(
|
||||
"configuration source %s at composition.profiles: expected a mapping, got %s",
|
||||
formatCompositionSources(field.value.sources), yamlKindName(field.value.kind),
|
||||
)
|
||||
}
|
||||
if len(field.value.fields) == 0 {
|
||||
return nil, pipelineCompositionEnvelope{}, fmt.Errorf("composition.profiles must declare at least one named profile")
|
||||
return pipelineCompositionEnvelope{}, -1, fmt.Errorf("composition.profiles must declare at least one named profile")
|
||||
}
|
||||
for _, profileField := range field.value.fields {
|
||||
name, err := normalizePipelineProfileName(profileField.key, "composition.profiles profile name")
|
||||
if err != nil {
|
||||
return nil, pipelineCompositionEnvelope{}, err
|
||||
return pipelineCompositionEnvelope{}, -1, err
|
||||
}
|
||||
profile, err := parsePipelineProfileDeclaration(name, profileField.value)
|
||||
if err != nil {
|
||||
return nil, pipelineCompositionEnvelope{}, err
|
||||
return pipelineCompositionEnvelope{}, -1, err
|
||||
}
|
||||
envelope.profiles = append(envelope.profiles, profile)
|
||||
}
|
||||
default:
|
||||
return nil, pipelineCompositionEnvelope{}, fmt.Errorf(
|
||||
return pipelineCompositionEnvelope{}, -1, fmt.Errorf(
|
||||
"configuration source %s at composition.%s: unknown composition field %q",
|
||||
formatCompositionSources(field.value.sources), field.key, field.key,
|
||||
)
|
||||
}
|
||||
}
|
||||
return envelope, index, nil
|
||||
}
|
||||
|
||||
func validatePipelineCompositionEnvelope(envelope pipelineCompositionEnvelope) error {
|
||||
if envelope.defaultProfile != nil && !pipelineProfileDeclared(envelope.profiles, *envelope.defaultProfile) {
|
||||
return nil, pipelineCompositionEnvelope{}, fmt.Errorf(
|
||||
return fmt.Errorf(
|
||||
"composition.default_profile %q does not name a declared profile", *envelope.defaultProfile,
|
||||
)
|
||||
}
|
||||
root.fields = append(root.fields[:index], root.fields[index+1:]...)
|
||||
for fieldIndex := range root.fields {
|
||||
root.fields[fieldIndex].order = fieldIndex
|
||||
return nil
|
||||
}
|
||||
|
||||
func pipelineBodyWithoutComposition(document *compositionDocument, compositionIndex int) *compositionDocument {
|
||||
root := cloneCompositionNode(document.root)
|
||||
if compositionIndex >= 0 {
|
||||
root.fields = append(root.fields[:compositionIndex], root.fields[compositionIndex+1:]...)
|
||||
}
|
||||
return &compositionDocument{root: root, sources: append([]string(nil), document.sources...)}, envelope, nil
|
||||
return &compositionDocument{root: root, sources: append([]string(nil), document.sources...)}
|
||||
}
|
||||
|
||||
func parsePipelineProfileDeclaration(name string, node *compositionNode) (pipelineProfileDeclaration, error) {
|
||||
|
||||
Reference in New Issue
Block a user