eng/tools/apidiff/cmd/common.go (145 lines of code) (raw):

// Copyright (c) Microsoft Corporation. All rights reserved. // Licensed under the MIT License. See License.txt in the project root for license information. package cmd import ( "encoding/json" "errors" "fmt" "os" "path/filepath" "strings" "time" "github.com/Azure/azure-sdk-for-go/eng/tools/internal/ioext" "github.com/Azure/azure-sdk-for-go/eng/tools/internal/repo" "github.com/Azure/azure-sdk-for-go/eng/tools/internal/report" ) func printf(format string, a ...interface{}) { if !quietFlag { fmt.Printf(format, a...) } } func println(a ...interface{}) { if !quietFlag { fmt.Println(a...) } } func dprintf(format string, a ...interface{}) { if debugFlag { printf(format, a...) } } func dprintln(a ...interface{}) { if debugFlag { println(a...) } } func vprintf(format string, a ...interface{}) { if verboseFlag { printf(format, a...) } } func vprintln(a ...interface{}) { if verboseFlag { println(a...) } } func processArgsAndClone(args []string) (cln repo.WorkingTree, err error) { if onlyAdditiveChangesFlag && onlyBreakingChangesFlag { err = errors.New("flags 'additions' and 'breakingchanges' are mutually exclusive") return } // there should be at minimum two args, a directory and a // sequence of commits, i.e. "d:\foo 1,2,3". else a directory // and two commits, i.e. "d:\foo 1 2" or "d:\foo 1 2,3" if len(args) < 2 { err = errors.New("not enough args were supplied") return } // here args[1] should be a comma-delimited list of commits if len(args) == 2 && strings.Index(args[1], ",") < 0 { err = errors.New("expected a comma-delimited list of commits") return } dir := args[0] dir, err = filepath.Abs(dir) if err != nil { err = fmt.Errorf("failed to convert path '%s' to absolute path: %v", dir, err) return } src, err := repo.Get(dir) if err != nil { err = fmt.Errorf("failed to get repository: %v", err) return } tempRepoDir := filepath.Join(os.TempDir(), fmt.Sprintf("apidiff-%v", time.Now().Unix())) if copyRepoFlag { vprintf("copying '%s' into '%s'...\n", src.Root(), tempRepoDir) err = ioext.CopyDir(src.Root(), tempRepoDir) if err != nil { err = fmt.Errorf("failed to copy repo: %v", err) return } cln, err = repo.Get(tempRepoDir) if err != nil { err = fmt.Errorf("failed to get copied repo: %v", err) return } } else { vprintf("cloning '%s' into '%s'...\n", src.Root(), tempRepoDir) cln, err = src.Clone(tempRepoDir) if err != nil { err = fmt.Errorf("failed to clone repository: %v", err) return } } // fix up pkgDir to the clone args[0] = strings.Replace(dir, src.Root(), cln.Root(), 1) return } type reportGenFunc func(dir string, cln repo.WorkingTree, baseCommit, targetCommit string) error func generateReports(args []string, cln repo.WorkingTree, fn reportGenFunc) error { defer func() { // delete clone vprintln("cleaning up clone") err := os.RemoveAll(cln.Root()) if err != nil { vprintf("failed to delete temp repo: %v\n", err) } }() var commits []string // if the commits are specified as 1 2,3,4 then it means that commit 1 is // always the base commit and to compare it against each target commit in // the sequence. however if it's specifed as 1,2,3,4 then the base commit // is relative to the iteration, i.e. compare 1-2, 2-3, 3-4. fixedBase := true if len(args) == 3 { commits = make([]string, 2, 2) commits[0] = args[1] commits[1] = args[2] } else { commits = strings.Split(args[1], ",") fixedBase = false } for i := 0; i+1 < len(commits); i++ { baseCommit := commits[i] if fixedBase { baseCommit = commits[0] } targetCommit := commits[i+1] err := fn(args[0], cln, baseCommit, targetCommit) if err != nil { return err } } return nil } // compares report status with the desired report options (breaking/additions) // to determine if the program should terminate with a non-zero exit code. func evalReportStatus(r report.Status) { if onlyBreakingChangesFlag && r.HasBreakingChanges() { os.Exit(1) } if onlyAdditiveChangesFlag && !r.HasAdditiveChanges() { os.Exit(1) } } // PrintReport prints the report to stdout func PrintReport(r report.Status) error { if r.IsEmpty() { println("no changes were found") return nil } if !suppressReport { b, err := json.MarshalIndent(r, "", " ") if err != nil { return fmt.Errorf("failed to marshal report: %v", err) } println(string(b)) } return nil }