Repository: grafana/tanka
Pull request #856 (2023-05-04 19:41:24)

`tool importers`: Local vendor should override global vendor
Currently, if a file is pulled from a local vendor overriding a global vendor, the global vendor will still show up as an imported file 
This fixes the issue by removing the global vendored lib as imported files when there exists a locally vendored file with the same name

github-actions[bot]: [PR Preview Action](https://github.com/rossjrw/pr-preview-action) b7b1c7151d20c3a7bedd1b6d95a347dc77ddc2a1
:---:
:rocket: Deployed preview to https://grafana.github.io/tanka/pr-preview/pr-856/
on branch [`gh-pages`](https://github.com/grafana/tanka/tree/gh-pages) at 2023-05-04 19:45 UTC
<!-- Sticky Pull Request Commentpr-preview -->

Patch:
diff --git a/pkg/jsonnet/find_importers.go b/pkg/jsonnet/find_importers.go
index 50c5d8fc..ac8bba9f 100644
--- a/pkg/jsonnet/find_importers.go
+++ b/pkg/jsonnet/find_importers.go
@@ -220,8 +220,27 @@ func findImporters(root string, searchForFile string, chain map[string]struct{})
 		}
 	}
 
-	importersCache[key] = importers
-	return importers, nil
+	// If we've found a vendored file, check that it's not overridden by a vendored file in the environment root
+	// In that case, we only want to keep the environment vendored file
+	var filteredImporters []string
+	rootVendor := filepath.Join(root, "vendor")
+	if strings.HasPrefix(searchForFile, rootVendor) {
+		for _, importer := range importers {
+			relativePath, err := filepath.Rel(rootVendor, searchForFile)
+			if err != nil {
+				return nil, err
+			}
+			vendoredFileInEnvironment := filepath.Join(filepath.Dir(importer), "vendor", relativePath)
+			if _, ok := jsonnetFilesCache[root][vendoredFileInEnvironment]; !ok {
+				filteredImporters = append(filteredImporters, importer)
+			}
+		}
+	} else {
+		filteredImporters = importers
+	}
+
+	importersCache[key] = filteredImporters
+	return filteredImporters, nil
 }
 
 func createJsonnetFileCache(root string) (map[string]*cachedJsonnetFile, error) {


Test patch:
diff --git a/pkg/jsonnet/find_importers_test.go b/pkg/jsonnet/find_importers_test.go
index 58080276..c3d03722 100644
--- a/pkg/jsonnet/find_importers_test.go
+++ b/pkg/jsonnet/find_importers_test.go
@@ -5,6 +5,7 @@ import (
 	"path/filepath"
 	"testing"
 
+	"github.com/grafana/tanka/pkg/jsonnet/jpath"
 	"github.com/stretchr/testify/require"
 )
 
@@ -31,8 +32,9 @@ func findImportersTestCases(t testing.TB) []findImportersTestCase {
 
 	return []findImportersTestCase{
 		{
-			name:  "no files",
-			files: []string{},
+			name:              "no files",
+			files:             []string{},
+			expectedImporters: nil,
 		},
 		{
 			name:        "invalid file",
@@ -118,6 +120,22 @@ func findImportersTestCases(t testing.TB) []findImportersTestCase {
 				absPath(t, "testdata/findImporters/environments/relative-import/main.jsonnet"),
 			},
 		},
+		{
+			name: "vendor override in env: override vendor used",
+			files: []string{
+				"testdata/findImporters/environments/vendor-override-in-env/vendor/vendor-override-in-env/main.libsonnet",
+			},
+			expectedImporters: []string{
+				absPath(t, "testdata/findImporters/environments/vendor-override-in-env/main.jsonnet"),
+			},
+		},
+		{
+			name: "vendor override in env: global vendor unused",
+			files: []string{
+				"testdata/findImporters/vendor/vendor-override-in-env/main.libsonnet",
+			},
+			expectedImporters: nil,
+		},
 	}
 }
 
@@ -129,6 +147,10 @@ func TestFindImportersForFiles(t *testing.T) {
 	require.NoError(t, err)
 	require.NotEmpty(t, files)
 	for _, file := range files {
+		// Skip non-main files
+		if filepath.Base(file) != jpath.DefaultEntrypoint {
+			continue
+		}
 		_, err := EvaluateFile(file, Opts{})
 		require.NoError(t, err, "failed to eval %s", file)
 	}
diff --git a/pkg/jsonnet/testdata/findImporters/environments/vendor-override-in-env/main.jsonnet b/pkg/jsonnet/testdata/findImporters/environments/vendor-override-in-env/main.jsonnet
new file mode 100644
index 00000000..b1ae741f
--- /dev/null
+++ b/pkg/jsonnet/testdata/findImporters/environments/vendor-override-in-env/main.jsonnet
@@ -0,0 +1,4 @@
+{
+  assert self.imported.test == 'env-vendor',
+  imported: (import 'vendor-override-in-env/main.libsonnet'),
+}
diff --git a/pkg/jsonnet/testdata/findImporters/environments/vendor-override-in-env/vendor/vendor-override-in-env/main.libsonnet b/pkg/jsonnet/testdata/findImporters/environments/vendor-override-in-env/vendor/vendor-override-in-env/main.libsonnet
new file mode 100644
index 00000000..3bb0e285
--- /dev/null
+++ b/pkg/jsonnet/testdata/findImporters/environments/vendor-override-in-env/vendor/vendor-override-in-env/main.libsonnet
@@ -0,0 +1,3 @@
+{
+  test: 'env-vendor',
+}
diff --git a/pkg/jsonnet/testdata/findImporters/vendor/vendor-override-in-env/main.libsonnet b/pkg/jsonnet/testdata/findImporters/vendor/vendor-override-in-env/main.libsonnet
new file mode 100644
index 00000000..54fd76a4
--- /dev/null
+++ b/pkg/jsonnet/testdata/findImporters/vendor/vendor-override-in-env/main.libsonnet
@@ -0,0 +1,3 @@
+{
+  test: 'global-vendor',
+}