Skip to content
This repository has been archived by the owner on Nov 17, 2021. It is now read-only.

Detect imported extvars and TLAs via sentinel import path #271

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/root.go
Original file line number Diff line number Diff line change
Expand Up @@ -252,7 +252,7 @@ func JsonnetVM(cmd *cobra.Command) (*jsonnet.VM, error) {
return nil, fmt.Errorf("Unable to determine current working directory: %v", err)
}

vm.Importer(utils.MakeUniversalImporter(searchUrls))
vm.Importer(utils.MakeUniversalImporter(searchUrls, dirURL(cwd)))

for _, spec := range []struct {
flagName string
Expand Down
21 changes: 14 additions & 7 deletions utils/importer.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"net/http"
"net/url"
"os"
"regexp"
"strings"
"time"

Expand All @@ -19,8 +18,6 @@ import (

var errNotFound = errors.New("Not found")

var extVarKindRE = regexp.MustCompile("^<(?:extvar|top-level-arg):.+>$")

//go:generate go-bindata -nometadata -ignore .*_test\.|~$DOLLAR -pkg $GOPACKAGE -o bindata.go -prefix ../ ../lib/...
func newInternalFS(prefix string) http.FileSystem {
// Asset/AssetDir returns `fmt.Errorf("Asset %s not found")`,
Expand Down Expand Up @@ -62,7 +59,7 @@ A real-world example:
will be resolved as https://raw.githubusercontent.com/ksonnet/ksonnet-lib/master/ksonnet.beta.2/k8s.libsonnet
and downloaded from that location.
*/
func MakeUniversalImporter(searchURLs []*url.URL) jsonnet.Importer {
func MakeUniversalImporter(searchURLs []*url.URL, extVarBaseURL *url.URL) jsonnet.Importer {
// Reconstructed copy of http.DefaultTransport (to avoid
// modifying the default)
t := &http.Transport{
Expand All @@ -83,13 +80,15 @@ func MakeUniversalImporter(searchURLs []*url.URL) jsonnet.Importer {

return &universalImporter{
BaseSearchURLs: searchURLs,
extVarBaseURL: extVarBaseURL,
HTTPClient: &http.Client{Transport: t},
cache: map[string]jsonnet.Contents{},
}
}

type universalImporter struct {
BaseSearchURLs []*url.URL
extVarBaseURL *url.URL
HTTPClient *http.Client
cache map[string]jsonnet.Contents
}
Expand Down Expand Up @@ -154,9 +153,17 @@ func (importer *universalImporter) expandImportToCandidateURLs(importedFrom, imp
return []*url.URL{importedPathURL}, nil
}

importDirURL, err := url.Parse(importedFrom)
if err != nil {
return nil, fmt.Errorf("Invalid import dir %q: %v", importedFrom, err)
var importDirURL *url.URL
// Is the import coming from a source nominated by the "--ext-code-file," "--ext-str-file,"
// "--tla-code-file," or "--tla-str-file flags"? If so, resolve relative import paths against
// the specially configured base directory.
if importedFrom == "" {
importDirURL = importer.extVarBaseURL
} else {
importDirURL, err = url.Parse(importedFrom)
if err != nil {
return nil, fmt.Errorf("Invalid import dir %q", importedFrom)
}
}

candidateURLs := make([]*url.URL, 1, len(importer.BaseSearchURLs)+1)
Expand Down
15 changes: 15 additions & 0 deletions utils/importer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@ func TestExpandImportToCandidateURLs(t *testing.T) {
BaseSearchURLs: []*url.URL{
{Scheme: "file", Path: "/first/base/search/"},
},
extVarBaseURL: &url.URL{
Scheme: "file",
Path: "/current/working/dir/",
},
}

t.Run("Absolute URL in import statement yields a single candidate", func(t *testing.T) {
Expand All @@ -53,4 +57,15 @@ func TestExpandImportToCandidateURLs(t *testing.T) {
t.Errorf("Expected %v, got %v", expected, urls)
}
})

t.Run("Relative URL in import statement used as external variable or TLA yields candidate relative to base URL", func(t *testing.T) {
urls, _ := importer.expandImportToCandidateURLs("", "../sought.jsonnet")
expected := []*url.URL{
{Scheme: "file", Host: "", Path: "/current/working/sought.jsonnet"},
{Scheme: "file", Host: "", Path: "/first/base/sought.jsonnet"},
}
if !reflect.DeepEqual(urls, expected) {
t.Errorf("Expected %v, got %v", expected, urls)
}
})
}