Skip to content
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

Extract downloadWriter from download command #826

Closed

Conversation

jdsutherland
Copy link
Contributor

These changes create a downloadWriter type that handles writing solution files and metadata.

@jdsutherland jdsutherland force-pushed the refactor-download-writer branch from 6a3abb1 to 39a8b36 Compare March 1, 2019 04:44
downloadWriter is the only consumer, so sanitizeLegacyFilepath should
live there.
@kytrinyx
Copy link
Member

kytrinyx commented Mar 1, 2019

This is a really big jump, and I'm not convinced that this is the right abstraction.

A lot of this change has to do with the solution files specifically. Would it make sense to explore something that only encapsulates solution-file related logic first, and see where that goes?

@jdsutherland
Copy link
Contributor Author

jdsutherland commented Mar 1, 2019

It doesn't seem like there are that many potential ways for this to end up. Can you give more of a sense of the issue you have with it?

I understand splitting this up but I don't really see something much different unfolding.

@kytrinyx
Copy link
Member

kytrinyx commented Mar 2, 2019

I feel like it has several jumps that make it hard to reason about the code. It hides information that seems necessary to understand what is going on.

Let me sit down on Sunday and mess around with it for a while so I can get a sense of what the options are.

@jdsutherland
Copy link
Contributor Author

I see. To me it looks pretty similar to the existing runDownload loop with the difference being that separate responsibilities have been extracted and the long reaching variables are done away with.

I started by pulling out the loop that writes solution files. Having done that, it seems like there are a few distinguishable responsibilities: requestFile and sanitizeLegacyFilepath. I also extracted destination as it is used a few places and seems worth following Demeter.

To my eye, this seems like a reasonable split of responsibilities. I tried starting over again but it didn't change anything for me; maybe my eyes are no good because I've looked at it too long. I'd be interested to see what you would suggest here.

@kytrinyx
Copy link
Member

kytrinyx commented Mar 2, 2019

Cool, yeah you might be right that this is the best split of responsibilities! I'm now very curious to see where this goes :-) I have time scheduled tomorrow to play with it.

Copy link
Contributor

@nywilken nywilken left a comment

Choose a reason for hiding this comment

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

@jdsutherland thanks for pushing this command forward and the work to simplify it.

I see where you are going with this but I don't think breaking the logic out into a writer type gets us closer to reducing the load of the download command. It feels like we are just moving the complexity deeper down, which tends to hide the intent of the code. I left a few comments around the changes to see if I can help provide guidance, but my first question is "What are we aiming for with the refactor?"

@@ -264,6 +197,119 @@ func (d download) needsSlugWhenGivenTrackOrTeam() error {
return nil
}

func (d download) metadata() *ws.ExerciseMetadata {
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this method might be going beyond the scope of the download type. Which If I understand correctly is a custom type used for parsing flags and setting up the download command. Having actual exercise metadata and solutionFile data ⬇️ tied to it doesn't seem correct.


// requestFile requests a Solution file from the API, returning an HTTP response.
// 0 Content-Length responses are swallowed, returning nil.
func (d download) requestFile(filename string) (*http.Response, error) {
Copy link
Contributor

@nywilken nywilken Mar 5, 2019

Choose a reason for hiding this comment

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

I could see this being its own function not tied to download. Maybe this is something that should live on the Exercism Client API with a single argument being the parsedURL.string() or in @kytrinyx's Solution File refactor sf.url().

Copy link
Member

Choose a reason for hiding this comment

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

I like the idea of having a helper on the client API with a single URL argument. That feels like a perfectly reasonable (and cohesive!) bit of behavior for the CLI.

}

// newDownloadWriter creates a downloadWriter.
func newDownloadWriter(dl *download) *downloadWriter {
Copy link
Contributor

@nywilken nywilken Mar 5, 2019

Choose a reason for hiding this comment

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

I think we could get a way with just initializing a literal downloadWriter in runDownload and dropping the constructor seeing as it is not doing anything special. With that being said, is there a reason for returning a pointer to a downloadWriter?

@jdsutherland
Copy link
Contributor Author

jdsutherland commented Mar 5, 2019

@nywilken thanks for your review. I would address your comments but I was under the impression that there isn't interest in pursuing this line based on @kytrinyx response. I was expecting to close this.

@nywilken
Copy link
Contributor

nywilken commented Mar 7, 2019

@jdsutherland I think there was some good discovery here. I’ll go ahead and close this PR and hope that we can use the discussion as a point of reference for future PRs. Feel free to open a new PR or issue(s) for the items discussed.

@nywilken nywilken closed this Mar 7, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants