Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion cmd/workspace/alerts/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/spf13/cobra"
)

func listOverride(listCmd *cobra.Command, listReq *sql.ListAlertsRequest) {
func listOverride(listCmd *cobra.Command, _ *sql.ListAlertsRequest) {
listCmd.Annotations["template"] = cmdio.Heredoc(`
{{range .}}{{green "%s" .Id}} {{.DisplayName}} {{.State}}
{{end}}`)
Expand Down
4 changes: 2 additions & 2 deletions cmd/workspace/apps/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ import (
"github.com/spf13/cobra"
)

func listOverride(listCmd *cobra.Command, listReq *apps.ListAppsRequest) {
func listOverride(listCmd *cobra.Command, _ *apps.ListAppsRequest) {
listCmd.Annotations["headerTemplate"] = cmdio.Heredoc(`
{{header "Name"}} {{header "Url"}} {{header "ComputeStatus"}} {{header "DeploymentStatus"}}`)
listCmd.Annotations["template"] = cmdio.Heredoc(`
Expand Down Expand Up @@ -45,7 +45,7 @@ func listOverride(listCmd *cobra.Command, listReq *apps.ListAppsRequest) {
tableview.RegisterConfig(listCmd, tableview.TableConfig{Columns: columns})
}

func listDeploymentsOverride(listDeploymentsCmd *cobra.Command, listDeploymentsReq *apps.ListAppDeploymentsRequest) {
func listDeploymentsOverride(listDeploymentsCmd *cobra.Command, _ *apps.ListAppDeploymentsRequest) {
listDeploymentsCmd.Annotations["headerTemplate"] = cmdio.Heredoc(`
{{header "DeploymentId"}} {{header "State"}} {{header "CreatedAt"}}`)
listDeploymentsCmd.Annotations["template"] = cmdio.Heredoc(`
Expand Down
2 changes: 1 addition & 1 deletion cmd/workspace/catalogs/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/spf13/cobra"
)

func listOverride(listCmd *cobra.Command, listReq *catalog.ListCatalogsRequest) {
func listOverride(listCmd *cobra.Command, _ *catalog.ListCatalogsRequest) {
listCmd.Annotations["headerTemplate"] = cmdio.Heredoc(`
{{header "Name"}} {{header "Type"}} {{header "Comment"}}`)
listCmd.Annotations["template"] = cmdio.Heredoc(`
Expand Down
18 changes: 18 additions & 0 deletions cmd/workspace/cluster-policies/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package cluster_policies

import (
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/cli/libs/tableview"
"github.com/databricks/databricks-sdk-go/service/compute"
"github.com/spf13/cobra"
)
Expand All @@ -10,6 +11,23 @@ func listOverride(listCmd *cobra.Command, _ *compute.ListClusterPoliciesRequest)
listCmd.Annotations["template"] = cmdio.Heredoc(`
{{range .}}{{.PolicyId | green}} {{.Name}}
{{end}}`)

columns := []tableview.ColumnDef{
{Header: "Policy ID", Extract: func(v any) string {
return v.(compute.Policy).PolicyId
}},
{Header: "Name", Extract: func(v any) string {
return v.(compute.Policy).Name
}},
{Header: "Default", Extract: func(v any) string {
if v.(compute.Policy).IsDefault {
return "yes"
}
return ""
}},
}

tableview.RegisterConfig(listCmd, tableview.TableConfig{Columns: columns})
}

func getOverride(getCmd *cobra.Command, _ *compute.GetClusterPolicyRequest) {
Expand Down
2 changes: 1 addition & 1 deletion cmd/workspace/external-locations/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/spf13/cobra"
)

func listOverride(listCmd *cobra.Command, listReq *catalog.ListExternalLocationsRequest) {
func listOverride(listCmd *cobra.Command, _ *catalog.ListExternalLocationsRequest) {
listCmd.Annotations["headerTemplate"] = cmdio.Heredoc(`
{{header "Name"}} {{header "Credential"}} {{header "URL"}}`)
listCmd.Annotations["template"] = cmdio.Heredoc(`
Expand Down
2 changes: 1 addition & 1 deletion cmd/workspace/jobs/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func listOverride(listCmd *cobra.Command, listReq *jobs.ListJobsRequest) {
})
}

func listRunsOverride(listRunsCmd *cobra.Command, listRunsReq *jobs.ListRunsRequest) {
func listRunsOverride(listRunsCmd *cobra.Command, _ *jobs.ListRunsRequest) {
listRunsCmd.Annotations["headerTemplate"] = cmdio.Heredoc(`
{{header "Job ID"}} {{header "Run ID"}} {{header "Result State"}} URL`)
listRunsCmd.Annotations["template"] = cmdio.Heredoc(`
Expand Down
25 changes: 25 additions & 0 deletions cmd/workspace/lakeview/overrides.go
Original file line number Diff line number Diff line change
@@ -1,10 +1,34 @@
package lakeview

import (
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/cli/libs/tableview"
"github.com/databricks/databricks-sdk-go/service/dashboards"
"github.com/spf13/cobra"
)

func listOverride(listCmd *cobra.Command, _ *dashboards.ListDashboardsRequest) {
listCmd.Annotations["headerTemplate"] = cmdio.Heredoc(`
{{header "Dashboard ID"}} {{header "Name"}} {{header "State"}}`)
listCmd.Annotations["template"] = cmdio.Heredoc(`
{{range .}}{{green "%s" .DashboardId}} {{.DisplayName}} {{blue "%s" .LifecycleState}}
{{end}}`)

columns := []tableview.ColumnDef{
{Header: "Dashboard ID", Extract: func(v any) string {
return v.(dashboards.Dashboard).DashboardId
}},
{Header: "Name", Extract: func(v any) string {
return v.(dashboards.Dashboard).DisplayName
}},
{Header: "State", Extract: func(v any) string {
return string(v.(dashboards.Dashboard).LifecycleState)
}},
}

tableview.RegisterConfig(listCmd, tableview.TableConfig{Columns: columns})
}

func publishOverride(cmd *cobra.Command, req *dashboards.PublishRequest) {
originalRunE := cmd.RunE
cmd.RunE = func(cmd *cobra.Command, args []string) error {
Expand All @@ -15,5 +39,6 @@ func publishOverride(cmd *cobra.Command, req *dashboards.PublishRequest) {
}

func init() {
listOverrides = append(listOverrides, listOverride)
publishOverrides = append(publishOverrides, publishOverride)
}
34 changes: 34 additions & 0 deletions cmd/workspace/pipelines/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -62,8 +62,34 @@ func listPipelinesOverride(listCmd *cobra.Command, listReq *pipelines.ListPipeli
}
}

func listPipelineEventsOverride(listCmd *cobra.Command, _ *pipelines.ListPipelineEventsRequest) {
listCmd.Annotations["headerTemplate"] = cmdio.Heredoc(`
{{header "Timestamp"}} {{header "Level"}} {{header "Event Type"}} {{header "Message"}}`)
listCmd.Annotations["template"] = cmdio.Heredoc(`
{{range .}}{{.Timestamp}} {{.Level}} {{.EventType}} {{.Message | sanitize}}
{{end}}`)

columns := []tableview.ColumnDef{
{Header: "Timestamp", Extract: func(v any) string {
return v.(pipelines.PipelineEvent).Timestamp
}},
{Header: "Level", Extract: func(v any) string {
return string(v.(pipelines.PipelineEvent).Level)
}},
{Header: "Event Type", Extract: func(v any) string {
return v.(pipelines.PipelineEvent).EventType
}},
{Header: "Message", MaxWidth: 200, Extract: func(v any) string {
return sanitizeWhitespace(v.(pipelines.PipelineEvent).Message)
}},
}

tableview.RegisterConfig(listCmd, tableview.TableConfig{Columns: columns})
}

func init() {
listPipelinesOverrides = append(listPipelinesOverrides, listPipelinesOverride)
listPipelineEventsOverrides = append(listPipelineEventsOverrides, listPipelineEventsOverride)

cmdOverrides = append(cmdOverrides, func(cli *cobra.Command) {
// all auto-generated commands apart from nonManagementCommands go into 'management' group
Expand Down Expand Up @@ -135,6 +161,14 @@ func disableSearchIfFilterSet(cmd *cobra.Command) {
}
}

var controlWhitespaceReplacer = strings.NewReplacer("\n", " ", "\r", " ", "\t", " ")

// sanitizeWhitespace replaces control whitespace (newlines, tabs) with spaces
// to prevent corrupting tab-delimited or TUI table output.
func sanitizeWhitespace(s string) string {
return controlWhitespaceReplacer.Replace(s)
}

var uuidRegex = regexp.MustCompile(`^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$`)

// looksLikeUUID checks if a string matches the UUID format with lowercase hex digits
Expand Down
2 changes: 1 addition & 1 deletion cmd/workspace/repos/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
"github.com/spf13/cobra"
)

func listOverride(listCmd *cobra.Command, listReq *workspace.ListReposRequest) {
func listOverride(listCmd *cobra.Command, _ *workspace.ListReposRequest) {
listCmd.Annotations["template"] = cmdio.Heredoc(`
{{range .}}{{green "%d" .Id}} {{.Path}} {{.Branch|blue}} {{.Url|cyan}}
{{end}}`)
Expand Down
2 changes: 1 addition & 1 deletion cmd/workspace/schemas/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/spf13/cobra"
)

func listOverride(listCmd *cobra.Command, listReq *catalog.ListSchemasRequest) {
func listOverride(listCmd *cobra.Command, _ *catalog.ListSchemasRequest) {
listCmd.Annotations["headerTemplate"] = cmdio.Heredoc(`
{{header "Full Name"}} {{header "Owner"}} {{header "Comment"}}`)
listCmd.Annotations["template"] = cmdio.Heredoc(`
Expand Down
29 changes: 29 additions & 0 deletions cmd/workspace/secrets/overrides.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
package secrets

import (
"time"

"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/cli/libs/tableview"
"github.com/databricks/databricks-sdk-go/service/workspace"
"github.com/spf13/cobra"
)
Expand All @@ -16,6 +19,17 @@ func listScopesOverride(listScopesCmd *cobra.Command) {
listScopesCmd.Annotations["template"] = cmdio.Heredoc(`
{{range .}}{{.Name|green}} {{.BackendType}}
{{end}}`)

columns := []tableview.ColumnDef{
{Header: "Scope", Extract: func(v any) string {
return v.(workspace.SecretScope).Name
}},
{Header: "Backend Type", Extract: func(v any) string {
return string(v.(workspace.SecretScope).BackendType)
}},
}

tableview.RegisterConfig(listScopesCmd, tableview.TableConfig{Columns: columns})
}

func listSecretsOverride(listSecretsCommand *cobra.Command, _ *workspace.ListSecretsRequest) {
Expand All @@ -24,6 +38,21 @@ func listSecretsOverride(listSecretsCommand *cobra.Command, _ *workspace.ListSec
listSecretsCommand.Annotations["template"] = cmdio.Heredoc(`
{{range .}}{{.Key|green}} {{.LastUpdatedTimestamp}}
{{end}}`)

columns := []tableview.ColumnDef{
{Header: "Key", Extract: func(v any) string {
return v.(workspace.SecretMetadata).Key
}},
{Header: "Last Updated", Extract: func(v any) string {
ts := v.(workspace.SecretMetadata).LastUpdatedTimestamp
if ts == 0 {
return ""
}
return time.UnixMilli(ts).UTC().Format("2006-01-02 15:04:05")
}},
}

tableview.RegisterConfig(listSecretsCommand, tableview.TableConfig{Columns: columns})
}

func init() {
Expand Down
2 changes: 1 addition & 1 deletion cmd/workspace/tables/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/spf13/cobra"
)

func listOverride(listCmd *cobra.Command, listReq *catalog.ListTablesRequest) {
func listOverride(listCmd *cobra.Command, _ *catalog.ListTablesRequest) {
listCmd.Annotations["headerTemplate"] = cmdio.Heredoc(`
{{header "Full Name"}} {{header "Table Type"}}`)
listCmd.Annotations["template"] = cmdio.Heredoc(`
Expand Down
2 changes: 1 addition & 1 deletion cmd/workspace/volumes/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/spf13/cobra"
)

func listOverride(listCmd *cobra.Command, listReq *catalog.ListVolumesRequest) {
func listOverride(listCmd *cobra.Command, _ *catalog.ListVolumesRequest) {
listCmd.Annotations["template"] = cmdio.Heredoc(`
{{range .}}{{green "%s" .Name}} {{.VolumeType}} {{.FullName}}
{{end}}`)
Expand Down
2 changes: 1 addition & 1 deletion cmd/workspace/warehouses/overrides.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"github.com/spf13/cobra"
)

func listOverride(listCmd *cobra.Command, listReq *sql.ListWarehousesRequest) {
func listOverride(listCmd *cobra.Command, _ *sql.ListWarehousesRequest) {
listCmd.Annotations["headerTemplate"] = cmdio.Heredoc(`
{{header "ID"}} {{header "Name"}} {{header "Size"}} {{header "State"}}`)
listCmd.Annotations["template"] = cmdio.Heredoc(`
Expand Down
11 changes: 10 additions & 1 deletion libs/cmdio/render.go
Original file line number Diff line number Diff line change
Expand Up @@ -313,6 +313,14 @@
return renderWithTemplate(ctx, newIteratorRenderer(i), c.outputFormat, c.out, c.headerTemplate, c.template)
}

var controlWhitespaceReplacer = strings.NewReplacer("\n", " ", "\r", " ", "\t", " ")

// sanitizeControlWhitespace replaces newlines and tabs with spaces to prevent
// corrupting tab-delimited text output.
func sanitizeControlWhitespace(s string) string {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This function is also defined in cmd/workspace/pipelines/overrides.go. Consolidate?

return controlWhitespaceReplacer.Replace(s)
}

var renderFuncMap = template.FuncMap{
// we render colored output if stdout is TTY, otherwise we render text.
// in the future we'll check if we can explicitly check for stderr being
Expand All @@ -330,8 +338,9 @@
"italic": func(format string, a ...any) string {
return color.New(color.Italic).Sprintf(format, a...)
},
"replace": strings.ReplaceAll,
"replace": strings.ReplaceAll,
"sanitize": sanitizeControlWhitespace,
"join": strings.Join,

Check failure on line 343 in libs/cmdio/render.go

View workflow job for this annotation

GitHub Actions / lint

File is not properly formatted (gofmt)
"sub": func(a, b int) int {
return a - b
},
Expand Down
7 changes: 5 additions & 2 deletions libs/tableview/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,11 @@ import "context"

// ColumnDef defines a column in the TUI table.
type ColumnDef struct {
Header string // Display name in header row.
MaxWidth int // Max cell width; 0 = default (50).
Header string // Display name in header row.
// MaxWidth caps cell display width; 0 = default (50). Values exceeding
// this limit are destructively truncated with "..." in the rendered
// output. Horizontal scrolling does not recover the hidden portion.
MaxWidth int
Extract func(v any) string // Extracts cell value from typed SDK struct.
}

Expand Down
19 changes: 10 additions & 9 deletions libs/tableview/paginated.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,11 @@ type paginatedModel struct {
limitReached bool
}

// Err returns the error recorded during data fetching, if any.
func (m paginatedModel) Err() error {
return m.err
}

// newFetchCmdFunc returns a closure that creates fetch commands, capturing ctx.
func newFetchCmdFunc(ctx context.Context) func(paginatedModel) tea.Cmd {
return func(m paginatedModel) tea.Cmd {
Expand Down Expand Up @@ -156,19 +161,14 @@ func RunPaginated(ctx context.Context, w io.Writer, cfg *TableConfig, iter RowIt
if err != nil {
return err
}
if pm, ok := finalModel.(FinalModel); ok {
if modelErr := pm.Err(); modelErr != nil {
return modelErr
if m, ok := finalModel.(FinalModel); ok {
if fetchErr := m.Err(); fetchErr != nil {
return fetchErr
}
}
return nil
}

// Err returns any error that occurred during data fetching.
func (m paginatedModel) Err() error {
return m.err
}

func (m paginatedModel) Init() tea.Cmd {
return m.makeFetchCmd(m)
}
Expand Down Expand Up @@ -275,7 +275,8 @@ func (m paginatedModel) renderContent() string {
}
fmt.Fprintln(tw, strings.Join(seps, "\t"))

// Data rows
// Data rows.
// MaxWidth truncation is destructive; horizontal scroll won't recover hidden text.
for _, row := range m.rows {
vals := make([]string, len(m.headers))
for i := range m.headers {
Expand Down
Loading