-
Notifications
You must be signed in to change notification settings - Fork 24
refactor: Add slackcontext package to DRY context management #7
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 3 commits
4add4cc
6c8907a
aae77de
a16ba4c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -16,6 +16,7 @@ | |
| "iostreams", | ||
| "opentracing", | ||
| "safeexec", | ||
| "slackcontext", | ||
| "slackdeps", | ||
| "slackerror", | ||
| "slackhq", | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -51,7 +51,7 @@ func NewEnvListCommand(clients *shared.ClientFactory) *cobra.Command { | |
| return preRunEnvListCommandFunc(ctx, clients) | ||
| }, | ||
| RunE: func(cmd *cobra.Command, args []string) error { | ||
| return runEnvListCommandFunc(clients) | ||
| return runEnvListCommandFunc(clients, cmd) | ||
| }, | ||
| } | ||
|
|
||
|
|
@@ -74,8 +74,9 @@ func preRunEnvListCommandFunc(ctx context.Context, clients *shared.ClientFactory | |
| // runEnvListCommandFunc outputs environment variables for a selected app | ||
| func runEnvListCommandFunc( | ||
| clients *shared.ClientFactory, | ||
| cmd *cobra.Command, | ||
| ) error { | ||
| ctx := context.Background() | ||
| ctx := cmd.Context() | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed getting the real context, so that the |
||
|
|
||
| selection, err := teamAppSelectPromptFunc( | ||
| ctx, | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -22,7 +22,6 @@ import ( | |
| "strings" | ||
| "syscall" | ||
|
|
||
| "github.com/opentracing/opentracing-go" | ||
| "github.com/slackapi/slack-cli/cmd/app" | ||
| "github.com/slackapi/slack-cli/cmd/auth" | ||
| "github.com/slackapi/slack-cli/cmd/collaborators" | ||
|
|
@@ -47,6 +46,7 @@ import ( | |
| "github.com/slackapi/slack-cli/internal/iostreams" | ||
| "github.com/slackapi/slack-cli/internal/pkg/version" | ||
| "github.com/slackapi/slack-cli/internal/shared" | ||
| "github.com/slackapi/slack-cli/internal/slackcontext" | ||
| "github.com/slackapi/slack-cli/internal/slackerror" | ||
| "github.com/slackapi/slack-cli/internal/style" | ||
| "github.com/slackapi/slack-cli/internal/update" | ||
|
|
@@ -222,6 +222,7 @@ func Init() (*cobra.Command, *shared.ClientFactory) { | |
| // TODO: consider using arguments for this function for certain dependencies, like working directory and other OS-specific strings, that OnInitialize above can provide during actual execution, but that we can override with test values for easier testing. | ||
| func InitConfig(clients *shared.ClientFactory, rootCmd *cobra.Command) error { | ||
| ctx := rootCmd.Context() | ||
|
|
||
| // Get the current working directory (usually, but not always the project) | ||
| workingDirPath, err := clients.Os.Getwd() | ||
| if err != nil { | ||
|
|
@@ -261,43 +262,35 @@ func InitConfig(clients *shared.ClientFactory, rootCmd *cobra.Command) error { | |
| clients.Config.ApiHostResolved = clients.AuthInterface().ResolveApiHost(ctx, clients.Config.ApiHostFlag, nil) | ||
| clients.Config.LogstashHostResolved = clients.AuthInterface().ResolveLogstashHost(ctx, clients.Config.ApiHostResolved, clients.CliVersion) | ||
|
|
||
| // TODO: should we store system ID in config or in context? | ||
| // Init System ID | ||
| if systemID, err := clients.Config.SystemConfig.InitSystemID(ctx); err != nil { | ||
| clients.IO.PrintDebug(ctx, "Error initializing user-level config system_id: %s", err.Error()) | ||
| } else { | ||
| // Used by Logstash | ||
| // TODO(slackcontext) Consolidate storing SystemID to slackcontext | ||
| clients.Config.SystemID = systemID | ||
|
Comment on lines
+270
to
271
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This would be a larger refactor that can wait until we 🪓 axe storing state in |
||
|
|
||
| // Used by OpenTracing | ||
| if span := opentracing.SpanFromContext(ctx); span != nil { | ||
| span.SetTag("system_id", clients.Config.SystemID) | ||
| ctx = opentracing.ContextWithSpan(ctx, span) | ||
| } | ||
|
|
||
| ctx = slackcontext.SetSystemID(ctx, systemID) | ||
| rootCmd.SetContext(ctx) | ||
| // Debug logging | ||
| clients.IO.PrintDebug(ctx, "system_id: %s", clients.Config.SystemID) | ||
| } | ||
|
|
||
| // TODO: should we store project ID in config or in context? | ||
| // Init Project ID, if current directory is a project | ||
| if projectID, _ := clients.Config.ProjectConfig.InitProjectID(ctx, false); projectID != "" { | ||
| // Used by Logstash | ||
| // TODO(slackcontext) Consolidate storing ProjectID to slackcontext | ||
| clients.Config.ProjectID = projectID | ||
|
Comment on lines
+282
to
283
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Likewise, this can wait until we 🪓 axe storing state in |
||
|
|
||
| // Used by OpenTracing | ||
| if span := opentracing.SpanFromContext(ctx); span != nil { | ||
| span.SetTag("project_id", clients.Config.ProjectID) | ||
| ctx = opentracing.ContextWithSpan(ctx, span) | ||
| } | ||
|
|
||
| ctx = slackcontext.SetProjectID(ctx, projectID) | ||
| rootCmd.SetContext(ctx) | ||
|
Comment on lines
-289
to
+286
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👾 ✨
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't think we need to do this, because the |
||
| // Debug logging | ||
| clients.IO.PrintDebug(ctx, "project_id: %s", clients.Config.ProjectID) | ||
| } | ||
|
|
||
| // Init configurations | ||
| clients.Config.LoadExperiments(ctx, clients.IO.PrintDebug) | ||
| // TODO: consolidate where we store CLI version; here are two locations, plus some code uses `contextutil.ContextFromVersion`, plus pkg/version/version | ||
| // TODO(slackcontext) Consolidate storing CLI version to slackcontext | ||
| clients.Config.Version = clients.CliVersion | ||
|
|
||
| // The domain auths (token->domain) shouldn't change for the execution of the CLI so preload them into config! | ||
|
|
@@ -334,10 +327,8 @@ func InitConfig(clients *shared.ClientFactory, rootCmd *cobra.Command) error { | |
| // listens for process interrupts and sends to IOStreams' GetInterruptChannel() for use in | ||
| // in communicating process interrupts elsewhere in the code. | ||
| func Execute(ctx context.Context, rootCmd *cobra.Command, clients *shared.ClientFactory) { | ||
| // TODO: ensure context is only used with setters and not with getters. After investigating, report: | ||
| // - internal/contextutil/contextutil.go has a `VersionFromContext` getter method which is used in various API methods when setting the user agent on HTTP requests, and when sending data up to logstash | ||
| // - internal/config/context.go has a variety of set and get methods related to app, token, team/enterprise/session/user/trace IDs, domains | ||
|
Comment on lines
-337
to
-339
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These files have been refactored to |
||
| ctx, cancel := context.WithCancel(ctx) | ||
|
|
||
| completedChan := make(chan bool, 1) // completed is used for signalling an end to command | ||
| exitChan := make(chan bool, 1) // exit blocks the command from exiting until completed | ||
| interruptChan := make(chan os.Signal, 1) // interrupt catches signals to avoid abrupt exits | ||
|
|
@@ -366,6 +357,7 @@ func Execute(ctx context.Context, rootCmd *cobra.Command, clients *shared.Client | |
| }() | ||
| case <-ctx.Done(): | ||
| // No interrupt signal sent, command executed to completion | ||
| // FIXME - `.Done()` channel is triggered by `cancel()` and not a successfully completion | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is a bug that i noticed while learning more about context. The
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm super curious about this 👀 It's not super clear what the bug is but I'm not doubting that this might be causing problems... Were you noticing something strange during command completion?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I only noticed the "bug" 🐛 while reading the code and didn't test it. From my understanding, the commenter thought So, the main bug is just the comment that's misleading. I'll make a note to follow-up on this and check if we should be cancelling the context at some point 🤔 |
||
| case <-completedChan: | ||
| // No canceled context, but command has completed execution | ||
| exitChan <- true | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -21,12 +21,15 @@ import ( | |||||||||||||||||||||||||
| "testing" | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| "github.com/slackapi/slack-cli/internal/shared" | ||||||||||||||||||||||||||
| "github.com/slackapi/slack-cli/internal/slackcontext" | ||||||||||||||||||||||||||
| "github.com/slackapi/slack-cli/test/testutil" | ||||||||||||||||||||||||||
| "github.com/stretchr/testify/assert" | ||||||||||||||||||||||||||
| "github.com/stretchr/testify/require" | ||||||||||||||||||||||||||
| ) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| func TestRootCommand(t *testing.T) { | ||||||||||||||||||||||||||
| ctx := slackcontext.MockContext(t.Context()) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
|
Comment on lines
+31
to
+32
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I've introduced a
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @mwbrooks This is wonderful with the setup in slack-cli/internal/slackcontext/slackcontext_mock.go Lines 23 to 34 in aae77de
|
||||||||||||||||||||||||||
| tmp, _ := os.MkdirTemp("", "") | ||||||||||||||||||||||||||
| _ = os.Chdir(tmp) | ||||||||||||||||||||||||||
| defer os.RemoveAll(tmp) | ||||||||||||||||||||||||||
|
|
@@ -38,7 +41,7 @@ func TestRootCommand(t *testing.T) { | |||||||||||||||||||||||||
| clientsMock := shared.NewClientsMock() | ||||||||||||||||||||||||||
| testutil.MockCmdIO(clientsMock.IO, cmd) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| err := cmd.Execute() | ||||||||||||||||||||||||||
| err := cmd.ExecuteContext(ctx) | ||||||||||||||||||||||||||
|
Comment on lines
-41
to
+44
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. TIL! Is this the same as Edit: Just saw the note in the PR description - this is neat! 🙏 📚
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You got it!
Whenever someone called |
||||||||||||||||||||||||||
| if err != nil { | ||||||||||||||||||||||||||
| assert.Fail(t, "cmd.Execute had unexpected error") | ||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||
|
|
@@ -131,6 +134,7 @@ func Test_Aliases(t *testing.T) { | |||||||||||||||||||||||||
| tmp, _ := os.MkdirTemp("", "") | ||||||||||||||||||||||||||
| _ = os.Chdir(tmp) | ||||||||||||||||||||||||||
| defer os.RemoveAll(tmp) | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| Init() | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
| tests := map[string]struct { | ||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While
runEnvListCommandFunc(ctx, clients, cmd)would be a more appropriate format, the otherenvcommands only passcmdand fetch the context withcmd.Context().This change is leaning on consistency and a smaller change footprint, since the PR is already quite large.