Rename 'solution metadata' to 'exercise metadata'#736
Rename 'solution metadata' to 'exercise metadata'#736nywilken merged 6 commits intoexercism:masterfrom
Conversation
I agree. Giving this a review now, but I'd love to get @nywilken input on it as well (even though it's a pure rename, thus not complicated, it's an important rename to get right, I think!) |
kytrinyx
left a comment
There was a problem hiding this comment.
Overall I think the choice of ExerciseMetadata is really great. I have reservations about ExerciseMetadatas, as detailed below.
Also, I think we need to rename some local variables that are currently s.
cmd/download_test.go
Outdated
| dir := filepath.Join(targetDir, "bogus-track", "bogus-exercise") | ||
| b, err := ioutil.ReadFile(workspace.NewExerciseFromDir(dir).MetadataFilepath()) | ||
| var s workspace.Solution | ||
| var s workspace.ExerciseMetadata |
There was a problem hiding this comment.
I think s is probably the wrong variable name now that the type has been renamed. How would you feel about metadata to match the variable names you've used in the matching command file? Since it's tests, we could also do something shorter (em? meta?). I don't know. I like the consistency of metadata.
workspace/exercise_metadata.go
Outdated
| return &ExerciseMetadata{}, err | ||
| } | ||
| var s Solution | ||
| var s ExerciseMetadata |
There was a problem hiding this comment.
Here, too, I think we need something other than s.
workspace/exercise_metadata.go
Outdated
| // This is appended to avoid name conflicts, and does not indicate a particular | ||
| // iteration. | ||
| func (s *Solution) Suffix() string { | ||
| func (s *ExerciseMetadata) Suffix() string { |
There was a problem hiding this comment.
Likewise here (and throughout this file). I think in this case em is good, since it's in the context of a method receiver.
workspace/exercise_metadata_test.go
Outdated
| defer os.RemoveAll(dir) | ||
|
|
||
| s1 := &Solution{ | ||
| s1 := &ExerciseMetadata{ |
workspace/exercise_metadatas.go
Outdated
| package workspace | ||
|
|
||
| // ExerciseMetadatas is a collection of exercise metadata to interactively choose from. | ||
| type ExerciseMetadatas []*ExerciseMetadata |
There was a problem hiding this comment.
I'm not super happy about Metadatas as a plural. Data is already plural. How about something like MetadataCollection or ExerciseMetadataCollection?
workspace/exercise_metadatas_test.go
Outdated
| filepath.Join(root, "charlie"), | ||
| } | ||
| sx, err := NewSolutions(paths) | ||
| sx, err := NewExerciseMetadatas(paths) |
There was a problem hiding this comment.
I think we need another variable name here, as well (but I don't have any suggestions until we settle on the type name).
|
I think the issues have been addressed. When changing these short var names I noticed something unrelated to the rename of this PR: -func (ws Workspace) ExerciseDir(s string) (string, error) {
- if !strings.HasPrefix(s, ws.Dir) {
+func (ws Workspace) ExerciseDir(path string) (string, error) {
+ if !strings.HasPrefix(path, ws.Dir) {
return "", errors.New("not in workspace")
}
- path := s
+ currentPath := path
for {
- if path == ws.Dir {
+ if currentPath == ws.Dir {
return "", errMissingMetadata
}
- if _, err := os.Lstat(path); os.IsNotExist(err) {
+ if _, err := os.Lstat(currentPath); os.IsNotExist(err) {
return "", err
}
- if _, err := os.Lstat(filepath.Join(path, metadataFilepath)); err == nil {
- return path, nil
+ if _, err := os.Lstat(filepath.Join(currentPath, metadataFilepath)); err == nil {
+ return currentPath, nil
}
- if _, err := os.Lstat(filepath.Join(path, legacyMetadataFilename)); err == nil {
- return path, nil
+ if _, err := os.Lstat(filepath.Join(currentPath, legacyMetadataFilename)); err == nil {
+ return currentPath, nil
}
- path = filepath.Dir(path)
+ currentPath = filepath.Dir(currentPath)
}
}I think |
aff1ed7 to
2c73d54
Compare
nywilken
left a comment
There was a problem hiding this comment.
@jdsutherland thanks for tackling this. I left a couple of change requests for you within my review, but will have some additional comments in response to @kytrinyx review.
I also called out an example and the Go spec, which I think could be helpful as you learn Go. The spec is a little dense so please feel free to ask any questions.
|
|
||
| const solutionFilename = "solution.json" | ||
| const legacySolutionFilename = ".solution.json" | ||
| const metadataFilename = "metadata.json" |
There was a problem hiding this comment.
We should probably add a note for this in the release notes as it could cause confusion for any users who version control their workspace files.
workspace/exercise_metadata.go
Outdated
| b, err := ioutil.ReadFile(filepath.Join(dir, metadataFilepath)) | ||
| if err != nil { | ||
| return &Solution{}, err | ||
| return &ExerciseMetadata{}, err |
There was a problem hiding this comment.
Seeing as our return value is a pointer we can return nil, err not bother allocating memory for an empty ExerciseMetadata.
workspace/exercise_metadata.go
Outdated
| return &Solution{}, err | ||
| var metadata ExerciseMetadata | ||
| if err := json.Unmarshal(b, &metadata); err != nil { | ||
| return &ExerciseMetadata{}, err |
There was a problem hiding this comment.
The same holds true here: return nil, err
|
|
||
| // NewExerciseMetadataCollection loads up the exercise metadata for each of the provided paths. | ||
| func NewExerciseMetadataCollection(paths []string) (ExerciseMetadataCollection, error) { | ||
| var metadataCollection []*ExerciseMetadata |
There was a problem hiding this comment.
Seeing as you defined a custom type for a slice of ExerciseMetadata you should use that because while the following two variables are indeed a slice of ExerciseMetadata they are actually not the same type. Named types ExerciseMetatadataCollection are their own type, regardless of what their underlying type []*ExerciseMetadata is.
Here is an example of what I am talking about
https://play.golang.org/p/_LuoH39ODUq
This concept is a little tough to explain in a review so take a minute to read the spec, and ask me any questions about it. https://golang.org/ref/spec#Type_identity
|
@jdsutherland @kytrinyx I think the names make sense. However, do we actually need it? I seems like we only have this type being used in a test. In fact, the constructor is so simple that I would say when we need to handle multiple paths we can achieve that functionality without a custom type. In short, I see we remove it! |
|
@nywilken Thanks for the review. The feedback gives the impression that it was viewed through the lens of additions rather than a pure rename. I think the suggestions are spot on though. Looking at the history, |
I have the tendency to do this a bit, otherwise I’m left thinking that I may have missed something.
Glad to hear that. The refactor work you got goning on here is good so happy to provide guidance anyway possible. |
@jdsutherland I think
@nywilken That's a great catch! I have been simplifying and refactoring, and didn't notice that we don't use it yet. @jdsutherland how would you feel about deleting it in a separate PR to be merged before this one? (I can also make the change, but not today or tomorrow). |
I thought that was the case. I grokked the code to make sure there were no other usage of this type, but didn’t say out right to remove. In case, there was something I was missing. Prior to our current implementation we had the ability to do an interactive submit which handled directories and multiple files so this made sense then. Now that we have a simple submit, let’s remove the ExerciseMetadatCollection type along with its tests. BTW thanks for pulling up the history. |
@jdsutherland I’ll submit a PR for the deletion and work with with @kytrinyx to have it merged prior to this one. |
|
@kytrinyx @jdsutherland sorry for the confusion. @jdsutherland if you have the bandwidth right now to delete the type please do. I thought that was your response to @kytrinyx. Otherwise I can get to it later tonight. My apologies. |
e1f61b0 to
92f5e0d
Compare
|
@nywilken I'll make a PR for the deletion now. |
🙇♂️ |
|
@jdsutherland I merged #737 you should be able to rebase onto master to get the latest changes. |
Additionally, change 'solution metadata' refs to 'exercise metadata'
7572a18 to
65283cd
Compare
|
@nywilken done |
nywilken
left a comment
There was a problem hiding this comment.
@jdsutherland this looks good to me. @kytrinyx if all is good with you I will merge this in.
CHANGELOG.md
Outdated
|
|
||
| ## Next Release | ||
| * **Your contribution here** | ||
| * [#736](https://github.com/exercism/cli/pull/736) Metadata file .solution.json renamed to metadata.json |
There was a problem hiding this comment.
@jdsutherland we normally add the contributor name to the changelog entry - [@jdsutherland].
|
I prepared the branch https://github.com/nywilken/exercism-cli/tree/aplha-release-branch-3.0.10, which I plan to make available as a pre-release for testing the renamed metadata file. I want to wait until this change is merged because I noticed that if I migrate an exercise to |
Maybe I'm misunderstanding what's being said here. The state of the code of the branch isn't expected to rename to |
|
@jdsutherland sorry for the confusion. If I pre-release master as it is right now it will migrate (rename) However, if I ask the community to test it and then merge in your branch where we rename solution.json to metadata.json. Users who tested with 3.0.10-alpha will not actually see the rename because it will not get flagged as a legacy file. So as to not have to write more code to handle that case I would rather wait to get this PR merged so that we go from |
Renaming
workspace.Solution(andsolution.json) was previously discussed here:#630 (comment)
#607 (comment)
This change is a pure rename.
I chose
workspace.ExerciseMetadata, opting forExerciseoverSolutionbecause I believe Exercise more intuitively describes the metadata.