-
-
Notifications
You must be signed in to change notification settings - Fork 362
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 exercism fetch
behavior to remove filesystem noise
#258
Conversation
This is my rough first attempt at a fix for #226. Any feedback is much appreciated! |
View all available language tracks with "exercism tracks" | ||
Fetch exercises for your first track with "exercism fetch LANGUAGE" | ||
`) | ||
os.Exit(0) |
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.
A couple things (philosophically):
- I think we should only use
os.Exit
for a value other than 0 (in the case of an error), and - I don't think we should ever have
os.Exit
in packages other thancmd
. Other packages should return errors, if that's what they are.
I like where this is going. A few suggestions, but nothing major, I think. |
@kytrinyx thanks for the feedback! All your comments have been addressed, and I made a couple other small changes to be more consistent with the existing style in |
You have yet to start a language track! | ||
View all available language tracks with "exercism tracks" | ||
Fetch exercises for your first track with "exercism fetch LANGUAGE"`) | ||
} |
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.
Instead of LANGUAGE
this should be TRACK_ID
(it's super confusing, I'm so sorry!).
Should we return that as an error instead of printing it 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 didn't really think that this warranted an error, since when an error is returned from this that will bubble up to a log.Fatal
call and exit in that fashion. I thought that might be a little jarring for the user, so I decided to go this route. However, I'm happy to change this to an error if you think that's more intention revealing!
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.
Hm. Yeah. I see what you mean.
I think it is an error, though. They asked to fetch something, and we're telling them: something's not right.
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.
That's a good point. If the user asked to do something and it couldn't be done, then that's totally an error. Ok, switching over to an error now!
This is looking really clean. I'm worried about that one name, but that's it. |
@kytrinyx I think we're nearly there. I still don't love the name of |
I like |
I sort of like the |
Yeah I like the |
@kytrinyx Great, |
Looks great. Does I think it would be good to see a test to verify this new behaviour. It could to be a little difficult because you're calling |
@lcowell Good call on not exporting I agree that a couple of tests would be a good thing, but I think the list of known languages would be a real hassle to keep up to date. Dealing with creating and deleting directories for the tests won't be that bad, so I'll just go that route for now. |
To get the list of user languages, isn't it just a matter of getting a listing of all the directories in your exercism language? Something like:
|
@lcowell Sorry, I thought when you said 'Pass a list of known languages' you meant that we'd keep a list of the available languages on exercism.io in a constant or something and pass that list. My misunderstanding! Yes, we could totally go the way you describe to solve this problem (that's the way I originally thought of doing it), but it was faster and easier for me to write the tests with the code in the shape it is in now rather than refactoring. If there's a particular problem or reason why it would be better to refactor then I'd love to hear it and would be glad to refactor! |
I think the motivation is to isolate the parts of the system that need to talk to the OS. This improves testability and reduces brittleness in the system. In a system where everything can talk to everything it becomes more difficult to reason about what's happening or what went wrong. |
@lcowell excellent call on passing the list of languages to |
Ok, let me know what you think about the way I've refactored this, and thanks again for the idea! |
This looks great. Is there some reason we can't handle |
@lcowell No reason, really. @kytrinyx had recommended that structure in a previous comment (here: #258 (comment)), so I went with that since it didn't really bother me either way. |
I like @lcowell's suggestion better :) (sorry!) |
Ok, updated and ready for review! |
Looks great. Nice work @devonestes ! Edit: I do feel like |
Agreed, now that you mention it :) Gawd I love code review. Now that you mention it, should we just have one |
I like code review too. I learn so much, whether I'm the one giving feedback or the one writing code. In the context of homework, which is something that is submitted, I think that I see a couple of approaches to implementing this: hw.Filter(dirMap)
err := hw.Save() or if we have err := hw.Filter(dirMap).Save() |
Yepp, I agree. |
Well right now in // HWFilter is used to categorize homework items.
type HWFilter int
// SummaryOption allows selective display of summary items.
type SummaryOption HWFilter
const (
// HWAll represents all items in the collection.
HWAll = iota
// HWUpdated represents problems where files have been added.
HWUpdated
// HWNew represents newly fetched problems.
HWNew
// HWNotSubmitted represents problems that have not yet been submitted for review.
HWNotSubmitted
)
...
// ItemsMatching returns a subset of the set of problems.
func (hw *Homework) ItemsMatching(filter HWFilter) []*Item {
items := []*Item{}
for _, item := range hw.Items {
if item.Matches(filter) {
items = append(items, item)
}
}
return items
} Since there's already a bit of framework for filtering |
Can you briefly describe how would you implement this? The only ways I can think of would add complexity instead of reduce. But hey, I'm only one coffee deep, so I might be missing something obvious. |
@lcowell I totally agree that it would add complexity, but if the goal is to have one |
I don't want to add complexity. Here's what I was thinking:
|
Ahh, I understand now. Crystal clear - I'll get on it now! |
This commit changes the behavior of `exercism fetch` when called without any arguments. Instead of fetching and writing exercises for all tracks, it will now fetch and update only for tracks the user has folders for on their local environment. If a user calls `exercism fetch` without having any language tracks in their exercises folder, a prompt is shown to the user to tell them how to list all available tracks and how to fetch their first track for a language of their choice.
I really like how this ended up. Thanks @devonestes and @lcowell for working through all the details! |
Changes `exercism fetch` behavior to remove filesystem noise
This commit changes the behavior of
exercism fetch
when called without any arguments. Instead of fetching and writing exercises for all tracks, it will now fetch and update only tracks for which the user has folders in their local environment. If a user callsexercism fetch
without having any language tracks in their exercises folder, a prompt is shown to the user to tell them how to list all available tracks and how to fetch their first track for a language of their choice.