Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion cmd/app/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,9 @@ func NewCommand(clients *shared.ClientFactory) *cobra.Command {
return runListCommand(cmd, clients)
},
PostRunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
if cmd.CalledAs() == "workspace" {
clients.IO.PrintInfo(cmd.Context(), false, fmt.Sprintf(
clients.IO.PrintInfo(ctx, false, fmt.Sprintf(
Comment on lines +49 to +51
Copy link
Member Author

@mwbrooks mwbrooks Apr 11, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: I think this is a better pattern and I remember @zimeg has also asked that we reduce the amount of arguments that are functions calls. The main benefit is that other functions in the code block can use the same context ctx ensuring more consistency through the code.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed too you're updating it to be a first declaration in a function, which I'm so much a fan of too 🙏 ✨

In later comments you note that we often avoid modifying ctx as well and I think this makes it more clear that it's meant to be more of a function argument and not a variable to change 😉

"\n%s It looks like you used %s. This command will be deprecated in an upcoming release.\n You can now use %s instead of %s.\n ",
style.Emoji("bulb"),
style.Commandf("workspace", true),
Expand Down
23 changes: 11 additions & 12 deletions cmd/app/link_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ func Test_Apps_Link(t *testing.T) {
mockLinkSlackAuth1,
}, nil)
cm.AddDefaultMocks()
setupAppLinkCommandMocks(t, cm, cf)
setupAppLinkCommandMocks(t, ctx, cm, cf)
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: This catches a .Setup(t *testing.T, ctx context.Context, ...) that provides the ctx. We can now use it instead of setupAppLinkCommandMocks(...) creating a non-mocked context.

cm.IO.On("SelectPrompt",
mock.Anything,
"Select the existing app team",
Expand Down Expand Up @@ -118,7 +118,7 @@ func Test_Apps_Link(t *testing.T) {
mockLinkSlackAuth1,
}, nil)
cm.AddDefaultMocks()
setupAppLinkCommandMocks(t, cm, cf)
setupAppLinkCommandMocks(t, ctx, cm, cf)
cm.IO.On("SelectPrompt",
mock.Anything,
"Select the existing app team",
Expand Down Expand Up @@ -177,7 +177,7 @@ func Test_Apps_Link(t *testing.T) {
mockLinkSlackAuth2,
}, nil)
cm.AddDefaultMocks()
setupAppLinkCommandMocks(t, cm, cf)
setupAppLinkCommandMocks(t, ctx, cm, cf)
existingApp := types.App{
AppID: mockLinkAppID1,
TeamDomain: mockLinkSlackAuth1.TeamDomain,
Expand Down Expand Up @@ -246,7 +246,7 @@ func Test_Apps_Link(t *testing.T) {
mockLinkSlackAuth2,
}, nil)
cm.AddDefaultMocks()
setupAppLinkCommandMocks(t, cm, cf)
setupAppLinkCommandMocks(t, ctx, cm, cf)
existingApp := types.App{
AppID: mockLinkAppID1,
TeamDomain: mockLinkSlackAuth1.TeamDomain,
Expand Down Expand Up @@ -321,7 +321,7 @@ func Test_Apps_Link(t *testing.T) {
mockLinkSlackAuth2,
}, nil)
cm.AddDefaultMocks()
setupAppLinkCommandMocks(t, cm, cf)
setupAppLinkCommandMocks(t, ctx, cm, cf)
existingApp := types.App{
AppID: mockLinkAppID2,
TeamDomain: mockLinkSlackAuth2.TeamDomain,
Expand Down Expand Up @@ -389,7 +389,7 @@ func Test_Apps_Link(t *testing.T) {
mockLinkSlackAuth2,
}, nil)
cm.AddDefaultMocks()
setupAppLinkCommandMocks(t, cm, cf)
setupAppLinkCommandMocks(t, ctx, cm, cf)
cm.IO.On("SelectPrompt",
mock.Anything,
"Select the existing app team",
Expand Down Expand Up @@ -437,9 +437,9 @@ func Test_Apps_Link(t *testing.T) {
mockLinkSlackAuth1,
}, nil)
cm.AddDefaultMocks()
setupAppLinkCommandMocks(t, cm, cf)
setupAppLinkCommandMocks(t, ctx, cm, cf)
// Set manifest source to project to trigger confirmation prompt
if err := cm.Config.ProjectConfig.SetManifestSource(t.Context(), config.MANIFEST_SOURCE_LOCAL); err != nil {
if err := cm.Config.ProjectConfig.SetManifestSource(ctx, config.MANIFEST_SOURCE_LOCAL); err != nil {
require.FailNow(t, fmt.Sprintf("Failed to set the manifest source in the memory-based file system: %s", err))
}
// Accept manifest source confirmation prompt
Expand Down Expand Up @@ -506,9 +506,9 @@ func Test_Apps_Link(t *testing.T) {
"decline manifest source prompt should not link app": {
Setup: func(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) {
cm.AddDefaultMocks()
setupAppLinkCommandMocks(t, cm, cf)
setupAppLinkCommandMocks(t, ctx, cm, cf)
// Set manifest source to project to trigger confirmation prompt
if err := cm.Config.ProjectConfig.SetManifestSource(t.Context(), config.MANIFEST_SOURCE_LOCAL); err != nil {
if err := cm.Config.ProjectConfig.SetManifestSource(ctx, config.MANIFEST_SOURCE_LOCAL); err != nil {
require.FailNow(t, fmt.Sprintf("Failed to set the manifest source in the memory-based file system: %s", err))
}
// Decline manifest source confirmation prompt
Expand Down Expand Up @@ -593,8 +593,7 @@ func Test_Apps_LinkAppHeaderSection(t *testing.T) {
}
}

func setupAppLinkCommandMocks(t *testing.T, cm *shared.ClientsMock, cf *shared.ClientFactory) {
ctx := t.Context()
func setupAppLinkCommandMocks(t *testing.T, ctx context.Context, cm *shared.ClientsMock, cf *shared.ClientFactory) {
projectDirPath := slackdeps.MockWorkingDirectory
cm.Os.On("Getwd").Return(projectDirPath, nil)

Expand Down
12 changes: 8 additions & 4 deletions cmd/auth/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,8 +51,9 @@ func NewListCommand(clients *shared.ClientFactory) *cobra.Command {

// runListCommand will execute the list command
func runListCommand(cmd *cobra.Command, clients *shared.ClientFactory) error {
ctx := cmd.Context()
log := newListLogger(cmd, clients.IO)
userAuthList, err := listFunc(cmd.Context(), clients, log)
userAuthList, err := listFunc(ctx, clients, log)
if err != nil {
return err
}
Expand Down Expand Up @@ -87,6 +88,8 @@ func newListLogger(cmd *cobra.Command, IO iostreams.IOStreamer) *logger.Logger {
// API Host: https://dev.slack.com (optional, only shown for custom API Hosts)
// Last Updated: 2021-03-12 11:18:00 -0700
func printAuthList(cmd *cobra.Command, IO iostreams.IOStreamer, userAuthList []types.SlackAuth) {
ctx := cmd.Context()

// Based on loosely on time.RFC3339
timeFormat := "2006-01-02 15:04:05 Z07:00"

Expand Down Expand Up @@ -121,7 +124,7 @@ func printAuthList(cmd *cobra.Command, IO iostreams.IOStreamer, userAuthList []t
cmd.Println()

// Print a trace with info about the authorization
IO.PrintTrace(cmd.Context(), slacktrace.AuthListInfo, authInfo.UserID, authInfo.TeamID)
IO.PrintTrace(ctx, slacktrace.AuthListInfo, authInfo.UserID, authInfo.TeamID)
}

// When there are no authorizations
Expand All @@ -130,11 +133,12 @@ func printAuthList(cmd *cobra.Command, IO iostreams.IOStreamer, userAuthList []t
}

// Print a trace with the total number of authorized workspaces
IO.PrintTrace(cmd.Context(), slacktrace.AuthListCount, fmt.Sprint(len(userAuthList)))
IO.PrintTrace(ctx, slacktrace.AuthListCount, fmt.Sprint(len(userAuthList)))
}

// printAuthListSuccess is displayed at the very end and helps guide the developer toward next steps.
func printAuthListSuccess(cmd *cobra.Command, IO iostreams.IOStreamer, userAuthList []types.SlackAuth) {
ctx := cmd.Context()
commandText := style.Commandf("login", true)

// When there are no authorizations, guide the user to creating an authorization.
Expand All @@ -145,5 +149,5 @@ func printAuthListSuccess(cmd *cobra.Command, IO iostreams.IOStreamer, userAuthL
)
}

IO.PrintTrace(cmd.Context(), slacktrace.AuthListSuccess)
IO.PrintTrace(ctx, slacktrace.AuthListSuccess)
}
3 changes: 2 additions & 1 deletion cmd/auth/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -127,14 +127,15 @@ func RunLoginCommand(clients *shared.ClientFactory, cmd *cobra.Command) (types.S
}

func printAuthSuccess(cmd *cobra.Command, IO iostreams.IOStreamer, credentialsPath string, token string) {
ctx := cmd.Context()

var secondaryLog string
if credentialsPath != "" {
secondaryLog = fmt.Sprintf("Authorization data was saved to %s", style.HomePath(credentialsPath))
} else if serviceTokenFlag && tokenFlag == "" {
secondaryLog = fmt.Sprintf("Service token:\n\n %s\n\nMake sure to copy the token now and save it safely.", token)
}

ctx := cmd.Context()
IO.PrintInfo(ctx, false, "\n%s", style.Sectionf(style.TextSection{
Emoji: "key",
Text: "You've successfully authenticated!",
Expand Down
3 changes: 2 additions & 1 deletion cmd/collaborators/add.go
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ func NewAddCommand(clients *shared.ClientFactory) *cobra.Command {
return cmdutil.IsValidProjectDirectory(clients)
},
RunE: func(cmd *cobra.Command, args []string) error {
return runAddCommandFunc(cmd.Context(), clients, cmd, args)
ctx := cmd.Context()
return runAddCommandFunc(ctx, clients, cmd, args)
},
}
cmd.Flags().StringVarP(&addFlags.permissionType, "permission-type", "P", "", "collaborator permission type: reader, owner")
Expand Down
3 changes: 1 addition & 2 deletions cmd/collaborators/list.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,9 +53,8 @@ func NewListCommand(clients *shared.ClientFactory) *cobra.Command {

// runListCommand will execute the list command
func runListCommand(cmd *cobra.Command, clients *shared.ClientFactory) error {
var span opentracing.Span
ctx := cmd.Context()
span, ctx = opentracing.StartSpanFromContext(ctx, "cmd.Collaborators.List")
span, _ := opentracing.StartSpanFromContext(ctx, "cmd.Collaborators.List")
defer span.Finish()

// Get the app auth selection from the flag or prompt
Expand Down
3 changes: 2 additions & 1 deletion cmd/collaborators/remove.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,8 @@ func NewRemoveCommand(clients *shared.ClientFactory) *cobra.Command {
return cmdutil.IsValidProjectDirectory(clients)
},
RunE: func(cmd *cobra.Command, args []string) error {
return runRemoveCommandFunc(cmd.Context(), clients, cmd, args)
ctx := cmd.Context()
return runRemoveCommandFunc(ctx, clients, cmd, args)
},
}
}
Expand Down
3 changes: 1 addition & 2 deletions cmd/collaborators/update.go
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,8 @@ func NewUpdateCommand(clients *shared.ClientFactory) *cobra.Command {

// runUpdateCommand will execute the update command
func runUpdateCommand(cmd *cobra.Command, clients *shared.ClientFactory, args []string) error {
var span opentracing.Span
ctx := cmd.Context()
span, ctx = opentracing.StartSpanFromContext(ctx, "cmd.Collaborators.Update")
span, _ := opentracing.StartSpanFromContext(ctx, "cmd.Collaborators.Update")
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

thought: This is up for debate. 🧠 OpenTracing span's return a new context that contains the span (and all of our values). Right now, we inconsistently replace the current ctx with the span's ctx. I've leaned toward not replacing our ctx because:

  • We never access the span through the ctx AFAIK
    • Instead, we often call span.Context()... to get it and modify it for API calls
  • We are moving toward a rule of thumb where the context should not be modified after a Cobra Execution

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mwbrooks Thanks for calling this out. How we use span in context is interesting to me.

We might consider follow ups for this, but IIRC spans are most useful for collecting traces that measure the beginning and end of function calls? I'm not sure if these can be gathered now, but we might find tools to visualize these useful in debugging slow processes 🔍

Not updating this ctx might cause strangeness in the trace callstack and make for confusing debugs if we explore this, but I have not tried it at all!

No blocker for this PR since we might consider this a standalone task altogether, but I'm also curious if this isn't seeming like the right use of context to you 🤔

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Making this more consistent overall is a nice change in this PR too!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yea, you bring up a good point about the span's forming a track callback. I'd expect that we'd want to update the context in that case.

Since we don't lean too heavily on the traces, I'll keep this PR as-is. The intention is to make everything consistent (not updating the context). Then, like you said, we can have a follow-up PR that updates everything together.

defer span.Finish()

var slackUser types.SlackUser
Expand Down
3 changes: 2 additions & 1 deletion cmd/doctor/doctor_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ func TestDoctorCommand(t *testing.T) {
expectedUpdateTime := "0001-01-01 00:00:00 Z"

t.Run("creates a complete report", func(t *testing.T) {
ctx := slackcontext.MockContext(t.Context())
clientsMock := shared.NewClientsMock()
clientsMock.AuthInterface.On("Auths", mock.Anything).Return([]types.SlackAuth{expectedCredentials}, nil)
clientsMock.AuthInterface.On("ResolveApiHost", mock.Anything, mock.Anything, mock.Anything).Return("api.slack.com")
Expand Down Expand Up @@ -90,7 +91,7 @@ func TestDoctorCommand(t *testing.T) {
err := cmd.Execute()
require.NoError(t, err)

report, err := performChecks(cmd.Context(), clients)
report, err := performChecks(ctx, clients)
require.NoError(t, err)

expectedValues := DoctorReport{
Expand Down
5 changes: 3 additions & 2 deletions cmd/fingerprint/fingerprint.go
Original file line number Diff line number Diff line change
Expand Up @@ -43,10 +43,11 @@ func NewCommand(clients *shared.ClientFactory) *cobra.Command {
{Command: "_fingerprint", Meaning: "Print the unique value that identifies the Slack CLI binary"},
}),
RunE: func(cmd *cobra.Command, args []string) error {
var span, _ = opentracing.StartSpanFromContext(cmd.Context(), "cmd._fingerprint")
ctx := cmd.Context()
var span, _ = opentracing.StartSpanFromContext(ctx, "cmd._fingerprint")
defer span.Finish()

clients.IO.PrintInfo(cmd.Context(), false, fingerprintHash)
clients.IO.PrintInfo(ctx, false, fingerprintHash)
return nil
},
}
Expand Down
3 changes: 2 additions & 1 deletion cmd/help/help.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,10 @@ func HelpFunc(
aliases map[string]string,
) func(*cobra.Command, []string) {
return func(cmd *cobra.Command, args []string) {
ctx := cmd.Context()
style.ToggleStyles(clients.IO.IsTTY() && !clients.Config.NoColor)
if help, _ := clients.Config.Flags.GetBool("help"); help {
clients.Config.LoadExperiments(cmd.Context(), clients.IO.PrintDebug)
clients.Config.LoadExperiments(ctx, clients.IO.PrintDebug)
}
experiments := []string{}
for _, exp := range clients.Config.GetExperiments() {
Expand Down
5 changes: 3 additions & 2 deletions cmd/platform/deploy.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,7 @@ func printDeployHosting(cmd *cobra.Command, event *logger.LogEvent) {
}

func printDeployHostingCompletion(clients *shared.ClientFactory, cmd *cobra.Command, event *logger.LogEvent) error {
var ctx = cmd.Context()
var authSession api.AuthSession

appName := event.DataToString("appName")
Expand Down Expand Up @@ -289,7 +290,7 @@ func printDeployHostingCompletion(clients *shared.ClientFactory, cmd *cobra.Comm

deploySpinner.Update(successfulDeployText, "").Stop()

clients.IO.PrintTrace(cmd.Context(), slacktrace.PlatformDeploySuccess)
clients.IO.PrintTrace(ctx, slacktrace.PlatformDeploySuccess)

navigateText := style.Sectionf(style.TextSection{
Emoji: "cloud_with_lightning",
Expand All @@ -300,7 +301,7 @@ func printDeployHostingCompletion(clients *shared.ClientFactory, cmd *cobra.Comm
},
})

clients.IO.PrintInfo(cmd.Context(), false, navigateText)
clients.IO.PrintInfo(ctx, false, navigateText)
return nil
}

Expand Down
2 changes: 1 addition & 1 deletion cmd/platform/run.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ func newRunLogger(clients *shared.ClientFactory, cmd *cobra.Command) *logger.Log
event.DataToString("teamName"),
)))
case "on_cloud_run_connection_connected":
clients.IO.PrintTrace(cmd.Context(), slacktrace.PlatformRunReady)
clients.IO.PrintTrace(ctx, slacktrace.PlatformRunReady)
cmd.Println(style.Secondary("Connected, awaiting events"))
case "on_cloud_run_connection_message":
message := event.DataToString("cloud_run_connection_message")
Expand Down
5 changes: 3 additions & 2 deletions cmd/project/create.go
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ func NewCreateCommand(clients *shared.ClientFactory) *cobra.Command {
}

func runCreateCommand(clients *shared.ClientFactory, cmd *cobra.Command, args []string) error {
ctx := cmd.Context()

// Set up event logger
log := newCreateLogger(clients, cmd)
Expand All @@ -102,7 +103,6 @@ func runCreateCommand(clients *shared.ClientFactory, cmd *cobra.Command, args []
}
clients.EventTracker.SetAppTemplate(template.GetTemplatePath())

ctx := cmd.Context()
appDirPath, err := CreateFunc(ctx, clients, log, createArgs)
if err != nil {
printAppCreateError(clients, cmd, err)
Expand Down Expand Up @@ -239,11 +239,12 @@ func printCreateSuccess(ctx context.Context, clients *shared.ClientFactory, appP

// 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(cmd.Context(), slacktrace.CreateError)
clients.IO.PrintTrace(ctx, slacktrace.CreateError)
}
16 changes: 9 additions & 7 deletions cmd/project/create_template.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,10 +153,10 @@ func promptTemplateSelection(cmd *cobra.Command, clients *shared.ClientFactory)
templateForCategory := getSelectionTemplate(clients)

// Print a trace with info about the category title options provided by CLI
clients.IO.PrintTrace(cmd.Context(), slacktrace.CreateCategoryOptions, strings.Join(titlesForCategory, ", "))
clients.IO.PrintTrace(ctx, slacktrace.CreateCategoryOptions, strings.Join(titlesForCategory, ", "))

// Prompt to choose a category
selection, err := clients.IO.SelectPrompt(cmd.Context(), promptForCategory, titlesForCategory, iostreams.SelectPromptConfig{
selection, err := clients.IO.SelectPrompt(ctx, promptForCategory, titlesForCategory, iostreams.SelectPromptConfig{
Description: func(value string, index int) string {
return optionsForCategory[index].Description
},
Expand Down Expand Up @@ -189,10 +189,10 @@ func promptTemplateSelection(cmd *cobra.Command, clients *shared.ClientFactory)
template := getSelectionTemplate(clients)

// Print a trace with info about the template title options provided by CLI
clients.IO.PrintTrace(cmd.Context(), slacktrace.CreateTemplateOptions, strings.Join(titles, ", "))
clients.IO.PrintTrace(ctx, slacktrace.CreateTemplateOptions, strings.Join(titles, ", "))

// Prompt to choose a template
selection, err := clients.IO.SelectPrompt(cmd.Context(), prompt, titles, iostreams.SelectPromptConfig{
selection, err := clients.IO.SelectPrompt(ctx, prompt, titles, iostreams.SelectPromptConfig{
Description: func(value string, index int) string {
return options[index].Description
},
Expand Down Expand Up @@ -238,7 +238,9 @@ func promptTemplateSelection(cmd *cobra.Command, clients *shared.ClientFactory)
// confirmExternalTemplateSelection prompts the user to confirm that they want to create an app from
// an external template and saves their preference if they choose to ignore future warnings
func confirmExternalTemplateSelection(cmd *cobra.Command, clients *shared.ClientFactory, template create.Template) (bool, error) {
trustSources, err := clients.Config.SystemConfig.GetTrustUnknownSources(cmd.Context())
ctx := cmd.Context()

trustSources, err := clients.Config.SystemConfig.GetTrustUnknownSources(ctx)
if err != nil {
return false, err
}
Expand All @@ -254,7 +256,7 @@ func confirmExternalTemplateSelection(cmd *cobra.Command, clients *shared.Client
},
}))

selection, err := clients.IO.SelectPrompt(cmd.Context(), "Proceed?", []string{"Yes", "Yes, don't ask again", "No"}, iostreams.SelectPromptConfig{
selection, err := clients.IO.SelectPrompt(ctx, "Proceed?", []string{"Yes", "Yes, don't ask again", "No"}, iostreams.SelectPromptConfig{
Required: true,
Flag: clients.Config.Flags.Lookup("force"),
})
Expand All @@ -263,7 +265,7 @@ func confirmExternalTemplateSelection(cmd *cobra.Command, clients *shared.Client
} else if selection.Option == "No" {
return false, nil
} else if selection.Option == "Yes, don't ask again" {
err = clients.Config.SystemConfig.SetTrustUnknownSources(cmd.Context(), true)
err = clients.Config.SystemConfig.SetTrustUnknownSources(ctx, true)
if err != nil {
return true, slackerror.Wrap(err, "failed to set trust_unknown_sources property to config")
}
Expand Down
Loading
Loading