summaryrefslogtreecommitdiff
path: root/ext/include/file_resolver.go
blob: 382c6d4c2686265802df13db5dc59e790b16da45 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
package include

import (
	"path/filepath"
	"strings"

	"github.com/hashicorp/hcl/v2/hcl"
	"github.com/hashicorp/hcl/v2/hclparse"
)

// FileResolver creates and returns a Resolver that interprets include paths
// as filesystem paths relative to the calling configuration file.
//
// When an include is requested, the source filename of the calling config
// file is first interpreted relative to the given basePath, and then the
// path given in configuration is interpreted relative to the resulting
// absolute caller configuration directory.
//
// This resolver assumes that all calling bodies are loaded from local files
// and that the paths to these files were correctly provided to the parser,
// either absolute or relative to the given basePath.
//
// If the path given in configuration ends with ".json" then the referenced
// file is interpreted as JSON. Otherwise, it is interpreted as HCL native
// syntax.
func FileResolver(baseDir string, parser *hclparse.Parser) Resolver {
	return &fileResolver{
		BaseDir: baseDir,
		Parser:  parser,
	}
}

type fileResolver struct {
	BaseDir string
	Parser  *hclparse.Parser
}

func (r fileResolver) ResolveBodyPath(path string, refRange hcl.Range) (hcl.Body, hcl.Diagnostics) {
	callerFile := filepath.Join(r.BaseDir, refRange.Filename)
	callerDir := filepath.Dir(callerFile)
	targetFile := filepath.Join(callerDir, path)

	var f *hcl.File
	var diags hcl.Diagnostics
	if strings.HasSuffix(targetFile, ".json") {
		f, diags = r.Parser.ParseJSONFile(targetFile)
	} else {
		f, diags = r.Parser.ParseHCLFile(targetFile)
	}

	return f.Body, diags
}