Skip to content

Commit 8012c65

Browse files
committed
fix(cli/jsonnet): do static import analysis on environment level
All of our current commands take environments, only the import analysis works on plain files ... this has no benefit, it actually makes the implementation harder, as we cannot use stable paths there. Switches to environments as the target.
1 parent f8c7660 commit 8012c65

File tree

4 files changed

+58
-28
lines changed

4 files changed

+58
-28
lines changed

cmd/tk/tool.go

+18-9
Original file line numberDiff line numberDiff line change
@@ -51,9 +51,12 @@ func jpathCmd() *cobra.Command {
5151

5252
func importsCmd() *cobra.Command {
5353
cmd := &cobra.Command{
54-
Use: "imports <file>",
55-
Short: "list all transitive imports of a file",
54+
Use: "imports <directory>",
55+
Short: "list all transitive imports of an environment",
5656
Args: cobra.ExactArgs(1),
57+
Annotations: map[string]string{
58+
"args": "baseDir",
59+
},
5760
Run: func(cmd *cobra.Command, args []string) {
5861
var modFiles []string
5962
if cmd.Flag("check").Changed {
@@ -64,22 +67,28 @@ func importsCmd() *cobra.Command {
6467
}
6568
}
6669

67-
f, err := filepath.Abs(args[0])
70+
dir, err := filepath.Abs(args[0])
6871
if err != nil {
69-
log.Fatalln("Opening file:", err)
72+
log.Fatalln("Loading environment:", err)
7073
}
7174

72-
deps, err := jsonnet.TransitiveImports(f)
75+
fi, err := os.Stat(dir)
7376
if err != nil {
74-
log.Fatalln("resolving imports:", err)
77+
log.Fatalln("Loading environment:", err)
78+
}
79+
80+
if !fi.IsDir() {
81+
log.Fatalln("The argument must be an environment's directory, but this does not seem to be the case.")
7582
}
7683

77-
// include main.jsonnet as well
78-
deps = append(deps, f)
84+
deps, err := jsonnet.TransitiveImports(dir)
85+
if err != nil {
86+
log.Fatalln("Resolving imports:", err)
87+
}
7988

8089
root, err := gitRoot()
8190
if err != nil {
82-
log.Fatalln("invoking git:", err)
91+
log.Fatalln("Invoking git:", err)
8392
}
8493
if modFiles != nil {
8594
for _, m := range modFiles {

pkg/jsonnet/imports.go

+26-8
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package jsonnet
33
import (
44
"io/ioutil"
55
"path/filepath"
6+
"sort"
67

78
jsonnet "github.com/google/go-jsonnet"
89
"github.com/google/go-jsonnet/ast"
@@ -13,14 +14,21 @@ import (
1314
"github.com/grafana/tanka/pkg/jsonnet/native"
1415
)
1516

16-
// TransitiveImports returns all recursive imports of a file
17-
func TransitiveImports(filename string) ([]string, error) {
18-
sonnet, err := ioutil.ReadFile(filename)
17+
// TransitiveImports returns all recursive imports of an environment
18+
func TransitiveImports(dir string) ([]string, error) {
19+
dir, err := filepath.Abs(dir)
20+
if err != nil {
21+
return nil, err
22+
}
23+
24+
mainFile := filepath.Join(dir, "main.jsonnet")
25+
26+
sonnet, err := ioutil.ReadFile(mainFile)
1927
if err != nil {
2028
return nil, errors.Wrap(err, "opening file")
2129
}
2230

23-
jpath, _, _, err := jpath.Resolve(filepath.Dir(filename))
31+
jpath, _, rootDir, err := jpath.Resolve(dir)
2432
if err != nil {
2533
return nil, errors.Wrap(err, "resolving JPATH")
2634
}
@@ -37,9 +45,17 @@ func TransitiveImports(filename string) ([]string, error) {
3745
}
3846

3947
imports := make([]string, 0)
40-
err = importRecursive(&imports, vm, node, "main.jsonnet")
48+
if err = importRecursive(&imports, vm, node, "main.jsonnet"); err != nil {
49+
return nil, err
50+
}
51+
52+
uniq := append(uniqueStringSlice(imports), mainFile)
53+
for i := range uniq {
54+
uniq[i], _ = filepath.Rel(rootDir, uniq[i])
55+
}
56+
sort.Strings(uniq)
4157

42-
return uniqueStringSlice(imports), err
58+
return uniq, nil
4359
}
4460

4561
// importRecursive takes a Jsonnet VM and recursively imports the AST. Every
@@ -56,7 +72,8 @@ func importRecursive(list *[]string, vm *jsonnet.VM, node ast.Node, currentPath
5672
return errors.Wrap(err, "importing jsonnet")
5773
}
5874

59-
*list = append(*list, foundAt)
75+
abs, _ := filepath.Abs(foundAt)
76+
*list = append(*list, abs)
6077

6178
if err := importRecursive(list, vm, contents, foundAt); err != nil {
6279
return err
@@ -71,7 +88,8 @@ func importRecursive(list *[]string, vm *jsonnet.VM, node ast.Node, currentPath
7188
return errors.Wrap(err, "importing string")
7289
}
7390

74-
*list = append(*list, foundAt)
91+
abs, _ := filepath.Abs(foundAt)
92+
*list = append(*list, abs)
7593

7694
// neither `import` nor `importstr`, probably object or similar: try children
7795
default:

pkg/jsonnet/imports_test.go

+10-9
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package jsonnet
22

33
import (
4+
"fmt"
45
"testing"
56

67
"github.com/stretchr/testify/assert"
@@ -10,15 +11,15 @@ import (
1011
// TestTransitiveImports checks that TransitiveImports is able to report all
1112
// recursive imports of a file
1213
func TestTransitiveImports(t *testing.T) {
13-
imports, err := TransitiveImports("testdata/main.jsonnet")
14+
imports, err := TransitiveImports("testdata")
15+
fmt.Println(imports)
1416
require.NoError(t, err)
15-
assert.ElementsMatch(t, []string{
16-
"testdata/trees.jsonnet",
17-
18-
"testdata/trees/apple.jsonnet",
19-
"testdata/trees/cherry.jsonnet",
20-
"testdata/trees/peach.jsonnet",
21-
22-
"testdata/trees/generic.libsonnet",
17+
assert.Equal(t, []string{
18+
"main.jsonnet",
19+
"trees.jsonnet",
20+
"trees/apple.jsonnet",
21+
"trees/cherry.jsonnet",
22+
"trees/generic.libsonnet",
23+
"trees/peach.jsonnet",
2324
}, imports)
2425
}

pkg/kubernetes/kubernetes_test.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@ func TestReconcile(t *testing.T) {
8888

8989
for _, c := range tests {
9090
t.Run(c.name, func(t *testing.T) {
91-
got, err := Reconcile(c.deep.(map[string]interface{}), c.spec, c.targets)
91+
config := v1alpha1.New()
92+
config.Spec = c.spec
93+
got, err := Reconcile(c.deep.(map[string]interface{}), *config, c.targets)
9294

9395
require.Equal(t, c.err, err)
9496
assert.ElementsMatch(t, c.flat, got)
@@ -99,7 +101,7 @@ func TestReconcile(t *testing.T) {
99101
func TestReconcileOrder(t *testing.T) {
100102
got := make([]manifest.List, 10)
101103
for i := 0; i < 10; i++ {
102-
r, err := Reconcile(testDataDeep().deep.(map[string]interface{}), v1alpha1.Spec{}, nil)
104+
r, err := Reconcile(testDataDeep().deep.(map[string]interface{}), *v1alpha1.New(), nil)
103105
require.NoError(t, err)
104106
got[i] = r
105107
}

0 commit comments

Comments
 (0)