Log warnings to stderr for "bundle validate -o json" (#2109)

## Changes
Previously diagnostics were not seen in JSON output mode. This change
prints them to stderr.

This also fixes acceptance tests to preprocess all output with
s/execPath/$CLI/ not just output.txt.

## Tests
Existing acceptance tests. In one case I've added non-json command to
check that they match in output.
This commit is contained in:
Denis Bilenko 2025-01-10 09:51:59 +01:00 committed by GitHub
parent b0c1c23630
commit 6d3b4159bd
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 54 additions and 14 deletions

View File

@ -55,12 +55,15 @@ func TestAccept(t *testing.T) {
// Do not read user's ~/.databrickscfg // Do not read user's ~/.databrickscfg
t.Setenv(env.HomeEnvVar(), homeDir) t.Setenv(env.HomeEnvVar(), homeDir)
repls := testdiff.ReplacementsContext{}
repls.Set(execPath, "$CLI")
testDirs := getTests(t) testDirs := getTests(t)
require.NotEmpty(t, testDirs) require.NotEmpty(t, testDirs)
for _, dir := range testDirs { for _, dir := range testDirs {
t.Run(dir, func(t *testing.T) { t.Run(dir, func(t *testing.T) {
t.Parallel() t.Parallel()
runTest(t, dir) runTest(t, dir, repls)
}) })
} }
} }
@ -85,7 +88,7 @@ func getTests(t *testing.T) []string {
return testDirs return testDirs
} }
func runTest(t *testing.T, dir string) { func runTest(t *testing.T, dir string, repls testdiff.ReplacementsContext) {
var tmpDir string var tmpDir string
var err error var err error
if KeepTmp { if KeepTmp {
@ -112,7 +115,7 @@ func runTest(t *testing.T, dir string) {
outB, err := cmd.CombinedOutput() outB, err := cmd.CombinedOutput()
out := formatOutput(string(outB), err) out := formatOutput(string(outB), err)
out = strings.ReplaceAll(out, os.Getenv("CLI"), "$CLI") out = repls.Replace(out)
doComparison(t, filepath.Join(dir, "output.txt"), "script output", out) doComparison(t, filepath.Join(dir, "output.txt"), "script output", out)
for key := range outputs { for key := range outputs {
@ -131,7 +134,8 @@ func runTest(t *testing.T, dir string) {
continue continue
} }
pathExpected := filepath.Join(dir, key) pathExpected := filepath.Join(dir, key)
doComparison(t, pathExpected, pathNew, string(newValBytes)) newVal := repls.Replace(string(newValBytes))
doComparison(t, pathExpected, pathNew, newVal)
} }
// Make sure there are not unaccounted for new files // Make sure there are not unaccounted for new files
@ -152,6 +156,7 @@ func runTest(t *testing.T, dir string) {
// Show the contents & support overwrite mode for it: // Show the contents & support overwrite mode for it:
pathNew := filepath.Join(tmpDir, name) pathNew := filepath.Join(tmpDir, name)
newVal := testutil.ReadFile(t, pathNew) newVal := testutil.ReadFile(t, pathNew)
newVal = repls.Replace(newVal)
doComparison(t, filepath.Join(dir, name), filepath.Join(tmpDir, name), newVal) doComparison(t, filepath.Join(dir, name), filepath.Join(tmpDir, name), newVal)
} }
} }

View File

@ -0,0 +1,6 @@
>>> errcode $CLI bundle validate -o json -t development
Error: file ./test1.py not found
Exit code: 1

View File

@ -1,8 +1,3 @@
>>> errcode $CLI bundle validate -o json -t development
Error: file ./test1.py not found
Exit code: 1
{ {
"name": "job", "name": "job",
"queue": { "queue": {
@ -36,6 +31,7 @@ Exit code: 1
>>> errcode $CLI bundle validate -o json -t staging >>> errcode $CLI bundle validate -o json -t staging
Error: file ./test1.py not found Error: file ./test1.py not found
Exit code: 1 Exit code: 1
{ {
"name": "job", "name": "job",
@ -66,3 +62,16 @@ Exit code: 1
} }
] ]
} }
>>> errcode $CLI bundle validate -t staging
Error: file ./test1.py not found
Name: override_job_tasks
Target: staging
Workspace:
User: tester@databricks.com
Path: /Workspace/Users/tester@databricks.com/.bundle/override_job_tasks/staging
Found 1 error
Exit code: 1

View File

@ -1,2 +1,3 @@
trace errcode $CLI bundle validate -o json -t development | jq .resources.jobs.foo trace errcode $CLI bundle validate -o json -t development 2> out.development.stderr.txt | jq .resources.jobs.foo
trace errcode $CLI bundle validate -o json -t staging | jq .resources.jobs.foo trace errcode $CLI bundle validate -o json -t staging | jq .resources.jobs.foo
trace errcode $CLI bundle validate -t staging

View File

@ -1,5 +1,9 @@
>>> $CLI bundle validate -o json -t dev >>> $CLI bundle validate -o json -t dev
Warning: expected map, found string
at resources.clusters.my_cluster
in databricks.yml:6:17
{ {
"clusters": { "clusters": {
"my_cluster": { "my_cluster": {

View File

@ -11,18 +11,17 @@ import (
"github.com/databricks/cli/bundle/render" "github.com/databricks/cli/bundle/render"
"github.com/databricks/cli/cmd/bundle/utils" "github.com/databricks/cli/cmd/bundle/utils"
"github.com/databricks/cli/cmd/root" "github.com/databricks/cli/cmd/root"
"github.com/databricks/cli/libs/diag"
"github.com/databricks/cli/libs/flags" "github.com/databricks/cli/libs/flags"
"github.com/spf13/cobra" "github.com/spf13/cobra"
) )
func renderJsonOutput(cmd *cobra.Command, b *bundle.Bundle, diags diag.Diagnostics) error { func renderJsonOutput(cmd *cobra.Command, b *bundle.Bundle) error {
buf, err := json.MarshalIndent(b.Config.Value().AsAny(), "", " ") buf, err := json.MarshalIndent(b.Config.Value().AsAny(), "", " ")
if err != nil { if err != nil {
return err return err
} }
_, _ = cmd.OutOrStdout().Write(buf) _, _ = cmd.OutOrStdout().Write(buf)
return diags.Error() return nil
} }
func newValidateCommand() *cobra.Command { func newValidateCommand() *cobra.Command {
@ -66,7 +65,23 @@ func newValidateCommand() *cobra.Command {
return nil return nil
case flags.OutputJSON: case flags.OutputJSON:
return renderJsonOutput(cmd, b, diags) renderOpts := render.RenderOptions{RenderSummaryTable: false}
err1 := render.RenderDiagnostics(cmd.ErrOrStderr(), b, diags, renderOpts)
err2 := renderJsonOutput(cmd, b)
if err2 != nil {
return err2
}
if err1 != nil {
return err1
}
if diags.HasError() {
return root.ErrAlreadyPrinted
}
return nil
default: default:
return fmt.Errorf("unknown output type %s", root.OutputType(cmd)) return fmt.Errorf("unknown output type %s", root.OutputType(cmd))
} }