From 487d527ee7c92eae17c7f6d5d6f6baf8c674a8e9 Mon Sep 17 00:00:00 2001 From: Levi Whalen Date: Mon, 3 Aug 2026 10:52:53 -0600 Subject: [PATCH] added new --app-id flag to application select --- pkg/cmd/application/selectapp/select.go | 18 ++++- pkg/cmd/application/selectapp/select_test.go | 69 ++++++++++++++++++-- 2 files changed, 82 insertions(+), 5 deletions(-) diff --git a/pkg/cmd/application/selectapp/select.go b/pkg/cmd/application/selectapp/select.go index 319c47f9..34661c5c 100644 --- a/pkg/cmd/application/selectapp/select.go +++ b/pkg/cmd/application/selectapp/select.go @@ -21,6 +21,7 @@ type SelectOptions struct { IO *iostreams.IOStreams Config config.IConfig + AppID string AppName string NewDashboardClient func(clientID string) *dashboard.Client @@ -49,6 +50,9 @@ func NewSelectCmd(f *cmdutil.Factory) *cobra.Command { # Select by name (non-interactive) $ algolia application select --app-name "My App" + + # Select by application ID (non-interactive) + $ algolia application select --app-id "ABCDEF1234" `), Aliases: []string{"use"}, Args: validators.NoArgs(), @@ -61,8 +65,11 @@ func NewSelectCmd(f *cmdutil.Factory) *cobra.Command { }, } + cmd.Flags(). + StringVar(&opts.AppID, "app-id", "", "Select application by ID (non-interactive)") cmd.Flags(). StringVar(&opts.AppName, "app-name", "", "Select application by name (non-interactive)") + cmd.MarkFlagsMutuallyExclusive("app-id", "app-name") return cmd } @@ -143,6 +150,15 @@ func pickApplication( opts *SelectOptions, apps []dashboard.Application, ) (*dashboard.Application, error) { + if opts.AppID != "" { + for i := range apps { + if apps[i].ID == opts.AppID { + return &apps[i], nil + } + } + return nil, fmt.Errorf("application with ID %q not found", opts.AppID) + } + if opts.AppName != "" { for i := range apps { if apps[i].Name == opts.AppName { @@ -153,7 +169,7 @@ func pickApplication( } if !opts.IO.CanPrompt() { - return nil, fmt.Errorf("--app-name is required in non-interactive mode") + return nil, fmt.Errorf("--app-id or --app-name is required in non-interactive mode") } cs := opts.IO.ColorScheme() diff --git a/pkg/cmd/application/selectapp/select_test.go b/pkg/cmd/application/selectapp/select_test.go index bc42da94..783156f6 100644 --- a/pkg/cmd/application/selectapp/select_test.go +++ b/pkg/cmd/application/selectapp/select_test.go @@ -64,19 +64,33 @@ func selectServer(t *testing.T, createHit *bool) *httptest.Server { } func newSelectOpts(t *testing.T, srv *httptest.Server, cfg *test.ConfigStub) *SelectOptions { + t.Helper() + // --app-name bypasses the interactive picker. + return newSelectOptsWithSelector(t, srv, cfg, func(opts *SelectOptions) { + opts.AppName = "My App" + }) +} + +func newSelectOptsWithSelector( + t *testing.T, + srv *httptest.Server, + cfg *test.ConfigStub, + selector func(*SelectOptions), +) *SelectOptions { t.Helper() seedToken(t) io, _, _, _ := iostreams.Test() - return &SelectOptions{ - IO: io, - Config: cfg, - AppName: "My App", // bypasses the interactive picker + opts := &SelectOptions{ + IO: io, + Config: cfg, NewDashboardClient: func(string) *dashboard.Client { c := dashboard.NewClientWithHTTPClient("test", srv.Client()) c.APIURL = srv.URL return c }, } + selector(opts) + return opts } func Test_runSelectCmd_RegeneratesKeyWhenNoUUID(t *testing.T) { @@ -122,3 +136,50 @@ func Test_runSelectCmd_ReusesKeyWhenUUIDPresent(t *testing.T) { assert.False(t, createHit, "expected no new key when a UUID is already stored") assert.Equal(t, "existing-uuid", cfg.SavedApps["APP1"].APIKeyUUID) } + +func Test_runSelectCmd_SelectsByAppID(t *testing.T) { + createHit := false + srv := selectServer(t, &createHit) + defer srv.Close() + + cfg := &test.ConfigStub{} + opts := newSelectOptsWithSelector(t, srv, cfg, func(o *SelectOptions) { + o.AppID = "APP1" + }) + + app, err := runSelectCmd(opts) + require.NoError(t, err) + require.NotNil(t, app) + + assert.Equal(t, "APP1", app.ID) + assert.Equal(t, "My App", app.Name) + assert.Equal(t, "new-key", cfg.SavedApps["APP1"].APIKey) +} + +func Test_runSelectCmd_UnknownAppID(t *testing.T) { + createHit := false + srv := selectServer(t, &createHit) + defer srv.Close() + + opts := newSelectOptsWithSelector(t, srv, &test.ConfigStub{}, func(o *SelectOptions) { + o.AppID = "NOPE" + }) + + _, err := runSelectCmd(opts) + require.Error(t, err) + assert.Equal(t, `application with ID "NOPE" not found`, err.Error()) + assert.False(t, createHit) +} + +func Test_runSelectCmd_RequiresSelectorWhenNonInteractive(t *testing.T) { + createHit := false + srv := selectServer(t, &createHit) + defer srv.Close() + + // iostreams.Test() is not a TTY, so the picker is unavailable. + opts := newSelectOptsWithSelector(t, srv, &test.ConfigStub{}, func(*SelectOptions) {}) + + _, err := runSelectCmd(opts) + require.Error(t, err) + assert.Equal(t, "--app-id or --app-name is required in non-interactive mode", err.Error()) +}