github.com/grafana/tanka@v0.26.1-0.20240506093700-c22cfc35c21a/pkg/jsonnet/implementations/goimpl/importer.go (about) 1 package goimpl 2 3 import ( 4 "path/filepath" 5 6 jsonnet "github.com/google/go-jsonnet" 7 ) 8 9 const locationInternal = "<internal>" 10 11 // extendedImporter wraps jsonnet.FileImporter to add additional functionality: 12 // - `import "file.yaml"` 13 // - `import "tk"` 14 type extendedImporter struct { 15 loaders []importLoader // for loading jsonnet from somewhere. First one that returns non-nil is used 16 processors []importProcessor // for post-processing (e.g. yaml -> json) 17 } 18 19 // importLoader are executed before the actual importing. If they return 20 // something, this value is used. 21 type importLoader func(importedFrom, importedPath string) (c *jsonnet.Contents, foundAt string, err error) 22 23 // importProcessor are executed after the file import and may modify the result 24 // further 25 type importProcessor func(contents, foundAt string) (c *jsonnet.Contents, err error) 26 27 // newExtendedImporter returns a new instance of ExtendedImporter with the 28 // correct jpaths set up 29 func newExtendedImporter(jpath []string) *extendedImporter { 30 return &extendedImporter{ 31 loaders: []importLoader{ 32 tkLoader, 33 newFileLoader(&jsonnet.FileImporter{ 34 JPaths: jpath, 35 })}, 36 processors: []importProcessor{}, 37 } 38 } 39 40 // Import implements the functionality offered by the ExtendedImporter 41 func (i *extendedImporter) Import(importedFrom, importedPath string) (contents jsonnet.Contents, foundAt string, err error) { 42 // load using loader 43 for _, loader := range i.loaders { 44 c, f, err := loader(importedFrom, importedPath) 45 if err != nil { 46 return jsonnet.Contents{}, "", err 47 } 48 if c != nil { 49 contents = *c 50 foundAt = f 51 break 52 } 53 } 54 55 // check if needs postprocessing 56 for _, processor := range i.processors { 57 c, err := processor(contents.String(), foundAt) 58 if err != nil { 59 return jsonnet.Contents{}, "", err 60 } 61 if c != nil { 62 contents = *c 63 break 64 } 65 } 66 67 return contents, foundAt, nil 68 } 69 70 // tkLoader provides `tk.libsonnet` from memory (builtin) 71 func tkLoader(_, importedPath string) (contents *jsonnet.Contents, foundAt string, err error) { 72 if importedPath != "tk" { 73 return nil, "", nil 74 } 75 76 return &tkLibsonnet, filepath.Join(locationInternal, "tk.libsonnet"), nil 77 } 78 79 // newFileLoader returns an importLoader that uses jsonnet.FileImporter to source 80 // files from the local filesystem 81 func newFileLoader(fi *jsonnet.FileImporter) importLoader { 82 return func(importedFrom, importedPath string) (contents *jsonnet.Contents, foundAt string, err error) { 83 var c jsonnet.Contents 84 c, foundAt, err = fi.Import(importedFrom, importedPath) 85 return &c, foundAt, err 86 } 87 }