Skip to content
This repository has been archived by the owner on Mar 22, 2022. It is now read-only.

implement the --diff flag for the fmt command #150

Merged
merged 2 commits into from
Nov 15, 2018

Conversation

danielj-jordan
Copy link
Contributor

#148

I am a bit new to Go and eager for any comments. Thanks

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.

@danielj-jordan I took a quick pass-through and left a few comments pertaining to the runFmt function signature. I will continue looking through the PR and make suggestions where possible.

Thanks again for opening up the PR!

cmd/fmt.go Outdated
if _, err := os.Stat(filepath.Join(outDir, "config")); os.IsNotExist(err) {
os.Mkdir(filepath.Join(outDir, "config"), os.ModePerm)
}
var diffFound = false
Copy link
Contributor

Choose a reason for hiding this comment

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

When assigning the zero value (default value) for a type it is preferred to just use var diffFound bool

cmd/fmt.go Outdated
@@ -29,19 +32,24 @@ It also normalizes and alphabetizes the exercise topics in the config.json file.
`,
Example: fmt.Sprintf(" %s fmt %s --verbose", binaryName, pathExample),
Run: func(cmd *cobra.Command, args []string) {
if err := runFmt(args[0], args[0], fmtVerbose); err != nil {

if diffFound, err := runFmt(args[0], args[0], fmtVerbose, fmtDiff); err != nil {
Copy link
Contributor

@nywilken nywilken Oct 25, 2018

Choose a reason for hiding this comment

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

Seeing as fmtVerbose and fmtDiff are package level variables we should be able to access them from within runFmt without having to pass them in.

If you remove the parameters from here and within the runFmt function you would need to update the references of verbose and diffonly to fmtVerbose and fmtDiff

@@ -24,7 +24,7 @@ func ExampleFormat() {
}
defer os.Remove(unformattedDir)

runFmt("../fixtures/format/unformatted/", unformattedDir, true)
runFmt("../fixtures/format/unformatted/", unformattedDir, true, false)
Copy link
Contributor

Choose a reason for hiding this comment

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

If you make the update so that runFmt uses fmtVerbose and fmtDiff directly you could remove the parameters and instead use the convention on lines 12-19 to set and reset the values for the pkg level variables fmtVerbose and fmtDiff.

oldVerbose = fmtVerbose
fmtVerbose = true
defer func() {
  fmtVerbose = oldVerbose
}

cmd/fmt_test.go Outdated
@@ -26,7 +26,7 @@ func TestFmtCommand(t *testing.T) {
t.Fatal(err)
}
defer os.Remove(formattedDir)
runFmt("../fixtures/format/formatted/", formattedDir, false)
runFmt("../fixtures/format/formatted/", formattedDir, false, false)
Copy link
Contributor

Choose a reason for hiding this comment

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

Same comment I left for fmt_example_test applies here.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thanks @nywilken. I made the changes that you suggested. If you like the current code, I can squash and re-submit the PR if you like.

Copy link
Member

@kytrinyx kytrinyx left a comment

Choose a reason for hiding this comment

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

This is looking great! I have a couple of tiny comments/suggestions, but I think this is basically good to go.

cmd/fmt.go Outdated
}
}
if changes != "" {
ui.Print("changes made to:\n", changes)
if fmtDiff == false {
Copy link
Member

Choose a reason for hiding this comment

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

Here we basically have an "if not else".

I think it would make sense to swap it around so that it reads `if fmtDiff, otherwise..."

