split into summary and detail

This commit is contained in:
Shreyas Goenka 2024-09-26 16:03:49 +02:00
parent fd01824ee1
commit 5308ad8bf3
No known key found for this signature in database
GPG Key ID: 92A07DF49CCB0622
2 changed files with 28 additions and 22 deletions

View File

@ -3,6 +3,7 @@ package loader
import ( import (
"context" "context"
"fmt" "fmt"
"slices"
"sort" "sort"
"strings" "strings"
@ -10,7 +11,6 @@ import (
"github.com/databricks/cli/bundle/config" "github.com/databricks/cli/bundle/config"
"github.com/databricks/cli/libs/diag" "github.com/databricks/cli/libs/diag"
"github.com/databricks/cli/libs/dyn" "github.com/databricks/cli/libs/dyn"
"golang.org/x/exp/maps"
) )
var resourceTypes = []string{ var resourceTypes = []string{
@ -99,22 +99,20 @@ func validateSingleResourceDefined(r *config.Root, ext, typ string) diag.Diagnos
return nil return nil
} }
msg := strings.Builder{} detail := strings.Builder{}
msg.WriteString(fmt.Sprintf("We recommend only defining a single %s in a file with the %s extension.\n", typ, ext)) detail.WriteString("The following resources are defined or configured in this file:\n")
lines := []string{}
// Dedup the list of resources before adding them the diagnostic message. This
// is needed because we do not dedup earlier when gathering the resources and
// it's valid to define the same resource in both the resources and targets block.
msg.WriteString("The following resources are defined or configured in this file:\n")
setOfLines := map[string]struct{}{}
for _, r := range resources { for _, r := range resources {
setOfLines[fmt.Sprintf(" - %s (%s)\n", r.key, r.typ)] = struct{}{} lines = append(lines, fmt.Sprintf(" - %s (%s)\n", r.key, r.typ))
} }
// Sort the line s to print to make the output deterministic. // Sort the line s to print to make the output deterministic.
listOfLines := maps.Keys(setOfLines) sort.Strings(lines)
sort.Strings(listOfLines) // Compact the lines before writing them to the message to remove any duplicate lines.
for _, l := range listOfLines { // This is needed because we do not dedup earlier when gathering the resources
msg.WriteString(l) // and it's valid to define the same resource in both the resources and targets block.
lines = slices.Compact(lines)
for _, l := range lines {
detail.WriteString(l)
} }
locations := []dyn.Location{} locations := []dyn.Location{}
@ -134,7 +132,8 @@ func validateSingleResourceDefined(r *config.Root, ext, typ string) diag.Diagnos
return diag.Diagnostics{ return diag.Diagnostics{
{ {
Severity: diag.Info, Severity: diag.Info,
Summary: msg.String(), Summary: fmt.Sprintf("We recommend only defining a single %s in a file with the %s extension.", typ, ext),
Detail: detail.String(),
Locations: locations, Locations: locations,
Paths: paths, Paths: paths,
}, },

View File

@ -58,7 +58,8 @@ func TestProcessIncludeValidatesFileFormat(t *testing.T) {
assert.Equal(t, diag.Diagnostics{ assert.Equal(t, diag.Diagnostics{
{ {
Severity: diag.Info, Severity: diag.Info,
Summary: "We recommend only defining a single job in a file with the .job.yml extension.\nThe following resources are defined or configured in this file:\n - bar (job)\n - foo (job)\n", Summary: "We recommend only defining a single job in a file with the .job.yml extension.",
Detail: "The following resources are defined or configured in this file:\n - bar (job)\n - foo (job)\n",
Locations: []dyn.Location{ Locations: []dyn.Location{
{File: filepath.FromSlash("testdata/format/foo.job.yml"), Line: 4, Column: 7}, {File: filepath.FromSlash("testdata/format/foo.job.yml"), Line: 4, Column: 7},
{File: filepath.FromSlash("testdata/format/foo.job.yml"), Line: 7, Column: 7}, {File: filepath.FromSlash("testdata/format/foo.job.yml"), Line: 7, Column: 7},
@ -209,7 +210,8 @@ func TestValidateFileFormat(t *testing.T) {
expected: diag.Diagnostics{ expected: diag.Diagnostics{
{ {
Severity: diag.Info, Severity: diag.Info,
Summary: "We recommend only defining a single pipeline in a file with the .pipeline.yml extension.\nThe following resources are defined or configured in this file:\n - job1 (job)\n", Summary: "We recommend only defining a single pipeline in a file with the .pipeline.yml extension.",
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n",
Locations: []dyn.Location{ Locations: []dyn.Location{
{File: "foo.pipeline.yml", Line: 1, Column: 1}, {File: "foo.pipeline.yml", Line: 1, Column: 1},
{File: "foo.pipeline.yml", Line: 2, Column: 2}, {File: "foo.pipeline.yml", Line: 2, Column: 2},
@ -242,7 +244,8 @@ func TestValidateFileFormat(t *testing.T) {
expected: diag.Diagnostics{ expected: diag.Diagnostics{
{ {
Severity: diag.Info, Severity: diag.Info,
Summary: "We recommend only defining a single job in a file with the .job.yml extension.\nThe following resources are defined or configured in this file:\n - job1 (job)\n - pipeline1 (pipeline)\n", Summary: "We recommend only defining a single job in a file with the .job.yml extension.",
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - pipeline1 (pipeline)\n",
Locations: []dyn.Location{ Locations: []dyn.Location{
{File: "foo.job.yml", Line: 1, Column: 1}, {File: "foo.job.yml", Line: 1, Column: 1},
{File: "foo.job.yml", Line: 2, Column: 2}, {File: "foo.job.yml", Line: 2, Column: 2},
@ -265,7 +268,8 @@ func TestValidateFileFormat(t *testing.T) {
expected: diag.Diagnostics{ expected: diag.Diagnostics{
{ {
Severity: diag.Info, Severity: diag.Info,
Summary: "We recommend only defining a single experiment in a file with the .experiment.yml extension.\nThe following resources are defined or configured in this file:\n - job1 (job)\n - pipeline1 (pipeline)\n", Summary: "We recommend only defining a single experiment in a file with the .experiment.yml extension.",
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - pipeline1 (pipeline)\n",
Locations: []dyn.Location{ Locations: []dyn.Location{
{File: "foo.experiment.yml", Line: 1, Column: 1}, {File: "foo.experiment.yml", Line: 1, Column: 1},
{File: "foo.experiment.yml", Line: 2, Column: 2}, {File: "foo.experiment.yml", Line: 2, Column: 2},
@ -288,7 +292,8 @@ func TestValidateFileFormat(t *testing.T) {
expected: diag.Diagnostics{ expected: diag.Diagnostics{
{ {
Severity: diag.Info, Severity: diag.Info,
Summary: "We recommend only defining a single job in a file with the .job.yml extension.\nThe following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n", Summary: "We recommend only defining a single job in a file with the .job.yml extension.",
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n",
Locations: []dyn.Location{ Locations: []dyn.Location{
{File: "foo.job.yml", Line: 1, Column: 1}, {File: "foo.job.yml", Line: 1, Column: 1},
{File: "foo.job.yml", Line: 2, Column: 2}, {File: "foo.job.yml", Line: 2, Column: 2},
@ -321,7 +326,8 @@ func TestValidateFileFormat(t *testing.T) {
expected: diag.Diagnostics{ expected: diag.Diagnostics{
{ {
Severity: diag.Info, Severity: diag.Info,
Summary: "We recommend only defining a single job in a file with the .job.yml extension.\nThe following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n", Summary: "We recommend only defining a single job in a file with the .job.yml extension.",
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n",
Locations: []dyn.Location{ Locations: []dyn.Location{
{File: "foo.job.yml", Line: 1, Column: 1}, {File: "foo.job.yml", Line: 1, Column: 1},
{File: "foo.job.yml", Line: 2, Column: 2}, {File: "foo.job.yml", Line: 2, Column: 2},
@ -344,7 +350,8 @@ func TestValidateFileFormat(t *testing.T) {
expected: diag.Diagnostics{ expected: diag.Diagnostics{
{ {
Severity: diag.Info, Severity: diag.Info,
Summary: "We recommend only defining a single job in a file with the .job.yml extension.\nThe following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n", Summary: "We recommend only defining a single job in a file with the .job.yml extension.",
Detail: "The following resources are defined or configured in this file:\n - job1 (job)\n - job2 (job)\n",
Locations: []dyn.Location{ Locations: []dyn.Location{
{File: "foo.job.yml", Line: 1, Column: 1}, {File: "foo.job.yml", Line: 1, Column: 1},
{File: "foo.job.yml", Line: 2, Column: 2}, {File: "foo.job.yml", Line: 2, Column: 2},