From 698b212491d83c1584eb892fe457ca976c8cb774 Mon Sep 17 00:00:00 2001 From: Tim Hockin Date: Fri, 10 Jul 2015 14:35:47 -0700 Subject: [PATCH] Run all munges on all docs Rather than terminating, Collect the errors and print them per-file-per-munge. --- cmd/mungedocs/links.go | 4 +- cmd/mungedocs/mungedocs.go | 103 ++++++++++++++++++++++--------------- 2 files changed, 64 insertions(+), 43 deletions(-) diff --git a/cmd/mungedocs/links.go b/cmd/mungedocs/links.go index 1ecdebf6418..e5934364882 100644 --- a/cmd/mungedocs/links.go +++ b/cmd/mungedocs/links.go @@ -58,7 +58,7 @@ func checkLinks(filePath string, fileBytes []byte) ([]byte, error) { if err != nil { errors = append( errors, - fmt.Sprintf("%v, link %q is unparsable: %v", filePath, linkText, err), + fmt.Sprintf("link %q is unparsable: %v", linkText, err), ) return in } @@ -74,7 +74,7 @@ func checkLinks(filePath string, fileBytes []byte) ([]byte, error) { if !targetExists { errors = append( errors, - fmt.Sprintf("%v, %q: target not found\n", filePath, linkText), + fmt.Sprintf("%q: target not found", linkText), ) } u.Path = newPath diff --git a/cmd/mungedocs/mungedocs.go b/cmd/mungedocs/mungedocs.go index 60f05849c7e..98910d44d0f 100644 --- a/cmd/mungedocs/mungedocs.go +++ b/cmd/mungedocs/mungedocs.go @@ -34,30 +34,32 @@ var ( ErrChangesNeeded = errors.New("mungedocs: changes required") + // All of the munge operations to perform. // TODO: allow selection from command line. (e.g., just check links in the examples directory.) - mungesToMake = munges{ - munger(updateTOC), - munger(checkLinks), + allMunges = []munge{ + {"table-of-contents", updateTOC}, + {"check-links", checkLinks}, } ) -// Munger processes a document, returning an updated document xor an error. -// Munger is NOT allowed to mutate 'before', if changes are needed it must copy -// data into a new byte array. -type munger func(filePath string, before []byte) (after []byte, err error) - -type munges []munger +// a munge processes a document, returning an updated document xor an error. +// The fn is NOT allowed to mutate 'before', if changes are needed it must copy +// data into a new byte array and return that. +type munge struct { + name string + fn func(filePath string, before []byte) (after []byte, err error) +} type fileProcessor struct { // Which munge functions should we call? - munges munges + munges []munge // Are we allowed to make changes? verifyOnly bool } // Either change a file or verify that it needs no changes (according to modify argument) -func (f fileProcessor) visit(path string, i os.FileInfo, e error) error { +func (f fileProcessor) visit(path string) error { if !strings.HasSuffix(path, ".md") { return nil } @@ -68,31 +70,55 @@ func (f fileProcessor) visit(path string, i os.FileInfo, e error) error { } modificationsMade := false + errFound := false + filePrinted := false for _, munge := range f.munges { - after, err := munge(path, fileBytes) - if err != nil { - return err - } - if !modificationsMade { - if !bytes.Equal(after, fileBytes) { - modificationsMade = true - if f.verifyOnly { - // We're not allowed to make changes. - return ErrChangesNeeded - } + after, err := munge.fn(path, fileBytes) + if err != nil || !bytes.Equal(after, fileBytes) { + if !filePrinted { + fmt.Printf("%s\n----\n", path) + filePrinted = true } + fmt.Printf("%s:\n", munge.name) + if err != nil { + fmt.Println(err) + errFound = true + } else { + fmt.Println("contents were modified") + modificationsMade = true + } + fmt.Println("") } fileBytes = after } // Write out new file with any changes. if modificationsMade { + if f.verifyOnly { + // We're not allowed to make changes. + return ErrChangesNeeded + } ioutil.WriteFile(path, fileBytes, 0644) } + if errFound { + return ErrChangesNeeded + } return nil } +func newWalkFunc(fp *fileProcessor, changesNeeded *bool) filepath.WalkFunc { + return func(path string, info os.FileInfo, err error) error { + if err := fp.visit(path); err != nil { + *changesNeeded = true + if err != ErrChangesNeeded { + return err + } + } + return nil + } +} + func main() { flag.Parse() @@ -102,30 +128,25 @@ func main() { } fp := fileProcessor{ - munges: mungesToMake, + munges: allMunges, verifyOnly: *verify, } // For each markdown file under source docs root, process the doc. - // If any error occurs, will exit with failure. - // If verify is true, then status is 0 for no changes needed, 1 for changes needed - // and >1 for an error during processing. - // If verify is false, then status is 0 if changes successfully made or no changes needed, - // 1 if changes were needed but require human intervention, and >1 for an unexpected - // error during processing. - err := filepath.Walk(*rootDir, fp.visit) + // - If any error occurs: exit with failure (exit >1). + // - If verify is true: exit 0 if no changes needed, exit 1 if changes + // needed. + // - If verify is false: exit 0 if changes successfully made or no + // changes needed. + var changesNeeded bool + + err := filepath.Walk(*rootDir, newWalkFunc(&fp, &changesNeeded)) if err != nil { - if err == ErrChangesNeeded { - if *verify { - fmt.Fprintf(os.Stderr, - "Some changes needed but not made due to --verify=true\n") - } else { - fmt.Fprintf(os.Stderr, - "Some changes needed but human intervention is required\n") - } - os.Exit(1) - } - fmt.Fprintf(os.Stderr, "filepath.Walk() returned %v\n", err) + fmt.Fprintf(os.Stderr, "ERROR: %v\n", err) os.Exit(2) } + if changesNeeded && *verify { + fmt.Fprintf(os.Stderr, "FAIL: changes needed but not made due to --verify\n") + os.Exit(1) + } }