From e3279b878042377181d54c8bea47aceb831f6fd1 Mon Sep 17 00:00:00 2001 From: Michael Brooks Date: Thu, 5 Mar 2026 16:21:28 -0800 Subject: [PATCH 1/2] refactor: remove logger from project create --- cmd/project/create.go | 84 ++---------------------------- cmd/project/create_test.go | 65 ++++++++++++----------- cmd/project/samples_test.go | 3 +- internal/pkg/create/create.go | 24 +++------ internal/pkg/create/create_test.go | 4 +- 5 files changed, 43 insertions(+), 137 deletions(-) diff --git a/cmd/project/create.go b/cmd/project/create.go index f73dec98..1d97b29b 100644 --- a/cmd/project/create.go +++ b/cmd/project/create.go @@ -23,7 +23,6 @@ import ( "time" "github.com/slackapi/slack-cli/internal/iostreams" - "github.com/slackapi/slack-cli/internal/logger" "github.com/slackapi/slack-cli/internal/pkg/create" "github.com/slackapi/slack-cli/internal/shared" "github.com/slackapi/slack-cli/internal/slackerror" @@ -45,9 +44,6 @@ var CreateFunc = create.Create var appCreateSpinner *style.Spinner -const copyTemplate = "Copying" -const cloneTemplate = "Cloning" - // promptObject describes the Github app template type promptObject struct { Title string // "Reverse string" @@ -93,9 +89,6 @@ name your app 'agent' (not create an AI Agent), use the --name flag instead.`, func runCreateCommand(clients *shared.ClientFactory, cmd *cobra.Command, args []string) error { ctx := cmd.Context() - // Set up event logger - log := newCreateLogger(clients, cmd) - // Get optional app name passed as an arg and check for category shortcuts appNameArg := "" categoryShortcut := "" @@ -177,88 +170,17 @@ func runCreateCommand(clients *shared.ClientFactory, cmd *cobra.Command, args [] } clients.EventTracker.SetAppTemplate(template.GetTemplatePath()) - appDirPath, err := CreateFunc(ctx, clients, log, createArgs) + appCreateSpinner.Update("Creating app from template", "").Start() + appDirPath, err := CreateFunc(ctx, clients, createArgs) if err != nil { printAppCreateError(clients, cmd, err) return err } + appCreateSpinner.Update(style.Sectionf(style.TextSection{Emoji: "gear", Text: "Created project directory"}), "").Stop() printCreateSuccess(ctx, clients, appDirPath) return nil } -/* -App creation is setting up local project directory -Events: on_app_create_completion -*/ - -// newCreateLogger creates a logger instance to receive event notifications -func newCreateLogger(clients *shared.ClientFactory, cmd *cobra.Command) *logger.Logger { - return logger.New( - // OnEvent - func(event *logger.LogEvent) { - switch event.Name { - case "on_app_create_template_default": - printAppCreateDefaultemplate(cmd, event) - case "on_app_create_template_custom": - printAppCreateCustomTemplate(cmd, event) - case "on_app_create_completion": - printProjectCreateCompletion(clients, cmd, event) - default: - // Ignore the event - } - }, - ) -} - -/* -App creation (not Create command) is cloning the template and creating the project directory -Events: on_app_create_template_custom, on_app_create_completion -*/ - -func printAppCreateDefaultemplate(cmd *cobra.Command, event *logger.LogEvent) { - startAppCreateSpinner(copyTemplate) -} - -// Print template URL if using custom app template -func printAppCreateCustomTemplate(cmd *cobra.Command, event *logger.LogEvent) { - var verb string - templatePath := event.DataToString("templatePath") - isGit := event.DataToBool("isGit") - gitBranch := event.DataToString("gitBranch") - - if isGit { - verb = cloneTemplate - } else { - verb = copyTemplate - } - templateText := fmt.Sprintf( - "%s template from %s", - verb, - templatePath, - ) - - if gitBranch != "" { - templateText = fmt.Sprintf("%s (branch: %s)", templateText, gitBranch) - } - - cmd.Print(style.Secondary(templateText), "\n\n") - - startAppCreateSpinner(verb) -} - -func startAppCreateSpinner(verb string) { - appCreateSpinner.Update(verb+" app template", "").Start() -} - -// Display message and added files at completion of app creation -func printProjectCreateCompletion(clients *shared.ClientFactory, cmd *cobra.Command, event *logger.LogEvent) { - createCompletionText := style.Sectionf(style.TextSection{ - Emoji: "gear", - Text: "Created project directory", - }) - appCreateSpinner.Update(createCompletionText, "").Stop() -} - // printCreateSuccess outputs an informative message after creating a new app func printCreateSuccess(ctx context.Context, clients *shared.ClientFactory, appPath string) { // Check if this is a Deno project to conditionally enable some features diff --git a/cmd/project/create_test.go b/cmd/project/create_test.go index 37d83102..64604d50 100644 --- a/cmd/project/create_test.go +++ b/cmd/project/create_test.go @@ -20,7 +20,6 @@ import ( "github.com/slackapi/slack-cli/internal/config" "github.com/slackapi/slack-cli/internal/iostreams" - "github.com/slackapi/slack-cli/internal/logger" "github.com/slackapi/slack-cli/internal/pkg/create" "github.com/slackapi/slack-cli/internal/shared" "github.com/slackapi/slack-cli/internal/slackerror" @@ -35,8 +34,8 @@ type CreateClientMock struct { mock.Mock } -func (m *CreateClientMock) Create(ctx context.Context, clients *shared.ClientFactory, log *logger.Logger, createArgs create.CreateArgs) (string, error) { - args := m.Called(ctx, clients, log, createArgs) +func (m *CreateClientMock) Create(ctx context.Context, clients *shared.ClientFactory, createArgs create.CreateArgs) (string, error) { + args := m.Called(ctx, clients, createArgs) return args.String(0), args.Error(1) } @@ -66,7 +65,7 @@ func TestCreateCommand(t *testing.T) { cm.IO.On("InputPrompt", mock.Anything, "Name your app:", mock.Anything). Return("my-app", nil) createClientMock = new(CreateClientMock) - createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", nil) + createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything).Return("", nil) CreateFunc = createClientMock.Create }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { @@ -76,7 +75,7 @@ func TestCreateCommand(t *testing.T) { AppName: "my-app", Template: template, } - createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, expected) + createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, expected) cm.IO.AssertCalled(t, "InputPrompt", mock.Anything, "Name your app:", mock.Anything) }, }, @@ -103,7 +102,7 @@ func TestCreateCommand(t *testing.T) { cm.IO.On("InputPrompt", mock.Anything, "Name your app:", mock.Anything). Return("my-deno-app", nil) createClientMock = new(CreateClientMock) - createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", nil) + createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything).Return("", nil) CreateFunc = createClientMock.Create }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { @@ -113,7 +112,7 @@ func TestCreateCommand(t *testing.T) { AppName: "my-deno-app", Template: template, } - createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, expected) + createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, expected) cm.IO.AssertCalled(t, "InputPrompt", mock.Anything, "Name your app:", mock.Anything) }, }, @@ -133,7 +132,7 @@ func TestCreateCommand(t *testing.T) { cm.IO.On("InputPrompt", mock.Anything, "Name your app:", mock.Anything). Return("my-agent", nil) createClientMock = new(CreateClientMock) - createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", nil) + createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything).Return("", nil) CreateFunc = createClientMock.Create }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { @@ -143,7 +142,7 @@ func TestCreateCommand(t *testing.T) { AppName: "my-agent", Template: template, } - createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, expected) + createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, expected) // Verify that category prompt was NOT called cm.IO.AssertNotCalled(t, "SelectPrompt", mock.Anything, "Select an app:", mock.Anything, mock.Anything) cm.IO.AssertCalled(t, "InputPrompt", mock.Anything, "Name your app:", mock.Anything) @@ -162,7 +161,7 @@ func TestCreateCommand(t *testing.T) { nil, ) createClientMock = new(CreateClientMock) - createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", nil) + createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything).Return("", nil) CreateFunc = createClientMock.Create }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { @@ -172,7 +171,7 @@ func TestCreateCommand(t *testing.T) { AppName: "my-agent-app", Template: template, } - createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, expected) + createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, expected) // Verify that category prompt was NOT called cm.IO.AssertNotCalled(t, "SelectPrompt", mock.Anything, "Select an app:", mock.Anything, mock.Anything) // Verify that name prompt was NOT called since name was provided as arg @@ -199,7 +198,7 @@ func TestCreateCommand(t *testing.T) { nil, ) createClientMock = new(CreateClientMock) - createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", nil) + createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything).Return("", nil) CreateFunc = createClientMock.Create }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { @@ -209,7 +208,7 @@ func TestCreateCommand(t *testing.T) { AppName: "agent", Template: template, } - createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, expected) + createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, expected) // Verify that name prompt was NOT called since name was provided as arg cm.IO.AssertNotCalled(t, "InputPrompt", mock.Anything, "Name your app:", mock.Anything) }, @@ -235,7 +234,7 @@ func TestCreateCommand(t *testing.T) { nil, ) createClientMock = new(CreateClientMock) - createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", nil) + createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything).Return("", nil) CreateFunc = createClientMock.Create }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { @@ -245,7 +244,7 @@ func TestCreateCommand(t *testing.T) { AppName: "agent", Template: template, } - createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, expected) + createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, expected) // Verify that category prompt WAS called (shortcut was not triggered) cm.IO.AssertCalled(t, "SelectPrompt", mock.Anything, "Select an app:", mock.Anything, mock.Anything) // Verify that name prompt was NOT called since --name flag was provided @@ -265,7 +264,7 @@ func TestCreateCommand(t *testing.T) { nil, ) createClientMock = new(CreateClientMock) - createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", nil) + createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything).Return("", nil) CreateFunc = createClientMock.Create }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { @@ -275,7 +274,7 @@ func TestCreateCommand(t *testing.T) { AppName: "my-custom-name", // --name flag overrides Template: template, } - createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, expected) + createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, expected) // Verify that category prompt was NOT called (shortcut was triggered) cm.IO.AssertNotCalled(t, "SelectPrompt", mock.Anything, "Select an app:", mock.Anything, mock.Anything) }, @@ -300,7 +299,7 @@ func TestCreateCommand(t *testing.T) { nil, ) createClientMock = new(CreateClientMock) - createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", nil) + createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything).Return("", nil) CreateFunc = createClientMock.Create }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { @@ -310,7 +309,7 @@ func TestCreateCommand(t *testing.T) { AppName: "my-name", // --name flag overrides "my-project" positional arg Template: template, } - createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, expected) + createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, expected) // Verify that name prompt was NOT called since --name flag was provided cm.IO.AssertNotCalled(t, "InputPrompt", mock.Anything, "Name your app:", mock.Anything) }, @@ -328,7 +327,7 @@ func TestCreateCommand(t *testing.T) { nil, ) createClientMock = new(CreateClientMock) - createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", nil) + createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything).Return("", nil) CreateFunc = createClientMock.Create }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { @@ -338,7 +337,7 @@ func TestCreateCommand(t *testing.T) { AppName: "my-name", // --name flag overrides "my-project" positional arg Template: template, } - createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, expected) + createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, expected) // Verify that category prompt was NOT called (agent shortcut was triggered) cm.IO.AssertNotCalled(t, "SelectPrompt", mock.Anything, "Select an app:", mock.Anything, mock.Anything) // Verify that name prompt was NOT called since --name flag was provided @@ -368,13 +367,13 @@ func TestCreateCommand(t *testing.T) { cm.IO.On("InputPrompt", mock.Anything, "Name your app:", mock.Anything). Return("", nil) createClientMock = new(CreateClientMock) - createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", nil) + createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything).Return("", nil) CreateFunc = createClientMock.Create }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { cm.IO.AssertCalled(t, "InputPrompt", mock.Anything, "Name your app:", mock.Anything) // When the user accepts the default (empty return), the generated name is used - createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, mock.MatchedBy(func(args create.CreateArgs) bool { + createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.MatchedBy(func(args create.CreateArgs) bool { return args.AppName != "" })) }, @@ -400,14 +399,14 @@ func TestCreateCommand(t *testing.T) { nil, ) createClientMock = new(CreateClientMock) - createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", nil) + createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything).Return("", nil) CreateFunc = createClientMock.Create }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { // Should NOT prompt for name since not a TTY cm.IO.AssertNotCalled(t, "InputPrompt", mock.Anything, "Name your app:", mock.Anything) // Should still call Create with a non-empty generated name - createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, mock.MatchedBy(func(args create.CreateArgs) bool { + createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.MatchedBy(func(args create.CreateArgs) bool { return args.AppName != "" })) }, @@ -432,7 +431,7 @@ func TestCreateCommand(t *testing.T) { nil, ) createClientMock = new(CreateClientMock) - createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", nil) + createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything).Return("", nil) CreateFunc = createClientMock.Create }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { @@ -442,7 +441,7 @@ func TestCreateCommand(t *testing.T) { AppName: "my-project", Template: template, } - createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, expected) + createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, expected) // Verify that name prompt was NOT called since name was provided as positional arg cm.IO.AssertNotCalled(t, "InputPrompt", mock.Anything, "Name your app:", mock.Anything) }, @@ -455,7 +454,7 @@ func TestCreateCommand(t *testing.T) { }, ExpectedErrorStrings: []string{"The --subdir flag requires the --template flag"}, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { - createClientMock.AssertNotCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything) + createClientMock.AssertNotCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything) }, }, "passes subdir flag to create function": { @@ -478,13 +477,13 @@ func TestCreateCommand(t *testing.T) { nil, ) createClientMock = new(CreateClientMock) - createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return("", nil) + createClientMock.On("Create", mock.Anything, mock.Anything, mock.Anything).Return("", nil) CreateFunc = createClientMock.Create }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { template, err := create.ResolveTemplateURL("slack-samples/bolt-js-starter-template") require.NoError(t, err) - createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, mock.MatchedBy(func(args create.CreateArgs) bool { + createClientMock.AssertCalled(t, "Create", mock.Anything, mock.Anything, mock.MatchedBy(func(args create.CreateArgs) bool { return args.AppName != "" && args.Template == template && args.Subdir == "apps/my-app" })) }, @@ -499,7 +498,7 @@ func TestCreateCommand(t *testing.T) { "Getting started", }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { - createClientMock.AssertNotCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything) + createClientMock.AssertNotCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything) }, }, "lists all templates with --list flag": { @@ -521,7 +520,7 @@ func TestCreateCommand(t *testing.T) { "slack-samples/deno-starter-template", }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { - createClientMock.AssertNotCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything) + createClientMock.AssertNotCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything) }, }, "lists agent templates with agent --list flag": { @@ -536,7 +535,7 @@ func TestCreateCommand(t *testing.T) { "slack-samples/bolt-python-assistant-template", }, ExpectedAsserts: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock) { - createClientMock.AssertNotCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything, mock.Anything) + createClientMock.AssertNotCalled(t, "Create", mock.Anything, mock.Anything, mock.Anything) output := cm.GetCombinedOutput() assert.NotContains(t, output, "Getting started") assert.NotContains(t, output, "Automation apps") diff --git a/cmd/project/samples_test.go b/cmd/project/samples_test.go index c3eedbae..3cdc3d3d 100644 --- a/cmd/project/samples_test.go +++ b/cmd/project/samples_test.go @@ -19,7 +19,6 @@ import ( "testing" "github.com/slackapi/slack-cli/internal/iostreams" - "github.com/slackapi/slack-cli/internal/logger" createPkg "github.com/slackapi/slack-cli/internal/pkg/create" "github.com/slackapi/slack-cli/internal/shared" "github.com/slackapi/slack-cli/test/testutil" @@ -72,7 +71,7 @@ func TestSamplesCommand(t *testing.T) { }, nil, ) - CreateFunc = func(ctx context.Context, clients *shared.ClientFactory, log *logger.Logger, createArgs createPkg.CreateArgs) (appDirPath string, err error) { + CreateFunc = func(ctx context.Context, clients *shared.ClientFactory, createArgs createPkg.CreateArgs) (appDirPath string, err error) { return createArgs.AppName, nil } }, diff --git a/internal/pkg/create/create.go b/internal/pkg/create/create.go index ee079fb3..079626ff 100644 --- a/internal/pkg/create/create.go +++ b/internal/pkg/create/create.go @@ -34,7 +34,6 @@ import ( "github.com/slackapi/slack-cli/internal/deputil" "github.com/slackapi/slack-cli/internal/experiment" "github.com/slackapi/slack-cli/internal/goutils" - "github.com/slackapi/slack-cli/internal/logger" "github.com/slackapi/slack-cli/internal/shared" "github.com/slackapi/slack-cli/internal/slackerror" "github.com/slackapi/slack-cli/internal/slackhttp" @@ -58,7 +57,7 @@ type CreateArgs struct { } // Create will create a new Slack app on the file system and app manifest on the Slack API. -func Create(ctx context.Context, clients *shared.ClientFactory, log *logger.Logger, createArgs CreateArgs) (appDirPath string, err error) { +func Create(ctx context.Context, clients *shared.ClientFactory, createArgs CreateArgs) (appDirPath string, err error) { span, ctx := opentracing.StartSpanFromContext(ctx, "cmd.create") defer span.Finish() @@ -132,11 +131,11 @@ func Create(ctx context.Context, clients *shared.ClientFactory, log *logger.Logg } if subdir != "" { - if err := createAppFromSubdir(ctx, projectDirPath, createArgs.Template, createArgs.GitBranch, subdir, log, clients.Fs); err != nil { + if err := createAppFromSubdir(ctx, projectDirPath, createArgs.Template, createArgs.GitBranch, subdir, clients.Fs); err != nil { return "", slackerror.Wrap(err, slackerror.ErrAppCreate) } } else { - if err := createApp(ctx, projectDirPath, createArgs.Template, createArgs.GitBranch, log, clients.Fs); err != nil { + if err := createApp(ctx, projectDirPath, createArgs.Template, createArgs.GitBranch, clients.Fs); err != nil { return "", slackerror.Wrap(err, slackerror.ErrAppCreate) } } @@ -160,9 +159,6 @@ func Create(ctx context.Context, clients *shared.ClientFactory, log *logger.Logg InstallProjectDependencies(ctx, clients, projectDirPath, config.ManifestSourceLocal) clients.IO.PrintTrace(ctx, slacktrace.CreateDependenciesSuccess) - // Notify listeners that app directory is created - log.Log("info", "on_app_create_completion") - return appDirPath, nil } @@ -222,15 +218,7 @@ func parentDirExists(dirPath string) (bool, error) { } // createApp will create the app directory using the default app template or a specified template URL. -func createApp(ctx context.Context, dirPath string, template Template, gitBranch string, log *logger.Logger, fs afero.Fs) error { - log.Data["templatePath"] = template.path - log.Data["isGit"] = template.isGit - log.Data["gitBranch"] = gitBranch - log.Data["isSample"] = template.IsSample() - - // Notify listeners - log.Log("info", "on_app_create_template") - +func createApp(ctx context.Context, dirPath string, template Template, gitBranch string, fs afero.Fs) error { if template.isGit { doctorSection, err := doctor.CheckGit(ctx) if doctorSection.HasError() || err != nil { @@ -369,7 +357,7 @@ func normalizeSubdir(subdir string) (string, error) { // createAppFromSubdir clones the full template into a temp directory, then copies // only the specified subdirectory to the final project path. -func createAppFromSubdir(ctx context.Context, dirPath string, template Template, gitBranch string, subdir string, log *logger.Logger, fs afero.Fs) error { +func createAppFromSubdir(ctx context.Context, dirPath string, template Template, gitBranch string, subdir string, fs afero.Fs) error { tmpDirRoot := afero.GetTempDir(fs, "") tmpDir, err := afero.TempDir(fs, tmpDirRoot, "slack-create-") if err != nil { @@ -378,7 +366,7 @@ func createAppFromSubdir(ctx context.Context, dirPath string, template Template, defer func() { _ = fs.RemoveAll(tmpDir) }() cloneDir := filepath.Join(tmpDir, "repo") - if err := createApp(ctx, cloneDir, template, gitBranch, log, fs); err != nil { + if err := createApp(ctx, cloneDir, template, gitBranch, fs); err != nil { return err } diff --git a/internal/pkg/create/create_test.go b/internal/pkg/create/create_test.go index baaa5583..37ff3063 100644 --- a/internal/pkg/create/create_test.go +++ b/internal/pkg/create/create_test.go @@ -22,7 +22,6 @@ import ( "github.com/slackapi/slack-cli/internal/config" "github.com/slackapi/slack-cli/internal/experiment" - "github.com/slackapi/slack-cli/internal/logger" "github.com/slackapi/slack-cli/internal/shared" "github.com/slackapi/slack-cli/internal/slackcontext" "github.com/slackapi/slack-cli/internal/slackhttp" @@ -301,9 +300,8 @@ func TestCreateAppFromSubdir(t *testing.T) { require.NoError(t, fs.Remove(outputDir)) template := Template{path: templateDir, isLocal: true} - log := logger.New(func(event *logger.LogEvent) {}) - err := createAppFromSubdir(t.Context(), outputDir, template, "", tc.subdir, log, fs) + err := createAppFromSubdir(t.Context(), outputDir, template, "", tc.subdir, fs) if tc.expectError { assert.Error(t, err) From 61491499beb7e0ccd04a404d41b752def0e9ab0e Mon Sep 17 00:00:00 2001 From: Michael Brooks Date: Fri, 6 Mar 2026 14:43:25 -0800 Subject: [PATCH 2/2] refactor: remove unused spinner in create --- .claude/CLAUDE.md | 4 ++++ cmd/project/create.go | 21 +-------------------- 2 files changed, 5 insertions(+), 20 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index bd7ab6c6..14a63f2e 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -31,6 +31,10 @@ make lint # Run golangci-lint golangci-lint --version # Verify linter version ``` +### Formatting + +Always run `gofmt -w` on changed Go files after making edits to ensure proper formatting. + ### Other Commands ```bash diff --git a/cmd/project/create.go b/cmd/project/create.go index 1d97b29b..8836a345 100644 --- a/cmd/project/create.go +++ b/cmd/project/create.go @@ -42,8 +42,6 @@ var createSubdirFlag string // TODO - Find best practice, such as using an Interface and Struct to create a client var CreateFunc = create.Create -var appCreateSpinner *style.Spinner - // promptObject describes the Github app template type promptObject struct { Title string // "Reverse string" @@ -159,9 +157,6 @@ func runCreateCommand(clients *shared.ClientFactory, cmd *cobra.Command, args [] } } - // Set up spinners - appCreateSpinner = style.NewSpinner(cmd.OutOrStdout()) - createArgs := create.CreateArgs{ AppName: appNameArg, Template: template, @@ -170,13 +165,11 @@ func runCreateCommand(clients *shared.ClientFactory, cmd *cobra.Command, args [] } clients.EventTracker.SetAppTemplate(template.GetTemplatePath()) - appCreateSpinner.Update("Creating app from template", "").Start() appDirPath, err := CreateFunc(ctx, clients, createArgs) if err != nil { - printAppCreateError(clients, cmd, err) return err } - appCreateSpinner.Update(style.Sectionf(style.TextSection{Emoji: "gear", Text: "Created project directory"}), "").Stop() + printCreateSuccess(ctx, clients, appDirPath) return nil } @@ -240,15 +233,3 @@ func generateRandomAppName() string { var randomName = fmt.Sprintf("%s-%s-%d", create.Adjectives[firstRandomNum], create.Animals[secondRandomNum], rand.Intn(1000)) return randomName } - -// printAppCreateError stops the creation spinners and displays the returned error message -func printAppCreateError(clients *shared.ClientFactory, cmd *cobra.Command, err error) { - ctx := cmd.Context() - switch { - case appCreateSpinner.Active(): - errorText := fmt.Sprintf("Error creating project directory: %s", err) - appCreateSpinner.Update(errorText, "warning").Stop() - default: - } - clients.IO.PrintTrace(ctx, slacktrace.CreateError) -}