diff --git a/.vscode/settings.json b/.vscode/settings.json index d823def2..fef6aad1 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -17,5 +17,13 @@ // This is better handled by Regal's selection ranges implementation "editor.smartSelect.selectLeadingAndTrailingWhitespace": false, "editor.smartSelect.selectSubwords": false - } + }, + // Enable to have values displayed inline during debugging + // The default value is "auto", which consults the language extension on whethher + // to have this enabled or not. And since the extension currently doesn't do anything + // on its own to support this, we need to explicitly enable it here if we want this. + // Long term, the extension + Regal should provide support for this, as it'll also + // result in a better experience when we can be more selective about what to show, + // and how. + "debug.inlineValues": "on" } diff --git a/internal/io/io.go b/internal/io/io.go index 8b3e1e91..3d891583 100644 --- a/internal/io/io.go +++ b/internal/io/io.go @@ -169,8 +169,8 @@ func WithCreateRecursive(path string, fn func(f *os.File) error) error { return fn(file) } -// FindInputPath consults the filesystem and returns the input.json or input.yaml closes to the -// file provided as arguments. +// FindInputPath consults the filesystem and returns the location of the input.json +// or input.yaml closest to the file provided. func FindInputPath(file string, workspacePath string) string { relative := strings.TrimPrefix(file, workspacePath) components := strings.Split(filepath.Dir(relative), string(os.PathSeparator)) diff --git a/internal/lsp/eval_test.go b/internal/lsp/eval_test.go index f25597ea..caec8e1f 100644 --- a/internal/lsp/eval_test.go +++ b/internal/lsp/eval_test.go @@ -106,16 +106,19 @@ func TestFindInputPath(t *testing.T) { t.Fatalf("did not expect to find input.%s", tc.fileExt) } - createWithContent(t, tmpDir+"/workspace/foo/bar/input."+tc.fileExt, tc.fileContent) + inputPath := filepath.Join(workspacePath, "foo", "bar", "input."+tc.fileExt) + createWithContent(t, inputPath, tc.fileContent) - if path, exp := rio.FindInputPath(file, workspacePath), workspacePath+"/foo/bar/input."+tc.fileExt; path != exp { + if path, exp := rio.FindInputPath(file, workspacePath), inputPath; path != exp { t.Errorf(`expected input at %s, got %s`, exp, path) } - testutil.MustRemove(t, tmpDir+"/workspace/foo/bar/input."+tc.fileExt) - createWithContent(t, tmpDir+"/workspace/input."+tc.fileExt, tc.fileContent) + testutil.MustRemove(t, inputPath) - if path, exp := rio.FindInputPath(file, workspacePath), workspacePath+"/input."+tc.fileExt; path != exp { + workspaceInputPath := filepath.Join(workspacePath, "input."+tc.fileExt) + createWithContent(t, workspaceInputPath, tc.fileContent) + + if path, exp := rio.FindInputPath(file, workspacePath), workspaceInputPath; path != exp { t.Errorf(`expected input at %s, got %s`, exp, path) } }) @@ -141,18 +144,30 @@ func TestFindInput(t *testing.T) { t.Fatalf("did not expect to find input.%s", tc.fileType) } - createWithContent(t, tmpDir+"/workspace/foo/bar/input."+tc.fileType, tc.fileContent) + inputPath := filepath.Join(workspacePath, "foo", "bar", "input."+tc.fileType) + + createWithContent(t, inputPath, tc.fileContent) path, content := rio.FindInput(file, workspacePath) - if path != workspacePath+"/foo/bar/input."+tc.fileType || !maps.Equal(content, map[string]any{"x": true}) { - t.Errorf(`expected input {"x": true} at, got %s`, content) + if path != inputPath { + t.Errorf(`expected input at %s, got %s`, inputPath, path) + } + + if !maps.Equal(content, map[string]any{"x": true}) { + t.Errorf(`expected input {"x": true}, got %s`, content) } - testutil.MustRemove(t, tmpDir+"/workspace/foo/bar/input."+tc.fileType) - createWithContent(t, tmpDir+"/workspace/input."+tc.fileType, tc.fileContent) + testutil.MustRemove(t, inputPath) + + workspaceInputPath := filepath.Join(workspacePath, "input."+tc.fileType) + createWithContent(t, workspaceInputPath, tc.fileContent) path, content = rio.FindInput(file, workspacePath) - if path != workspacePath+"/input."+tc.fileType || !maps.Equal(content, map[string]any{"x": true}) { + if path != workspaceInputPath { + t.Errorf(`expected input at %s, got %s`, workspaceInputPath, path) + } + + if !maps.Equal(content, map[string]any{"x": true}) { t.Errorf(`expected input {"x": true} at, got %s`, content) } }) diff --git a/pkg/linter/linter.go b/pkg/linter/linter.go index 3add293a..9d33e5ac 100644 --- a/pkg/linter/linter.go +++ b/pkg/linter/linter.go @@ -869,27 +869,22 @@ func (l Linter) lintWithAggregateRules( ctx, cancel := context.WithCancel(ctx) defer cancel() - input := map[string]any{ - // This will be replaced by the routing policy to provide each - // aggregate rule only the aggregated data from the same rule - "aggregates_internal": aggregates, - // There is no file provided in input here, but we'll provide *something* for - // consistency, and to avoid silently failing with undefined should someone - // refer to input.regal in an aggregate_report rule - "ignore_directives": ignoreDirectives, - "regal": map[string]any{ - "operations": []string{"aggregate"}, - "file": map[string]any{ - "name": "__aggregate_report__", - "lines": []string{}, - }, - }, - } + regal := ast.ObjectTerm( + ast.Item(ast.InternedTerm("operations"), ast.ArrayTerm(ast.InternedTerm("aggregate"))), + ast.Item(ast.InternedTerm("file"), ast.ObjectTerm( + ast.Item(ast.InternedTerm("name"), ast.InternedTerm("__aggregate_report__")), + ast.Item(ast.InternedTerm("lines"), ast.InternedEmptyArray), + )), + ) - inputValue, err := transform.ToOPAInputValue(input) - if err != nil { - return report.Report{}, fmt.Errorf("failed to transform input value: %w", err) - } + aggParsed, _ := transform.ToOPAInputValue(aggregates) + dirParsed, _ := transform.ToOPAInputValue(ignoreDirectives) + + inputValue := ast.NewObject( + ast.Item(ast.InternedTerm("aggregates_internal"), ast.NewTerm(aggParsed)), + ast.Item(ast.InternedTerm("ignore_directives"), ast.NewTerm(dirParsed)), + ast.Item(ast.InternedTerm("regal"), regal), + ) evalArgs := []rego.EvalOption{ rego.EvalParsedInput(inputValue), diff --git a/pkg/linter/linter_test.go b/pkg/linter/linter_test.go index 53015c24..89b46dc8 100644 --- a/pkg/linter/linter_test.go +++ b/pkg/linter/linter_test.go @@ -438,7 +438,7 @@ func TestLintWithPrintHook(t *testing.T) { func TestLintWithAggregateRule(t *testing.T) { t.Parallel() - policies := make(map[string]string) + policies := make(map[string]string, 2) policies["foo.rego"] = `package foo import data.bar