From 771f30ddb7e4e15f0eac10c77a3be36291bfe012 Mon Sep 17 00:00:00 2001 From: danielj-jordan <12012148+danielj-jordan@users.noreply.github.com> Date: Tue, 13 Nov 2018 06:38:53 -0800 Subject: [PATCH] implement --test flag --- cmd/fmt.go | 39 +++++++++++++++----- cmd/fmt_example_test.go | 82 ++++++++++++++++++++++++++++++++++++++++- cmd/fmt_test.go | 33 +++++++++++++++-- 3 files changed, 140 insertions(+), 14 deletions(-) diff --git a/cmd/fmt.go b/cmd/fmt.go index 1f22cca..2cfc5c4 100644 --- a/cmd/fmt.go +++ b/cmd/fmt.go @@ -13,8 +13,13 @@ import ( "github.com/spf13/cobra" ) -// verbose flag for fmt command. -var fmtVerbose bool +var ( + // verbose flag for fmt command. + fmtVerbose bool + + // test flag for fmt command displays the proposed changes + fmtTest bool +) // fmtCmd defines the fmt command var fmtCmd = &cobra.Command{ @@ -29,20 +34,28 @@ 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]); err != nil { ui.PrintError(err.Error()) os.Exit(1) + } else if diffFound && fmtTest { + os.Exit(2) } + }, Args: cobra.ExactArgs(1), } -func runFmt(inDir, outDir string, verbose bool) error { +func runFmt(inDir, outDir string) (bool, error) { if _, err := os.Stat(filepath.Join(outDir, "config")); os.IsNotExist(err) { os.Mkdir(filepath.Join(outDir, "config"), os.ModePerm) } + if fmtTest { + fmtVerbose = true + } + var fs = []struct { inPath string outPath string @@ -61,6 +74,7 @@ func runFmt(inDir, outDir string, verbose bool) error { } var changes string + var diffFound bool errs := &multierror.Error{} for _, f := range fs { @@ -70,19 +84,25 @@ func runFmt(inDir, outDir string, verbose bool) error { continue } if diff != "" { - if verbose { + if fmtVerbose { ui.Print(fmt.Sprintf("%s\n\n%s", f.inPath, diff)) } changes += fmt.Sprintf("%s\n", f.inPath) + diffFound = true + } } if changes != "" { - ui.Print("changes made to:\n", changes) + if fmtTest { + ui.Print("no changes were made to:\n", changes) + } else { + ui.Print("changes made to:\n", changes) + } } if err := errs.ErrorOrNil(); err != nil { - return err + return diffFound, err } - return nil + return diffFound, nil } func formatFile(cfg ConfigSerializer, inPath, outPath string) (string, error) { @@ -105,7 +125,7 @@ func formatFile(cfg ConfigSerializer, inPath, outPath string) (string, error) { if err != nil { return "", err } - if diff != "" { + if diff != "" && !fmtTest { if err := ioutil.WriteFile(outPath, dst, os.FileMode(0644)); err != nil { return "", err } @@ -116,4 +136,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(&fmtTest, "test", "t", false, "display the proposed changes, but do not make them.") } diff --git a/cmd/fmt_example_test.go b/cmd/fmt_example_test.go index 79e4c95..04a4229 100644 --- a/cmd/fmt_example_test.go +++ b/cmd/fmt_example_test.go @@ -8,7 +8,7 @@ import ( "github.com/exercism/configlet/ui" ) -func ExampleFormat() { +func ExampleFormatVerboseFlag() { oldOut := ui.Out oldErrOut := ui.ErrOut ui.Out = os.Stdout @@ -24,7 +24,10 @@ func ExampleFormat() { } defer os.Remove(unformattedDir) - runFmt("../fixtures/format/unformatted/", unformattedDir, true) + fmtVerbose = true + fmtTest = false + + runFmt("../fixtures/format/unformatted/", unformattedDir) // Output: //-> ../fixtures/format/unformatted/config.json @@ -79,3 +82,78 @@ func ExampleFormat() { // ../fixtures/format/unformatted/config.json //../fixtures/format/unformatted/config/maintainers.json } + +func ExampleFormatTestFlag() { + oldOut := ui.Out + oldErrOut := ui.ErrOut + ui.Out = os.Stdout + ui.ErrOut = os.Stderr + defer func() { + ui.Out = oldOut + ui.ErrOut = oldErrOut + }() + + unformattedDir, err := ioutil.TempDir("", "unformatted") + if err != nil { + log.Fatal(err) + } + defer os.Remove(unformattedDir) + + fmtVerbose = false + fmtTest = true + + runFmt("../fixtures/format/unformatted/", unformattedDir) + + // Output: + //-> ../fixtures/format/unformatted/config.json + // + //@@ -11 +11,2 @@ + //-{ + //+ { + //+ "slug": "one", + //@@ -13 +13,0 @@ + //- "slug": "one", + //@@ -14,0 +15 @@ + //+ "auto_approve": true, + //@@ -17 +17,0 @@ + //- "auto_approve": true, + //@@ -19,4 +19,4 @@ + //- "Control-flow (conditionals)", + //- "Logic", + //- "Booleans", + //- "Integers" + //+ "booleans", + //+ "control_flow_conditionals", + //+ "integers", + //+ "logic" + //@@ -25,0 +26 @@ + //+ "slug": "two", + //@@ -27 +27,0 @@ + //- "slug": "two", + //@@ -32,5 +32,8 @@ + //- "Time", + //- "Mathematics", + //- "Text formatting", + //- "Equality" + //- ]}]} + //+ "equality", + //+ "mathematics", + //+ "text_formatting", + //+ "time" + //+ ] + //+ } + //+ ] + //+} + // + //-> ../fixtures/format/unformatted/config/maintainers.json + // + //@@ -2,2 +2,2 @@ + //- "docs_url": "http://docs.example.com", + //- "maintainers": [] + //+ "docs_url": "http://docs.example.com", + //+ "maintainers": [] + // + //-> no changes were made to: + // ../fixtures/format/unformatted/config.json + //../fixtures/format/unformatted/config/maintainers.json +} diff --git a/cmd/fmt_test.go b/cmd/fmt_test.go index efd25a2..1f49f41 100644 --- a/cmd/fmt_test.go +++ b/cmd/fmt_test.go @@ -26,7 +26,10 @@ func TestFmtCommand(t *testing.T) { t.Fatal(err) } defer os.Remove(formattedDir) - runFmt("../fixtures/format/formatted/", formattedDir, false) + + fmtTest = false + fmtVerbose = false + runFmt("../fixtures/format/formatted/", formattedDir) _, err = os.Stat(filepath.Join(formattedDir, "config.json")) assert.True(t, os.IsNotExist(err)) @@ -40,7 +43,10 @@ func TestFmtCommand(t *testing.T) { t.Fatal(err) } defer os.Remove(malformedDir) - runFmt("../fixtures/format/malformed/", malformedDir, false) + + fmtTest = false + fmtVerbose = false + runFmt("../fixtures/format/malformed/", malformedDir) track, err := ioutil.ReadFile(filepath.Join(malformedDir, "config.json")) if err != nil { @@ -53,6 +59,24 @@ func TestFmtCommand(t *testing.T) { t.Fatal(err) } assert.Equal(t, maintainer, maintainerCfg) + + // It does not rewrite an incorrectly formatted file when the diff opton is true + unformattedDir, err := ioutil.TempDir("", "unformatted") + if err != nil { + t.Fatal(err) + } + defer os.Remove(formattedDir) + + fmtTest = true + fmtVerbose = false + runFmt("../fixtures/format/unformatted/", unformattedDir) + + _, err = os.Stat(filepath.Join(unformattedDir, "config.json")) + assert.True(t, os.IsNotExist(err)) + + _, err = os.Stat(filepath.Join(unformattedDir, "config", "maintainers.json")) + assert.True(t, os.IsNotExist(err)) + } func TestSemanticsOfMissingTopics(t *testing.T) { @@ -61,7 +85,10 @@ func TestSemanticsOfMissingTopics(t *testing.T) { t.Fatal(err) } defer os.Remove(semanticsDir) - runFmt("../fixtures/format/semantics/", semanticsDir, false) + + fmtTest = false + fmtVerbose = false + runFmt("../fixtures/format/semantics/", semanticsDir) // No change; nothing should be written to out dir. _, err = os.Stat(filepath.Join(semanticsDir, "config.json"))