cmd/fmt.go Outdated
@@ -105,7 +122,7 @@ func formatFile(cfg ConfigSerializer, inPath, outPath string) (string, error) {
if err != nil {
return "", err
}
if diff != "" {
if diff != "" && fmtDiff == false {
Copy link
Member

Choose a reason for hiding this comment

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

It would be more idiomatic to make this !fmtDiff

cmd/fmt.go Outdated
@@ -116,4 +133,5 @@ func formatFile(cfg ConfigSerializer, inPath, outPath string) (string, error) {
func init() {
RootCmd.AddCommand(fmtCmd)
fmtCmd.Flags().BoolVarP(&fmtVerbose, "verbose", "v", false, "display the diff of the formatted changes.")
fmtCmd.Flags().BoolVarP(&fmtDiff, "diff", "d", false, "display the diff of the proposed changes, but do not make them.")
Copy link
Member

Choose a reason for hiding this comment

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

How would you feel about dry-run as the flag name instead of diff?
That's a very common flag name for something that would try something out, report what would happen, but then not actually make the changes.

@nywilken I'd love to hear your thoughts on this one as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think it is better named dry-run also.

Copy link
Contributor

Choose a reason for hiding this comment

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

How would you feel about dry-run as the flag name instead of diff?

👍 I like that option over diff. I would even go so far as saying that we copy the option and messaging from the grep command

-n, --dry-run       perform a trial run with no changes made

Copy link
Contributor

@nywilken nywilken Nov 4, 2018

Choose a reason for hiding this comment

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

Actually, looking at the original issue we want a non-zero code if there are formatting issues so a dry-run might not be the option we want. In fact, I wouldn't expect dry-run to exit without error if the command successfully prints out the changes that would be written to the source file.

What if we keep the dry-run option, but also add a -t, --test flag that returns a non-zero if there are formatting issue?

-t, —test performs a trial and exits if formatting is needed; meant to be used with ci

Copy link
Contributor

@nywilken nywilken Nov 4, 2018

Choose a reason for hiding this comment

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

What if we keep the dry-run option, but also add a -t, --test flag that returns a non-zero if there are formatting issue.

I pulled down the branch and see that dry-run does not actually print the changes unless the verbose flag is passed as well so I would like to change my previous suggestion slightly. Which of course is open for discussion.

Rename the dry-run option to test or check using the messaging above, enable verbosity any time the check flag is passed so that if the check fails users will see the diff. Thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

@nywilken these are good observations. I think that it's important that we can exit with an error code in order to be able to use this in CI. In that sense, I think that test communicates this better than dry-run.

For the doctor command, I think we always need to print in the test version, whether or not verbose is passed. I think it's fine to not print verbose output if just running doctor to fix something.

fmtVerbose = true
fmtDiff = false

runFmt("../fixtures/format/unformatted/", unformattedDir)
Copy link
Member

Choose a reason for hiding this comment

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

I really like how much more readable this became now that the booleans are being assigned to the package variables!

@danielj-jordan danielj-jordan force-pushed the implement-fmt-diff-flag branch from 14b5327 to b702936 Compare November 3, 2018 01:16
@danielj-jordan
Copy link
Contributor Author

@nywilken @kytrinyx Thanks for the feedback. I have incorporated all your recommendations and squashed the commit.

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.

@danielj-jordan @kytrinyx this is coming along nicely. I left a couple of suggestions along with my thoughts on the flag name. FWIW the code suggestions within this review should not have to change if we decide to rename the flag - only the references to the flag variable.

cmd/fmt.go Outdated
ui.Print(fmt.Sprintf("%s\n\n%s", f.inPath, diff))
}
changes += fmt.Sprintf("%s\n", f.inPath)
diffFound = true

}
}
if changes != "" {
Copy link
Contributor

Choose a reason for hiding this comment

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

The declaration of diffFound can actually be moved right above this line with a slight change

Suggested change
if changes != "" {
diffFound := changes != ""
if diffFound {
...

cmd/fmt.go Outdated
if _, err := os.Stat(filepath.Join(outDir, "config")); os.IsNotExist(err) {
os.Mkdir(filepath.Join(outDir, "config"), os.ModePerm)
}
var diffFound bool
Copy link
Contributor

Choose a reason for hiding this comment

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

This declaration can be made closer to where it is being used.

Copy link
Member

Choose a reason for hiding this comment

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

This should still be moved closer to where it's used 👍

cmd/fmt.go Outdated
ui.Print(fmt.Sprintf("%s\n\n%s", f.inPath, diff))
}
changes += fmt.Sprintf("%s\n", f.inPath)
diffFound = true
Copy link
Contributor

Choose a reason for hiding this comment

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

If you apply the suggestions made below you can drop this line.

cmd/fmt.go Outdated
}
}
if changes != "" {
ui.Print("changes made to:\n", changes)
if fmtDryRun {
Copy link
Contributor

Choose a reason for hiding this comment

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

Seeing as the flag description specifies that no changes will be made I would drop this if/else and instead only print when changes were made.

if diffFound && !fmtDryRun {
    ui.Print("changes made to:\n", changes)
}

}
if err := errs.ErrorOrNil(); err != nil {
return err
return diffFound, err
Copy link
Contributor

Choose a reason for hiding this comment

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

If you apply the suggestion on line 92 you can just return false with the error

@@ -29,19 +35,24 @@ It also normalizes and alphabetizes the exercise topics in the config.json file.
`,
Example: fmt.Sprintf(" %s fmt %s --verbose", binaryName, pathExample),
Run: func(cmd *cobra.Command, args []string) {
if err := runFmt(args[0], args[0], fmtVerbose); err != nil {

Copy link
Contributor

Choose a reason for hiding this comment

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

What do you think enabling verbosity anytime the format check is run? Something like the following right before we call runFmt(...)

if fmtDryRun {
    fmtVerbose = true
}

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yes. It makes sense to do this

@danielj-jordan
Copy link
Contributor Author

I want to confirm that the flag should be named —test not —dry-run. Please reply and confirm. Thank you

@kytrinyx
Copy link
Member

kytrinyx commented Nov 5, 2018

@danielj-jordan thank you for confirming. Yes! We're going with --test rather than --dry-run.

Also, the command should

  1. set verbose to true even if verbose wasn't passed, and
  2. exit with a non-zero code if something needs changing

@danielj-jordan danielj-jordan force-pushed the implement-fmt-diff-flag branch from b702936 to b4cb42b Compare November 10, 2018 00:52
@danielj-jordan
Copy link
Contributor Author

@kytrinyx @nywilken I am not sure if you got notified, but the —test flag is implemented. It always runs with verbose.

@kytrinyx
Copy link
Member

@danielj-jordan Ah, nope! I didn't see the notification. Thanks so much, I'll take a look at this in the morning.

Copy link
Member

@kytrinyx kytrinyx left a comment

Choose a reason for hiding this comment

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

There's one more minor tweak to do (the diffFound thing that @nywilken mentioned previously. After that I think this is good to go!

cmd/fmt.go Outdated
if _, err := os.Stat(filepath.Join(outDir, "config")); os.IsNotExist(err) {
os.Mkdir(filepath.Join(outDir, "config"), os.ModePerm)
}
var diffFound bool
Copy link
Member

Choose a reason for hiding this comment

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

This should still be moved closer to where it's used 👍

@danielj-jordan danielj-jordan force-pushed the implement-fmt-diff-flag branch from b4cb42b to 771f30d Compare November 13, 2018 14:39
@danielj-jordan
Copy link
Contributor Author

@kytrinyx I moved the declaration closer. Thanks

Copy link
Member

@kytrinyx kytrinyx left a comment

Choose a reason for hiding this comment

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

This is great, thanks so much @danielj-jordan!

@kytrinyx kytrinyx dismissed nywilken’s stale review November 15, 2018 14:25

Suggestions have been applied.

@kytrinyx kytrinyx merged commit 7c547b5 into exercism:master Nov 15, 2018
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants