2019-10-14 11:02:53 -04:00
|
|
|
package hcl2template
|
|
|
|
|
|
|
|
import (
|
|
|
|
"github.com/hashicorp/hcl/v2"
|
2019-12-17 05:25:56 -05:00
|
|
|
"github.com/hashicorp/hcl/v2/gohcl"
|
|
|
|
"github.com/hashicorp/hcl/v2/hclsyntax"
|
2019-10-14 11:02:53 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
const (
|
|
|
|
buildFromLabel = "from"
|
|
|
|
|
2019-12-17 05:25:56 -05:00
|
|
|
buildSourceLabel = "source"
|
2019-10-14 11:02:53 -04:00
|
|
|
|
2019-12-17 05:25:56 -05:00
|
|
|
buildProvisionerLabel = "provisioner"
|
|
|
|
|
|
|
|
buildPostProcessorLabel = "post-processor"
|
2019-10-14 11:02:53 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
var buildSchema = &hcl.BodySchema{
|
|
|
|
Blocks: []hcl.BlockHeaderSchema{
|
2019-12-17 05:25:56 -05:00
|
|
|
{Type: buildFromLabel, LabelNames: []string{"type"}},
|
|
|
|
{Type: buildProvisionerLabel, LabelNames: []string{"type"}},
|
|
|
|
{Type: buildPostProcessorLabel, LabelNames: []string{"type"}},
|
2019-10-14 11:02:53 -04:00
|
|
|
},
|
|
|
|
}
|
|
|
|
|
2019-12-17 05:25:56 -05:00
|
|
|
type BuildBlock struct {
|
|
|
|
ProvisionerBlocks []*ProvisionerBlock
|
2019-10-14 11:02:53 -04:00
|
|
|
|
2019-12-17 05:25:56 -05:00
|
|
|
PostProcessors []*PostProcessorBlock
|
2019-10-14 11:02:53 -04:00
|
|
|
|
2019-12-17 05:25:56 -05:00
|
|
|
Froms []SourceRef
|
2019-10-14 11:02:53 -04:00
|
|
|
|
|
|
|
HCL2Ref HCL2Ref
|
|
|
|
}
|
|
|
|
|
2019-12-17 05:25:56 -05:00
|
|
|
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)
|
2019-10-14 11:02:53 -04:00
|
|
|
|
2020-01-06 11:10:12 -05:00
|
|
|
if ref == NoSource ||
|
|
|
|
!hclsyntax.ValidIdentifier(ref.Type) ||
|
2019-12-17 05:25:56 -05:00
|
|
|
!hclsyntax.ValidIdentifier(ref.Name) {
|
|
|
|
diags = append(diags, &hcl.Diagnostic{
|
|
|
|
Severity: hcl.DiagError,
|
|
|
|
Summary: "Invalid " + sourceLabel + " reference",
|
2020-01-06 11:10:12 -05:00
|
|
|
Detail: "A " + sourceLabel + " type is made of three parts that are" +
|
|
|
|
"split by a dot `.`; each part must start with a letter and " +
|
2019-12-17 05:25:56 -05:00
|
|
|
"may contain only letters, digits, underscores, and dashes." +
|
|
|
|
"A valid source reference looks like: `source.type.name`",
|
2020-01-06 08:29:43 -05:00
|
|
|
Subject: block.DefRange.Ptr(),
|
2019-12-17 05:25:56 -05:00
|
|
|
})
|
|
|
|
continue
|
|
|
|
}
|
2019-10-14 11:02:53 -04:00
|
|
|
|
2019-12-17 05:25:56 -05:00
|
|
|
build.Froms = append(build.Froms, ref)
|
|
|
|
}
|
|
|
|
|
2020-01-06 08:29:43 -05:00
|
|
|
content, moreDiags := b.Config.Content(buildSchema)
|
|
|
|
diags = append(diags, moreDiags...)
|
2019-10-14 11:02:53 -04:00
|
|
|
for _, block := range content.Blocks {
|
|
|
|
switch block.Type {
|
2019-12-17 05:25:56 -05:00
|
|
|
case buildProvisionerLabel:
|
|
|
|
p, moreDiags := p.decodeProvisioner(block)
|
2019-10-14 11:02:53 -04:00
|
|
|
diags = append(diags, moreDiags...)
|
2019-12-17 05:25:56 -05:00
|
|
|
if moreDiags.HasErrors() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
build.ProvisionerBlocks = append(build.ProvisionerBlocks, p)
|
|
|
|
case buildPostProcessorLabel:
|
|
|
|
pp, moreDiags := p.decodePostProcessorGroup(block)
|
2019-10-14 11:02:53 -04:00
|
|
|
diags = append(diags, moreDiags...)
|
2019-12-17 05:25:56 -05:00
|
|
|
if moreDiags.HasErrors() {
|
|
|
|
continue
|
|
|
|
}
|
|
|
|
build.PostProcessors = append(build.PostProcessors, pp)
|
2019-10-14 11:02:53 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return build, diags
|
|
|
|
}
|