diff --git a/command/status.go b/command/status.go index c9774f447..6553c721e 100644 --- a/command/status.go +++ b/command/status.go @@ -103,14 +103,18 @@ func (c *StatusCommand) Run(args []string) int { var match contexts.Context matchCount := 0 for ctx, vers := range res.Matches { - if len(vers) == 1 { + if l := len(vers); l == 1 { match = ctx matchCount++ + } else if l > 0 && vers[0] == id { + // Exact match + match = ctx + break } // Only a single result should return, as this is a match against a full id if matchCount > 1 || len(vers) > 1 { - c.Ui.Error(fmt.Sprintf("Multiple matches found for id %q", id)) + c.outputMultipleMatches(id, res.Matches) return 1 } } @@ -134,3 +138,15 @@ func (c *StatusCommand) Run(args []string) int { return cmd.Run(argsCopy) } + +func (c *StatusCommand) outputMultipleMatches(id string, matches map[contexts.Context][]string) { + c.Ui.Error(fmt.Sprintf("Multiple matches found for id %q", id)) + for ctx, vers := range matches { + if len(vers) == 0 { + continue + } + + c.Ui.Error(fmt.Sprintf("\n%s:", strings.Title(string(ctx)))) + c.Ui.Error(fmt.Sprintf("%s", strings.Join(vers, ", "))) + } +} diff --git a/command/status_test.go b/command/status_test.go index a25f6abb4..4b7f1c38f 100644 --- a/command/status_test.go +++ b/command/status_test.go @@ -39,6 +39,35 @@ func TestStatusCommand_Run_JobStatus(t *testing.T) { ui.OutputWriter.Reset() } +func TestStatusCommand_Run_JobStatus_MultiMatch(t *testing.T) { + assert := assert.New(t) + t.Parallel() + + srv, _, url := testServer(t, true, nil) + defer srv.Shutdown() + + ui := new(cli.MockUi) + cmd := &StatusCommand{Meta: Meta{Ui: ui, flagAddress: url}} + + // Create two fake jobs sharing a prefix + state := srv.Agent.Server().State() + j := mock.Job() + j2 := mock.Job() + j2.ID = fmt.Sprintf("%s-more", j.ID) + assert.Nil(state.UpsertJob(1000, j)) + assert.Nil(state.UpsertJob(1001, j2)) + + // Query to check the job status + if code := cmd.Run([]string{"-address=" + url, j.ID}); code != 0 { + t.Fatalf("expected exit 0, got: %d", code) + } + + out := ui.OutputWriter.String() + assert.Contains(out, j.ID) + + ui.OutputWriter.Reset() +} + func TestStatusCommand_Run_EvalStatus(t *testing.T) { assert := assert.New(t) t.Parallel()