mirror of https://github.com/databricks/cli.git
Run command must always take a single argument (#156)
This commit is contained in:
parent
61ef0ba8c6
commit
49aa858b89
|
@ -24,55 +24,34 @@ type Runner interface {
|
|||
Run(ctx context.Context) error
|
||||
}
|
||||
|
||||
// Collect collects a list of runners given a list of arguments.
|
||||
// Find locates a runner matching the specified argument.
|
||||
//
|
||||
// Its behavior is as follows:
|
||||
// 1. If no arguments are specified, it returns a runner for the only resource in the bundle.
|
||||
// 2. If multiple arguments are specified, for each argument:
|
||||
// 2.1. Try to find a resource with <key> identical to the argument.
|
||||
// 2.2. Try to find a resource with <type>.<key> identical to the argument.
|
||||
// 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 Collect(b *bundle.Bundle, args []string) ([]Runner, 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")
|
||||
}
|
||||
|
||||
var out []Runner
|
||||
|
||||
// If the bundle contains only a single resource, we know what to run.
|
||||
if len(args) == 0 {
|
||||
if len(keyWithType) != 1 {
|
||||
return nil, fmt.Errorf("bundle defines multiple resources; please specify resource to run")
|
||||
}
|
||||
for _, runners := range keyWithType {
|
||||
if len(runners) != 1 {
|
||||
// This invariant is covered by [ResourceKeys].
|
||||
panic("length of []run.Runner must be 1")
|
||||
}
|
||||
out = append(out, runners[0])
|
||||
}
|
||||
return out, nil
|
||||
}
|
||||
|
||||
for _, arg := range args {
|
||||
runners, ok := keyOnly[arg]
|
||||
runners, ok := keyOnly[arg]
|
||||
if !ok {
|
||||
runners, ok = keyWithType[arg]
|
||||
if !ok {
|
||||
runners, ok = keyWithType[arg]
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("no such resource: %s", arg)
|
||||
}
|
||||
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, ", "))
|
||||
}
|
||||
out = append(out, runners[0])
|
||||
}
|
||||
|
||||
return out, nil
|
||||
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
|
||||
}
|
||||
|
|
|
@ -9,18 +9,18 @@ import (
|
|||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestCollectNoResources(t *testing.T) {
|
||||
func TestFindNoResources(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
Config: config.Root{
|
||||
Resources: config.Resources{},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := Collect(b, []string{"foo"})
|
||||
_, err := Find(b, "foo")
|
||||
assert.ErrorContains(t, err, "bundle defines no resources")
|
||||
}
|
||||
|
||||
func TestCollectNoArg(t *testing.T) {
|
||||
func TestFindSingleArg(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
Config: config.Root{
|
||||
Resources: config.Resources{
|
||||
|
@ -31,28 +31,11 @@ func TestCollectNoArg(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
out, err := Collect(b, []string{})
|
||||
_, err := Find(b, "foo")
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, out, 1)
|
||||
}
|
||||
|
||||
func TestCollectNoArgMultipleResources(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
Config: config.Root{
|
||||
Resources: config.Resources{
|
||||
Jobs: map[string]*resources.Job{
|
||||
"foo": {},
|
||||
"bar": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := Collect(b, []string{})
|
||||
assert.ErrorContains(t, err, "bundle defines multiple resources")
|
||||
}
|
||||
|
||||
func TestCollectSingleArg(t *testing.T) {
|
||||
func TestFindSingleArgNotFound(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
Config: config.Root{
|
||||
Resources: config.Resources{
|
||||
|
@ -63,27 +46,11 @@ func TestCollectSingleArg(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
out, err := Collect(b, []string{"foo"})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, out, 1)
|
||||
}
|
||||
|
||||
func TestCollectSingleArgNotFound(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
Config: config.Root{
|
||||
Resources: config.Resources{
|
||||
Jobs: map[string]*resources.Job{
|
||||
"foo": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
_, err := Collect(b, []string{"bar"})
|
||||
_, err := Find(b, "bar")
|
||||
assert.ErrorContains(t, err, "no such resource: bar")
|
||||
}
|
||||
|
||||
func TestCollectSingleArgAmbiguous(t *testing.T) {
|
||||
func TestFindSingleArgAmbiguous(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
Config: config.Root{
|
||||
Resources: config.Resources{
|
||||
|
@ -97,11 +64,11 @@ func TestCollectSingleArgAmbiguous(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
_, err := Collect(b, []string{"key"})
|
||||
_, err := Find(b, "key")
|
||||
assert.ErrorContains(t, err, "ambiguous: ")
|
||||
}
|
||||
|
||||
func TestCollectSingleArgWithType(t *testing.T) {
|
||||
func TestFindSingleArgWithType(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
Config: config.Root{
|
||||
Resources: config.Resources{
|
||||
|
@ -112,27 +79,6 @@ func TestCollectSingleArgWithType(t *testing.T) {
|
|||
},
|
||||
}
|
||||
|
||||
out, err := Collect(b, []string{"jobs.key"})
|
||||
_, err := Find(b, "jobs.key")
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, out, 1)
|
||||
}
|
||||
|
||||
func TestCollectMultipleArg(t *testing.T) {
|
||||
b := &bundle.Bundle{
|
||||
Config: config.Root{
|
||||
Resources: config.Resources{
|
||||
Jobs: map[string]*resources.Job{
|
||||
"foo": {},
|
||||
"bar": {},
|
||||
},
|
||||
Pipelines: map[string]*resources.Pipeline{
|
||||
"qux": {},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
out, err := Collect(b, []string{"foo", "bar", "qux"})
|
||||
assert.NoError(t, err)
|
||||
assert.Len(t, out, 3)
|
||||
}
|
||||
|
|
|
@ -9,9 +9,10 @@ import (
|
|||
)
|
||||
|
||||
var runCmd = &cobra.Command{
|
||||
Use: "run [flags] KEY...",
|
||||
Use: "run [flags] KEY",
|
||||
Short: "Run a workload (e.g. a job or a pipeline)",
|
||||
|
||||
Args: cobra.ExactArgs(1),
|
||||
PreRunE: ConfigureBundle,
|
||||
RunE: func(cmd *cobra.Command, args []string) error {
|
||||
b := bundle.Get(cmd.Context())
|
||||
|
@ -24,16 +25,14 @@ var runCmd = &cobra.Command{
|
|||
return err
|
||||
}
|
||||
|
||||
runners, err := run.Collect(b, args)
|
||||
runner, err := run.Find(b, args[0])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
for _, runner := range runners {
|
||||
err = runner.Run(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
err = runner.Run(cmd.Context())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
|
|
Loading…
Reference in New Issue