mirror of
https://github.com/opentofu/opentofu.git
synced 2024-12-30 10:47:14 -06:00
ffe5f7c4e6
This is the frontend to the work-in-progress codepath for upgrading the source code for a module written for Terraform v0.11 or earlier to use the new syntax and idiom of v0.12. The underlying upgrade code is not yet complete as of this commit, and so the command is not yet very useful. We will continue to iterate on the upgrade code in subsequent commits.
101 lines
3.0 KiB
Go
101 lines
3.0 KiB
Go
package configs
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
|
|
"github.com/hashicorp/hcl2/hcl"
|
|
"github.com/hashicorp/hcl2/hclparse"
|
|
"github.com/spf13/afero"
|
|
)
|
|
|
|
// Parser is the main interface to read configuration files and other related
|
|
// files from disk.
|
|
//
|
|
// It retains a cache of all files that are loaded so that they can be used
|
|
// to create source code snippets in diagnostics, etc.
|
|
type Parser struct {
|
|
fs afero.Afero
|
|
p *hclparse.Parser
|
|
}
|
|
|
|
// NewParser creates and returns a new Parser that reads files from the given
|
|
// filesystem. If a nil filesystem is passed then the system's "real" filesystem
|
|
// will be used, via afero.OsFs.
|
|
func NewParser(fs afero.Fs) *Parser {
|
|
if fs == nil {
|
|
fs = afero.OsFs{}
|
|
}
|
|
|
|
return &Parser{
|
|
fs: afero.Afero{Fs: fs},
|
|
p: hclparse.NewParser(),
|
|
}
|
|
}
|
|
|
|
// LoadHCLFile is a low-level method that reads the file at the given path,
|
|
// parses it, and returns the hcl.Body representing its root. In many cases
|
|
// it is better to use one of the other Load*File methods on this type,
|
|
// which additionally decode the root body in some way and return a higher-level
|
|
// construct.
|
|
//
|
|
// If the file cannot be read at all -- e.g. because it does not exist -- then
|
|
// this method will return a nil body and error diagnostics. In this case
|
|
// callers may wish to ignore the provided error diagnostics and produce
|
|
// a more context-sensitive error instead.
|
|
//
|
|
// The file will be parsed using the HCL native syntax unless the filename
|
|
// ends with ".json", in which case the HCL JSON syntax will be used.
|
|
func (p *Parser) LoadHCLFile(path string) (hcl.Body, hcl.Diagnostics) {
|
|
src, err := p.fs.ReadFile(path)
|
|
|
|
if err != nil {
|
|
return nil, hcl.Diagnostics{
|
|
{
|
|
Severity: hcl.DiagError,
|
|
Summary: "Failed to read file",
|
|
Detail: fmt.Sprintf("The file %q could not be read.", path),
|
|
},
|
|
}
|
|
}
|
|
|
|
var file *hcl.File
|
|
var diags hcl.Diagnostics
|
|
switch {
|
|
case strings.HasSuffix(path, ".json"):
|
|
file, diags = p.p.ParseJSON(src, path)
|
|
default:
|
|
file, diags = p.p.ParseHCL(src, path)
|
|
}
|
|
|
|
// If the returned file or body is nil, then we'll return a non-nil empty
|
|
// body so we'll meet our contract that nil means an error reading the file.
|
|
if file == nil || file.Body == nil {
|
|
return hcl.EmptyBody(), diags
|
|
}
|
|
|
|
return file.Body, diags
|
|
}
|
|
|
|
// Sources returns a map of the cached source buffers for all files that
|
|
// have been loaded through this parser, with source filenames (as requested
|
|
// when each file was opened) as the keys.
|
|
func (p *Parser) Sources() map[string][]byte {
|
|
return p.p.Sources()
|
|
}
|
|
|
|
// ForceFileSource artificially adds source code to the cache of file sources,
|
|
// as if it had been loaded from the given filename.
|
|
//
|
|
// This should be used only in special situations where configuration is loaded
|
|
// some other way. Most callers should load configuration via methods of
|
|
// Parser, which will update the sources cache automatically.
|
|
func (p *Parser) ForceFileSource(filename string, src []byte) {
|
|
// We'll make a synthetic hcl.File here just so we can reuse the
|
|
// existing cache.
|
|
p.p.AddFile(filename, &hcl.File{
|
|
Body: hcl.EmptyBody(),
|
|
Bytes: src,
|
|
})
|
|
}
|