mirror of https://github.com/databricks/cli.git
Use interactive prompt to select resource to run if not specified (#762)
## Changes Display an interactive prompt with a list of resources to run if one isn't specified and the command is run interactively. ## Tests Manually confirmed: * The new prompt works * Shell completion still works * Specifying a key argument still works
This commit is contained in:
parent
0cb05d1ded
commit
a2775f836f
|
@ -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 &&
|
||||
|
|
|
@ -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.
|
||||
|
@ -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()
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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))
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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)
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ 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"
|
||||
)
|
||||
|
@ -16,9 +17,9 @@ import (
|
|||
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,
|
||||
}
|
||||
|
||||
|
@ -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(),
|
||||
|
@ -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
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue