-
Notifications
You must be signed in to change notification settings - Fork 24
refactor(config): destructify project-level getter and setters in package config #138
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
Conversation
…os, projectConfig)
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #138 +/- ##
==========================================
- Coverage 63.59% 63.58% -0.02%
==========================================
Files 212 212
Lines 22348 22348
==========================================
- Hits 14213 14209 -4
- Misses 7054 7058 +4
Partials 1081 1081 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
zimeg
left a comment
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.
@mwbrooks LGTM! I was thinking more about where config will end up after similar changes and it's seeming good.
One comment I left was around perhaps unclear logic when calling a function, but these changes are shifting how I think about invocations:
The
fsandosused have the context of the path started in!
This might not be surprising to you, but using arguments instead of internal structures surfaces this more for me 😉
| projectDirPath, err := GetProjectDirPath(fs, os) | ||
| if err != nil { | ||
| return projectConfig, err | ||
| } |
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.
👁️🗨️ This might be because I'm used to the before version of this code, but to me this:
projectConfig, err := clients.Config.ProjectConfig.ReadProjectConfigFile(ctx)Hid the magic of how the project path was found. I realize now we're doing the same thing with arguments shared instead, but it wasn't obvious how fs and os were used to read the configuration to me...
projectConfig, err := config.ReadProjectConfigFile(ctx, clients.Fs, clients.Os)I do think this is good improvement for testing and using this package overall and it's not so confusing IRL but I wanted to share an initial thought here!
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.
I agree @zimeg, this function has always felt magical to me as well.
Behind the scenes, it's using the current working directory as the project path, but that's bad practice imo. This kind of logic makes it difficult for us to support running commands in sub-directories and it confusing to read as a maintainer.
We should definitely improve it in the future!
| // createProject will mock a project's required directory and files. | ||
| // If there is an error, it will fail the test. | ||
| func CreateProject(t require.TestingT, ctx context.Context, fs afero.Fs, os types.Os, projectDirPath string) { |
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.
🔍 I'm super curious if adding options of common fixtures for this might be tried later, or if that's something that'll be left to test setups?
The tests above I think are clear, and as more of clients is destructured this might read so well:
slackmock.CreateProject(t, ctx, clients.Fs, clients.Os, slackdeps.MockWorkingDirectory)
_, err := config.WriteProjectConfigFile(ctx, clients.Fs, clients.Os, tt.projectConfig)
require.NoError(t, err)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.
🧠 Interesting! What do you have in mind? Are you thinking project fixtures like "project-deno", "project-bolt-js", "project-missing-hooks", "project-missing-dotslack", etc?
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.
@mwbrooks Those are all seeming solid to me and appear most in tests IIRC - I do wonder if adding these now or much later makes the most sense in case other patterns appear, but those cases are still so good to have 😌 🎉
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.
@zimeg Sorry, I meant to respond before I hit merge 🤦🏻 I think we can add these later, but perhaps we should try to experiment with it while we're doing the destructify work, in case it's not as elegant as we hope?
|
Thanks so much for the PR review @zimeg! Keep the honest thoughts coming with this destructify work. The goal is to make the code easier to use and maintain, which reducing things like circular dependencies and passing "god objects." If you ever get a sense that this isn't the right direction - particularly from the testing perspective - then we can stop and re-eval! |
Summary
This pull request continues PR #130 by de-struct-ifying the following project-level methods in
package config:config.ProjectConfigJSONFileExists(...)config.WriteProjectConfigFile(...)config.ReadProjectConfigFile(...)config.SetManifestSource(...)I've chosen these methods because their changes are relatively straight-forward and repetitive. The remaining methods require wider changes, so I'd like to isolate them to smaller, future PRs.
Changes
A common refactor looks like this:
Remove method from the interface:
- GetProjectDirPath() (string, error)Update method to be a standalone function with dependencies as arguments:
Update references to use the standalone function:
Remove method from the project mocks:
Update tests to use filesystem mock instead of project-config mock:
Requirements