Skip to content
Merged
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
7 changes: 7 additions & 0 deletions bundle/run/job.go
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,13 @@ type jobRunner struct {
job *resources.Job
}

func (r *jobRunner) Name() string {
if r.job == nil || r.job.JobSettings == nil {
return ""
}
return r.job.JobSettings.Name
}

func isFailed(task jobs.RunTask) bool {
return task.State.LifeCycleState == jobs.RunLifeCycleStateInternalError ||
(task.State.LifeCycleState == jobs.RunLifeCycleStateTerminated &&
Expand Down
22 changes: 15 additions & 7 deletions bundle/run/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"fmt"

"github.com/databricks/cli/bundle"
"golang.org/x/exp/maps"
)

// RunnerLookup maps identifiers to a list of workloads that match that identifier.
Expand Down Expand Up @@ -32,18 +33,20 @@ func ResourceKeys(b *bundle.Bundle) (keyOnly RunnerLookup, keyWithType RunnerLoo
return
}

// ResourceCompletions returns a list of keys that unambiguously reference resources in the bundle.
func ResourceCompletions(b *bundle.Bundle) []string {
seen := make(map[string]bool)
comps := []string{}
// ResourceCompletionMap returns a map of resource keys to their respective names.
func ResourceCompletionMap(b *bundle.Bundle) map[string]string {
out := make(map[string]string)
keyOnly, keyWithType := ResourceKeys(b)

// Keep track of resources we have seen by their fully qualified key.
seen := make(map[string]bool)

// First add resources that can be identified by key alone.
for k, v := range keyOnly {
// Invariant: len(v) >= 1. See [ResourceKeys].
if len(v) == 1 {
seen[v[0].Key()] = true
comps = append(comps, k)
out[k] = v[0].Name()
}
}

Expand All @@ -54,8 +57,13 @@ func ResourceCompletions(b *bundle.Bundle) []string {
if ok {
continue
}
comps = append(comps, k)
out[k] = v[0].Name()
}

return comps
return out
}

// ResourceCompletions returns a list of keys that unambiguously reference resources in the bundle.
func ResourceCompletions(b *bundle.Bundle) []string {
return maps.Keys(ResourceCompletionMap(b))
}
7 changes: 7 additions & 0 deletions bundle/run/pipeline.go
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,13 @@ type pipelineRunner struct {
pipeline *resources.Pipeline
}

func (r *pipelineRunner) Name() string {
if r.pipeline == nil || r.pipeline.PipelineSpec == nil {
return ""
}
return r.pipeline.PipelineSpec.Name
}

func (r *pipelineRunner) Run(ctx context.Context, opts *Options) (output.RunOutput, error) {
var pipelineID = r.pipeline.ID

Expand Down
3 changes: 3 additions & 0 deletions bundle/run/runner.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,9 @@ type Runner interface {
// This is used for showing the user hints w.r.t. disambiguation.
Key() string

// Name returns the resource's name, if defined.
Name() string

// Run the underlying worklow.
Run(ctx context.Context, opts *Options) (output.RunOutput, error)
}
Expand Down
30 changes: 25 additions & 5 deletions cmd/bundle/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,17 @@ import (
"github.com/databricks/cli/bundle/phases"
"github.com/databricks/cli/bundle/run"
"github.com/databricks/cli/cmd/root"
"github.com/databricks/cli/libs/cmdio"
"github.com/databricks/cli/libs/flags"
"github.com/spf13/cobra"
)

func newRunCommand() *cobra.Command {
cmd := &cobra.Command{
Use: "run [flags] KEY",
Short: "Run a workload (e.g. a job or a pipeline)",
Short: "Run a resource (e.g. a job or a pipeline)",

Args: cobra.ExactArgs(1),
Args: cobra.MaximumNArgs(1),
PreRunE: ConfigureBundleWithVariables,
}

Expand All @@ -29,9 +30,10 @@ func newRunCommand() *cobra.Command {
cmd.Flags().BoolVar(&noWait, "no-wait", false, "Don't wait for the run to complete.")

cmd.RunE = func(cmd *cobra.Command, args []string) error {
b := bundle.Get(cmd.Context())
ctx := cmd.Context()
b := bundle.Get(ctx)

err := bundle.Apply(cmd.Context(), b, bundle.Seq(
err := bundle.Apply(ctx, b, bundle.Seq(
phases.Initialize(),
terraform.Interpolate(),
terraform.Write(),
Expand All @@ -42,13 +44,31 @@ func newRunCommand() *cobra.Command {
return err
}

// If no arguments are specified, prompt the user to select something to run.
if len(args) == 0 && cmdio.IsInteractive(ctx) {
// Invert completions from KEY -> NAME, to NAME -> KEY.
inv := make(map[string]string)
for k, v := range run.ResourceCompletionMap(b) {
inv[v] = k
}
id, err := cmdio.Select(ctx, inv, "Resource to run")
if err != nil {
return err
}
args = append(args, id)
}

if len(args) != 1 {
return fmt.Errorf("expected a KEY of the resource to run")
}

runner, err := run.Find(b, args[0])
if err != nil {
return err
}

runOptions.NoWait = noWait
output, err := runner.Run(cmd.Context(), &runOptions)
output, err := runner.Run(ctx, &runOptions)
if err != nil {
return err
}
Expand Down