github.com/pdmccormick/importable-docker-buildx@v0.0.0-20240426161518-e47091289030/bake/hcl.go (about)

     1  package bake
     2  
     3  import (
     4  	"strings"
     5  
     6  	"github.com/hashicorp/hcl/v2"
     7  	"github.com/hashicorp/hcl/v2/hclparse"
     8  	"github.com/moby/buildkit/solver/errdefs"
     9  	"github.com/moby/buildkit/solver/pb"
    10  )
    11  
    12  func ParseHCLFile(dt []byte, fn string) (*hcl.File, bool, error) {
    13  	var err error
    14  	if strings.HasSuffix(fn, ".json") {
    15  		f, diags := hclparse.NewParser().ParseJSON(dt, fn)
    16  		if diags.HasErrors() {
    17  			err = diags
    18  		}
    19  		return f, true, err
    20  	}
    21  	if strings.HasSuffix(fn, ".hcl") {
    22  		f, diags := hclparse.NewParser().ParseHCL(dt, fn)
    23  		if diags.HasErrors() {
    24  			err = diags
    25  		}
    26  		return f, true, err
    27  	}
    28  	f, diags := hclparse.NewParser().ParseHCL(dt, fn+".hcl")
    29  	if diags.HasErrors() {
    30  		f, diags2 := hclparse.NewParser().ParseJSON(dt, fn+".json")
    31  		if !diags2.HasErrors() {
    32  			return f, true, nil
    33  		}
    34  		return nil, false, diags
    35  	}
    36  	return f, true, nil
    37  }
    38  
    39  func formatHCLError(err error, files []File) error {
    40  	if err == nil {
    41  		return nil
    42  	}
    43  	diags, ok := err.(hcl.Diagnostics)
    44  	if !ok {
    45  		return err
    46  	}
    47  	for _, d := range diags {
    48  		if d.Severity != hcl.DiagError {
    49  			continue
    50  		}
    51  		if d.Subject != nil {
    52  			var dt []byte
    53  			for _, f := range files {
    54  				if d.Subject.Filename == f.Name {
    55  					dt = f.Data
    56  					break
    57  				}
    58  			}
    59  			src := errdefs.Source{
    60  				Info: &pb.SourceInfo{
    61  					Filename: d.Subject.Filename,
    62  					Data:     dt,
    63  				},
    64  				Ranges: []*pb.Range{toErrRange(d.Subject)},
    65  			}
    66  			err = errdefs.WithSource(err, src)
    67  			break
    68  		}
    69  	}
    70  	return err
    71  }
    72  
    73  func toErrRange(in *hcl.Range) *pb.Range {
    74  	return &pb.Range{
    75  		Start: pb.Position{Line: int32(in.Start.Line), Character: int32(in.Start.Column)},
    76  		End:   pb.Position{Line: int32(in.End.Line), Character: int32(in.End.Column)},
    77  	}
    78  }