package run import ( "context" "fmt" "strings" "github.com/databricks/cli/bundle" "github.com/databricks/cli/bundle/run/output" ) type key string func (k key) Key() string { return string(k) } // Runner defines the interface for a runnable resource (or workload). type Runner interface { // Key returns the fully qualified (unique) identifier for this runnable resource. // 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) // Cancel the underlying workflow. Cancel(ctx context.Context) error // Runners support parsing and completion of additional positional arguments. argsHandler } // Find locates a runner matching the specified argument. // // Its behavior is as follows: // 1. Try to find a resource with <key> identical to the argument. // 2. Try to find a resource with <type>.<key> identical to the argument. // // If an argument resolves to multiple resources, it returns an error. func Find(b *bundle.Bundle, arg string) (Runner, error) { keyOnly, keyWithType := ResourceKeys(b) if len(keyWithType) == 0 { return nil, fmt.Errorf("bundle defines no resources") } runners, ok := keyOnly[arg] if !ok { runners, ok = keyWithType[arg] if !ok { return nil, fmt.Errorf("no such resource: %s", arg) } } if len(runners) != 1 { var keys []string for _, runner := range runners { keys = append(keys, runner.Key()) } return nil, fmt.Errorf("ambiguous: %s (can resolve to all of %s)", arg, strings.Join(keys, ", ")) } return runners[0], nil }