package run import ( "context" "fmt" "strings" "github.com/databricks/bricks/bundle" ) // TODO: refactor this package into service specific implementations. Its // getting bloated. (https://github.com/databricks/bricks/issues/282) type key string func (k key) Key() string { return string(k) } type RunOutput interface { String() (string, error) } // 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 // Run the underlying worklow. Run(ctx context.Context, opts *Options) (RunOutput, error) } // Find locates a runner matching the specified argument. // // Its behavior is as follows: // 1. Try to find a resource with identical to the argument. // 2. Try to find a resource with . 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 }