diff --git a/rm-gocheck.go b/rm-gocheck.go deleted file mode 100644 index 0067ca2b5b..0000000000 --- a/rm-gocheck.go +++ /dev/null @@ -1,472 +0,0 @@ -// +build ignore - -package main - -import ( - "bufio" - "bytes" - "errors" - "flag" - "fmt" - "go/format" - "io/ioutil" - "os" - "os/exec" - "path/filepath" - "regexp" - "strings" - "sync" -) - -var ( - shouldCommit = flag.Bool("commit", false, "if set, each step will result in a commit") - filter = flag.String("filter", "", "only run on files matching filter") - titlePrefix = flag.String("prefix", "rm-gocheck: ", "commit title prefix") - allFiles []string - fileToCmp = map[string]string{} - cmps = map[string][]string{} -) - -type action func(*step) string - -type step struct { - files []string - pkgs map[string]string - - title string - pattern string - action action - comment string -} - -func mustSh(format string, args ...interface{}) (output []string) { - var err error - output, err = sh(format, args...) - if err != nil { - panic(err) - } - return -} - -func sh(format string, args ...interface{}) (output []string, err error) { - cmdargs := fmt.Sprintf(format, args...) - out, err := exec.Command("sh", "-c", cmdargs).CombinedOutput() - if err != nil { - return nil, fmt.Errorf("cmd=%s\nout=%s\n", cmdargs, out) - } - l := strings.Split(string(out), "\n") - // remove last element if empty - if len(l[len(l)-1]) == 0 { - l = l[:len(l)-1] - } - return l, nil -} - -func listToArgs(l []string) string { - s := fmt.Sprintf("%q", l) - s = s[1 : len(s)-1] - return s -} - -func Replace(subst string) action { - return func(s *step) string { - return fmt.Sprintf("sed -E -i 's#%s#%s#g' \\\n-- %s", s.pattern, subst, listToArgs(s.files)) - } -} - -func CmpReplace(subst string) action { - return func(s *step) string { - var allCmdArgs, filesNeedingCmpImport []string - for _, file := range s.files { - cmp, ok := fileToCmp[file] - if !ok { - cmp = "cmp" - l := mustSh(`grep -m 1 -F '"gotest.tools/assert/cmp"' %s | awk '{print $1}'`, file) - if len(l) > 0 { - cmp = l[0] - } else { - filesNeedingCmpImport = append(filesNeedingCmpImport, file) - } - fileToCmp[file] = cmp - cmps[cmp] = append(cmps[cmp], file) - } - } - - if len(filesNeedingCmpImport) > 0 { - linesep := " \\\n" - importCmd := fmt.Sprintf(`sed -E -i '0,/^import "github\.com/ s/^(import "github\.com.*)/\1\nimport "gotest.tools\/assert\/cmp")/'%s-- %s`, linesep, listToArgs(filesNeedingCmpImport)) - allCmdArgs = append(allCmdArgs, importCmd) - importCmd = fmt.Sprintf(`sed -E -i '0,/^\t+"github\.com/ s/(^\t+"github\.com.*)/\1\n"gotest.tools\/assert\/cmp"/'%s-- %s`, linesep, listToArgs(filesNeedingCmpImport)) - allCmdArgs = append(allCmdArgs, importCmd) - } - - for cmp, files := range cmps { - cmdargs := fmt.Sprintf("sed -E -i 's#%s#%s#g' \\\n-- %s", s.pattern, strings.ReplaceAll(subst, "${cmp}", cmp), listToArgs(files)) - allCmdArgs = append(allCmdArgs, cmdargs) - } - return strings.Join(allCmdArgs, " \\\n&& \\\n") - } -} - -func redress(pattern string, files ...string) error { - rgx, err := regexp.Compile(pattern) - if err != nil { - return err - } - if len(files) == 0 { - return errors.New("no files provided") - } - fn := func(file string) error { - f, err := os.Open(file) - if err != nil { - return err - } - defer f.Close() - - tmpName := file + ".tmp" - fixed, err := os.Create(tmpName) - if err != nil { - return err - } - defer fixed.Close() - - const ( - searching = iota - found - line_done - ) - state := searching - s := bufio.NewScanner(f) - for s.Scan() { - b := s.Bytes() - if state != found { - bb := bytes.TrimRight(b, " \t") - if state == line_done && len(bb) == 0 { - continue - } - state = searching - if !rgx.Match(b) { - fixed.Write(b) - fixed.Write([]byte{'\n'}) - } else { - fixed.Write(bb) - fixed.Write([]byte{' '}) - state = found - } - continue - } - b = bytes.TrimRight(b, " \t") - fixed.Write(b) - if len(b) > 0 { - switch b[len(b)-1] { - case ',', '(': - fixed.Write([]byte{' '}) - continue - case ')': - fixed.Write([]byte{'\n'}) - state = line_done - } - } - } - if err := s.Err(); err != nil { - return err - } - - fixed.Close() - f.Close() - src, err := ioutil.ReadFile(tmpName) - if err != nil { - return err - } - src, err = format.Source(src) - if err != nil { - return err - } - os.Remove(tmpName) - return ioutil.WriteFile(file, src, 0644) - } - - var wg sync.WaitGroup - wg.Add(len(files)) - for _, file := range files { - go func(file string) { - defer wg.Done() - if err := fn(file); err != nil { - panic(fmt.Sprintf("redress %s: %v", file, err)) - } - }(file) - } - wg.Wait() - return nil -} - -func Redress(s *step) string { - return fmt.Sprintf("go run rm-gocheck.go redress '%s' \\\n %s", s.pattern, listToArgs(s.files)) -} - -func Format(s *step) string { - pkgs := make([]string, 0, len(s.pkgs)) - for dir := range s.pkgs { - pkgs = append(pkgs, "./"+dir) - } - files := listToArgs(pkgs) - return fmt.Sprintf("goimports -w \\\n-- %s \\\n&& \\\n gofmt -w -s \\\n-- %s", files, files) -} - -func CommentInterface(s *step) string { - cmds := make([]string, 0, len(s.pkgs)) - for dir := range s.pkgs { - cmd := fmt.Sprintf(`while :; do \ - out=$(go test -c ./%s 2>&1 | grep 'cannot use nil as type string in return argument') || break - echo "$out" | while read line; do - file=$(echo "$line" | cut -d: -f1) - n=$(echo "$line" | cut -d: -f2) - sed -E -i "${n}"'s#\b(return .*, )nil#\1""#g' "$file" - done -done`, dir) - cmds = append(cmds, cmd) - } - return strings.Join(cmds, " \\\n&& \\\n") -} - -func Eg(template string, prehook action, helperTypes string) action { - return func(s *step) string { - cmds := make([]string, 0, 3+4*len(s.pkgs)) - - if prehook != nil { - cmds = append(cmds, prehook(s)) - } - - cmdstr := fmt.Sprintf(`go get -d golang.org/x/tools/cmd/eg && dir=$(go env GOPATH)/src/golang.org/x/tools && git -C "$dir" fetch https://github.com/tiborvass/tools handle-variadic && git -C "$dir" checkout 61a94b82347c29b3289e83190aa3dda74d47abbb && go install golang.org/x/tools/cmd/eg`) - cmds = append(cmds, cmdstr) - - for dir, pkg := range s.pkgs { - cmds = append(cmds, fmt.Sprintf(`/bin/echo -e 'package %s\n%s' > ./%s/eg_helper.go`, pkg, helperTypes, dir)) - cmds = append(cmds, fmt.Sprintf(`goimports -w ./%s`, dir)) - cmds = append(cmds, fmt.Sprintf(`eg -w -t %s -- ./%s`, template, dir)) - cmds = append(cmds, fmt.Sprintf(`rm -f ./%s/eg_helper.go`, dir)) - } - cmds = append(cmds, fmt.Sprintf("go run rm-gocheck.go redress '%s' \\\n %s", `\bassert\.Assert\b.*(\(|,)\s*$`, listToArgs(s.files))) - return strings.Join(cmds, " \\\n&& \\\n") - } -} - -func do(steps []step) { - fileArgs := listToArgs(allFiles) - for _, s := range steps { - fmt.Print(s.title, "... ") - s.files, _ = sh(`git grep --name-only -E '%s' -- %s`, s.pattern, fileArgs) - if len(s.files) == 0 { - fmt.Println("no files match") - continue - } - s.pkgs = map[string]string{} - pkg := "" - if len(s.files) > 0 { - x := mustSh(`grep -m1 '^package ' -- %s | cut -d' ' -f2`, s.files[0]) - pkg = x[0] - } - for _, file := range s.files { - s.pkgs[filepath.Dir(file)] = pkg - } - cmdstr := s.action(&s) - mustSh(cmdstr) - if *shouldCommit { - if len(s.comment) > 0 { - s.comment = "\n\n" + s.comment - } - msg := fmt.Sprintf("%s%s\n\n%s%s", *titlePrefix, s.title, cmdstr, s.comment) - sh(`git add %s`, listToArgs(s.files)) - cmd := exec.Command("git", "commit", "-s", "-F-") - cmd.Stdin = strings.NewReader(msg) - out, err := cmd.CombinedOutput() - if err != nil { - panic(string(out)) - } - fmt.Println("committed") - } else { - fmt.Println("done") - } - } -} - -func main() { - flag.Parse() - - args := flag.Args() - if len(args) > 0 { - switch cmd := args[0]; cmd { - case "redress": - if len(args) < 3 { - panic(fmt.Sprintf("usage: %s [flags] redress ", os.Args[0])) - } - if err := redress(args[1], args[2:]...); err != nil { - panic(fmt.Sprintf("redress: %v", err)) - } - return - default: - panic(fmt.Sprintf("unknown command %s", cmd)) - } - } - - allFiles, _ = sh(`git grep --name-only '"github.com/go-check/check"' :**.go | grep -vE '^(vendor/|integration-cli/checker|rm-gocheck\.go|template\..*\.go)' | grep -E '%s'`, *filter) - if len(allFiles) == 0 { - return - } - - do([]step{ - { - title: "normalize c.Check to c.Assert", - pattern: `\bc\.Check\(`, - action: Replace(`c.Assert(`), - }, - { - title: "redress multiline c.Assert calls", - pattern: `\bc\.Assert\b.*(,|\()\s*$`, - action: Redress, - }, - { - title: "c.Assert(...) -> assert.Assert(c, ...)", - pattern: `\bc\.Assert\(`, - action: Replace(`assert.Assert(c, `), - }, - { - title: "check.C -> testing.B for BenchmarkXXX", - pattern: `( Benchmark[^\(]+\([^ ]+ \*)check\.C\b`, - action: Replace(`\1testing.B`), - }, - { - title: "check.C -> testing.T", - pattern: `\bcheck\.C\b`, - action: Replace(`testing.T`), - }, - { - title: "ErrorMatches -> assert.ErrorContains", - pattern: `\bassert\.Assert\(c, (.*), check\.ErrorMatches,`, - action: Replace(`assert.ErrorContains(c, \1,`), - }, - { - title: "normalize to use checker", - pattern: `\bcheck\.(Equals|DeepEquals|HasLen|IsNil|Matches|Not|NotNil)\b`, - action: Replace(`checker.\1`), - }, - { - title: "Not(IsNil) -> != nil", - pattern: `\bassert\.Assert\(c, (.*), checker\.Not\(checker\.IsNil\)`, - action: Replace(`assert.Assert(c, \1 != nil`), - }, - { - title: "Not(Equals) -> a != b", - pattern: `\bassert\.Assert\(c, (.*), checker\.Not\(checker\.Equals\), (.*)`, - action: Replace(`assert.Assert(c, \1 != \2`), - }, - { - title: "Not(Matches) -> !cmp.Regexp", - pattern: `\bassert\.Assert\(c, (.*), checker\.Not\(checker\.Matches\), (.*)\)`, - action: CmpReplace(`assert.Assert(c, !${cmp}.Regexp("^"+\2+"$", \1)().Success())`), - }, - { - title: "Equals -> assert.Equal", - pattern: `\bassert\.Assert\(c, (.*), checker\.Equals, (.*)`, - action: Replace(`assert.Equal(c, \1, \2`), - }, - { - title: "DeepEquals -> assert.DeepEqual", - pattern: `\bassert\.Assert\(c, (.*), checker\.DeepEquals, (.*)`, - action: Replace(`assert.DeepEqual(c, \1, \2`), - }, - { - title: "HasLen -> assert.Equal + len()", - pattern: `\bassert\.Assert\(c, (.*), checker\.HasLen, (.*)`, - action: Replace(`assert.Equal(c, len(\1), \2`), - }, - { - title: "IsNil", - pattern: `\bassert\.Assert\(c, (.*), checker\.IsNil\b`, - action: Replace(`assert.Assert(c, \1 == nil`), - }, - { - title: "NotNil", - pattern: `\bassert\.Assert\(c, (.*), checker\.NotNil\b`, - action: Replace(`assert.Assert(c, \1 != nil`), - }, - { - title: "False", - pattern: `\bassert\.Assert\(c, (.*), checker\.False\b`, - action: Replace(`assert.Assert(c, !\1`), - }, - { - title: "True", - pattern: `\bassert\.Assert\(c, (.*), checker\.True`, - action: Replace(`assert.Assert(c, \1`), - }, - { - title: "redress check.Suite calls", - pattern: `[^/]\bcheck\.Suite\(.*\{\s*$`, - action: Redress, - }, - { - title: "comment out check.Suite calls", - pattern: `^([^*])+?((var .*)?check\.Suite\(.*\))`, - action: Replace(`\1/*\2*/`), - }, - { - title: "comment out check.TestingT", - pattern: `([^*])(check\.TestingT\([^\)]+\))`, - action: Replace(`\1/*\2*/`), - }, - { - title: "run goimports to compile successfully", - action: Format, - }, - { - title: "Matches -> cmp.Regexp", - pattern: `\bassert\.Assert\(c, (.*), checker\.Matches, (.*)\)$`, - action: Eg("template.matches.go", - CmpReplace(`assert.Assert(c, eg_matches(${cmp}.Regexp, \1, \2))`), - `var eg_matches func(func(cmp.RegexOrPattern, string) cmp.Comparison, interface{}, string, ...interface{}) bool`), - }, - { - title: "Not(Contains) -> !strings.Contains", - pattern: `\bassert\.Assert\(c, (.*), checker\.Not\(checker\.Contains\), (.*)\)$`, - action: Eg("template.not_contains.go", - Replace(`assert.Assert(c, !eg_contains(\1, \2))`), - `var eg_contains func(arg1, arg2 string, extra ...interface{}) bool`), - }, - { - title: "Contains -> strings.Contains", - pattern: `\bassert\.Assert\(c, (.*), checker\.Contains, (.*)\)$`, - action: Eg("template.contains.go", - Replace(`assert.Assert(c, eg_contains(\1, \2))`), - `var eg_contains func(arg1, arg2 string, extra ...interface{}) bool`), - }, - { - title: "convert check.Commentf to string - with multiple args", - pattern: `\bcheck.Commentf\(([^,]+),(.*)\)`, - action: Replace(`fmt.Sprintf(\1,\2)`), - }, - { - title: "convert check.Commentf to string - with just one string", - pattern: `\bcheck.Commentf\(("[^"]+")\)`, - action: Replace(`\1`), - }, - { - title: "convert check.Commentf to string - other", - pattern: `\bcheck.Commentf\(([^\)]+)\)`, - action: Replace(`\1`), - }, - { - title: "check.CommentInterface -> string", - pattern: `(\*testing\.T\b.*)check\.CommentInterface\b`, - action: Replace(`\1string`), - }, - { - title: "goimports", - action: Format, - }, - { - title: "fix compile errors from converting check.CommentInterface to string", - action: CommentInterface, - }, - }) -} diff --git a/template.contains.go b/template.contains.go deleted file mode 100644 index 673c95bfb1..0000000000 --- a/template.contains.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build ignore - -package main - -import ( - "strings" - "testing" - - "gotest.tools/assert" -) - -type fn func(arg1, arg2 string, extra ...interface{}) bool -type assertfn func(t assert.TestingT, comparison assert.BoolOrComparison, msgAndArgs ...interface{}) - -func before( - t *testing.T, - a assertfn, - eg_contains fn, - arg1 string, - arg2 string, - extra ...interface{}) { - - a(t, eg_contains(arg1, arg2, extra...)) -} - -func after( - t *testing.T, - a assertfn, - eg_contains fn, - arg1 string, - arg2 string, - extra ...interface{}) { - - a(t, strings.Contains(arg1, arg2), extra...) -} diff --git a/template.matches.go b/template.matches.go deleted file mode 100644 index b9c563f05d..0000000000 --- a/template.matches.go +++ /dev/null @@ -1,37 +0,0 @@ -// +build ignore - -package main - -import ( - "testing" - - "gotest.tools/assert" - "gotest.tools/assert/cmp" -) - -type fn func(re func(cmp.RegexOrPattern, string) cmp.Comparison, r interface{}, v string, extra ...interface{}) bool -type assertfn func(t assert.TestingT, comparison assert.BoolOrComparison, msgAndArgs ...interface{}) - -func before( - t *testing.T, - a assertfn, - eg_matches fn, - re func(cmp.RegexOrPattern, string) cmp.Comparison, - r string, - v string, - extra ...interface{}) { - - a(t, eg_matches(re, v, r, extra...)) -} - -func after( - t *testing.T, - a assertfn, - eg_matches fn, - re func(cmp.RegexOrPattern, string) cmp.Comparison, - r string, - v string, - extra ...interface{}) { - - a(t, re("^"+r+"$", v), extra...) -} diff --git a/template.not_contains.go b/template.not_contains.go deleted file mode 100644 index 4d5609cda0..0000000000 --- a/template.not_contains.go +++ /dev/null @@ -1,35 +0,0 @@ -// +build ignore - -package main - -import ( - "strings" - "testing" - - "gotest.tools/assert" -) - -type fn func(arg1, arg2 string, extra ...interface{}) bool -type assertfn func(t assert.TestingT, comparison assert.BoolOrComparison, msgAndArgs ...interface{}) - -func before( - t *testing.T, - a assertfn, - eg_contains fn, - arg1 string, - arg2 string, - extra ...interface{}) { - - a(t, !eg_contains(arg1, arg2, extra...)) -} - -func after( - t *testing.T, - a assertfn, - eg_contains fn, - arg1 string, - arg2 string, - extra ...interface{}) { - - a(t, !strings.Contains(arg1, arg2), extra...) -} diff --git a/template.waitAndAssert.go b/template.waitAndAssert.go deleted file mode 100644 index 8b3d1d3449..0000000000 --- a/template.waitAndAssert.go +++ /dev/null @@ -1,40 +0,0 @@ -// +build ignore - -package main - -import ( - "testing" - "time" - - "github.com/docker/docker/integration-cli/checker" - "gotest.tools/assert" - "gotest.tools/poll" -) - -func pollCheck(t *testing.T, f interface{}, compare func(x interface{}) assert.BoolOrComparison) poll.Check - -type eg_compareFunc func(...interface{}) checker.Compare - -type waitAndAssertFunc func(t *testing.T, timeout time.Duration, ff, comparison interface{}, args ...interface{}) - -func before( - waitAndAssert waitAndAssertFunc, - t *testing.T, - timeout time.Duration, - f interface{}, - comparison interface{}, - args ...interface{}) { - - waitAndAssert(t, timeout, f, comparison, args...) -} - -func after( - waitAndAssert waitAndAssertFunc, - t *testing.T, - timeout time.Duration, - f interface{}, - comparison interface{}, - args ...interface{}) { - - poll.WaitOn(t, pollCheck(t, f, comparison.(eg_compareFunc)(args...)), poll.WithTimeout(timeout)) -}