Skip to content
This repository has been archived by the owner on Jun 27, 2023. It is now read-only.

Improve performance of mock generation (#396) #397

Merged
merged 3 commits into from
Feb 22, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 22 additions & 15 deletions mockgen/mockgen.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ package main
// TODO: This does not support embedding package-local interfaces in a separate file.

import (
"bufio"
"bytes"
"encoding/json"
"flag"
"fmt"
"go/build"
Expand Down Expand Up @@ -304,10 +304,16 @@ func (g *generator) Generate(pkg *model.Package, outputPkgName string, outputPac
}
sort.Strings(sortedPaths)

importPaths := make([]string, 0)
codyoss marked this conversation as resolved.
Show resolved Hide resolved
for _, pth := range sortedPaths {
codyoss marked this conversation as resolved.
Show resolved Hide resolved
importPaths = append(importPaths, pth)
}
packagesName := lookupPackagesName(importPaths)

g.packageMap = make(map[string]string, len(im))
localNames := make(map[string]bool, len(im))
for _, pth := range sortedPaths {
base, ok := lookupPackageName(pth)
base, ok := packagesName[pth]
if !ok {
base = sanitize(path.Base(pth))
}
Expand Down Expand Up @@ -622,22 +628,23 @@ func (g *generator) Output() []byte {
return src
}

func lookupPackageName(importPath string) (string, bool) {
var pkg struct {
Name string
}
func lookupPackagesName(importPaths []string) map[string]string {
codyoss marked this conversation as resolved.
Show resolved Hide resolved
names := make(map[string]string)
codyoss marked this conversation as resolved.
Show resolved Hide resolved
b := bytes.NewBuffer(nil)
cmd := exec.Command("go", "list", "-json", importPath)
args := []string{"list", "-f", "{{.Name}} {{.ImportPath}}"}
args = append(args, importPaths...)
cmd := exec.Command("go", args...)
cmd.Stdout = b
err := cmd.Run()
if err != nil {
return "", false
}
err = json.Unmarshal(b.Bytes(), &pkg)
if err != nil {
return "", false
cmd.Run()
sc := bufio.NewScanner(b)
for sc.Scan() {
codyoss marked this conversation as resolved.
Show resolved Hide resolved
pkg := strings.Split(sc.Text(), " ")
if len(pkg) != 2 {
codyoss marked this conversation as resolved.
Show resolved Hide resolved
log.Fatalln("Unable to lookup packages name: invalid output of go list command")
}
names[pkg[1]] = pkg[0]
}
return pkg.Name, true
return names
}

func printVersion() {
Expand Down
37 changes: 18 additions & 19 deletions mockgen/mockgen_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -335,30 +335,29 @@ func TestGetArgNames(t *testing.T) {
}
}

func Test_lookupPackageName(t *testing.T) {
type args struct {
importPath string
}
func Test_lookupPackagesName(t *testing.T) {
tests := []struct {
name string
codyoss marked this conversation as resolved.
Show resolved Hide resolved
importPath string
wantPackageName string
wantOK bool
shouldPresent bool
}{
{"golang package", "context", "context", true},
{"third party", "golang.org/x/tools/present", "present", true},
{"modules", "rsc.io/quote/v3", "quote", true},
{"fail", "this/should/not/work", "", false},
{"context", "context", true},
{"golang.org/x/tools/present", "present", true},
{"rsc.io/quote/v3", "quote", true},
{"this/should/not/work", "", false},
}
importPaths := make([]string, 0)
for _, t := range tests {
importPaths = append(importPaths, t.importPath)
}
gotPackagesName := lookupPackagesName(importPaths)
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
gotPackageName, gotOk := lookupPackageName(tt.importPath)
if gotPackageName != tt.wantPackageName {
t.Errorf("lookupPackageName() gotPackageName = %v, wantPackageName %v", gotPackageName, tt.wantPackageName)
}
if gotOk != tt.wantOK {
t.Errorf("lookupPackageName() gotOk = %v, wantOK %v", gotOk, tt.wantOK)
}
})
gotPackageName, gotOk := gotPackagesName[tt.importPath]
if gotPackageName != tt.wantPackageName {
t.Errorf("lookupPackagesName() gotPackageName = %v, wantPackageName = %v", gotPackageName, tt.wantPackageName)
}
if gotOk != tt.shouldPresent {
t.Errorf("lookupPackageName() gotOk = %v, shouldPresent = %v", gotOk, tt.shouldPresent)
}
}
}
11 changes: 10 additions & 1 deletion mockgen/parse.go
Original file line number Diff line number Diff line change
Expand Up @@ -432,6 +432,15 @@ func (p *fileParser) parseType(pkg string, typ ast.Expr) (model.Type, error) {
// importsOfFile returns a map of package name to import path
// of the imports in file.
func importsOfFile(file *ast.File) (normalImports map[string]string, dotImports []string) {
importPaths := make([]string, 0)
codyoss marked this conversation as resolved.
Show resolved Hide resolved
for _, is := range file.Imports {
if is.Name != nil {
continue
}
importPath := is.Path.Value[1 : len(is.Path.Value)-1] // remove quotes
importPaths = append(importPaths, importPath)
}
packagesName := lookupPackagesName(importPaths)
normalImports = make(map[string]string)
dotImports = make([]string, 0)
for _, is := range file.Imports {
Expand All @@ -445,7 +454,7 @@ func importsOfFile(file *ast.File) (normalImports map[string]string, dotImports
}
pkgName = is.Name.Name
} else {
pkg, ok := lookupPackageName(importPath)
pkg, ok := packagesName[importPath]
if !ok {
// Fallback to import path suffix. Note that this is uncertain.
_, last := path.Split(importPath)
Expand Down