packer-cn/hcl2template/types.build.go

100 lines
2.5 KiB
Go

package hcl2template
import (
"github.com/hashicorp/hcl/v2"
"github.com/hashicorp/hcl/v2/gohcl"
"github.com/hashicorp/hcl/v2/hclsyntax"
)
const (
buildFromLabel = "from"
buildSourceLabel = "source"
buildProvisionerLabel = "provisioner"
buildPostProcessorLabel = "post-processor"
)
var buildSchema = &hcl.BodySchema{
Blocks: []hcl.BlockHeaderSchema{
{Type: buildFromLabel, LabelNames: []string{"type"}},
{Type: buildProvisionerLabel, LabelNames: []string{"type"}},
{Type: buildPostProcessorLabel, LabelNames: []string{"type"}},
},
}
type BuildBlock struct {
ProvisionerBlocks []*ProvisionerBlock
PostProcessors []*PostProcessorBlock
Froms []SourceRef
HCL2Ref HCL2Ref
}
type Builds []*BuildBlock
func (p *Parser) decodeBuildConfig(block *hcl.Block) (*BuildBlock, hcl.Diagnostics) {
build := &BuildBlock{}
var b struct {
FromSources []string `hcl:"sources"`
Config hcl.Body `hcl:",remain"`
}
diags := gohcl.DecodeBody(block.Body, nil, &b)
for _, buildFrom := range b.FromSources {
ref := sourceRefFromString(buildFrom)
if ref == NoSource {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid " + sourceLabel + " reference",
Detail: "A " + sourceLabel + " type must start with a letter and " +
"may contain only letters, digits, underscores, and dashes." +
"A valid source reference looks like: `source.type.name`",
Subject: &block.LabelRanges[0],
})
continue
}
if !hclsyntax.ValidIdentifier(ref.Type) ||
!hclsyntax.ValidIdentifier(ref.Name) {
diags = append(diags, &hcl.Diagnostic{
Severity: hcl.DiagError,
Summary: "Invalid " + sourceLabel + " reference",
Detail: "A " + sourceLabel + " type must start with a letter and " +
"may contain only letters, digits, underscores, and dashes." +
"A valid source reference looks like: `source.type.name`",
Subject: &block.LabelRanges[0],
})
continue
}
build.Froms = append(build.Froms, ref)
}
content, diags := b.Config.Content(buildSchema)
for _, block := range content.Blocks {
switch block.Type {
case buildProvisionerLabel:
p, moreDiags := p.decodeProvisioner(block)
diags = append(diags, moreDiags...)
if moreDiags.HasErrors() {
continue
}
build.ProvisionerBlocks = append(build.ProvisionerBlocks, p)
case buildPostProcessorLabel:
pp, moreDiags := p.decodePostProcessorGroup(block)
diags = append(diags, moreDiags...)
if moreDiags.HasErrors() {
continue
}
build.PostProcessors = append(build.PostProcessors, pp)
}
}
return build, diags
}