github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/kmg/SubCommand/goCmd/GoTest.go (about)

     1  package goCmd
     2  
     3  import (
     4  	"flag"
     5  	"fmt"
     6  	//"github.com/bronze1man/kmg/console"
     7  	"go/build"
     8  	"os"
     9  	"path/filepath"
    10  
    11  	"github.com/bronze1man/kmg/kmgFile"
    12  
    13  	"github.com/bronze1man/kmg/kmgCmd"
    14  	"github.com/bronze1man/kmg/kmgConfig"
    15  	"github.com/bronze1man/kmg/kmgConsole"
    16  )
    17  
    18  /*
    19  递归目录的go test
    20   支持.kmg.yml目录结构提示文件(该文件必须存在)
    21   -v 更详细的描述
    22   -m 一个模块名,从这个模块名开始递归目录测试
    23   -d 一个目录名,从这个目录开始递归目录测试
    24   -bench benchmarks参数,直接传递到go test
    25   -onePackage 不递归目录测试,仅测试一个package
    26  */
    27  func runGoTest() {
    28  	command := GoTest{}
    29  	flag.BoolVar(&command.v, "v", false, "show output of test")
    30  	flag.StringVar(&command.dir, "d", "", "dir path to test")
    31  	flag.StringVar(&command.moduleName, "m", "", "module name to test")
    32  	flag.StringVar(&command.bench, "bench", "", "bench parameter pass to go test")
    33  	flag.BoolVar(&command.onePackage, "onePackage", false, "only test one package")
    34  	flag.StringVar(&command.runArg, "run", "", "Run only those tests and examples matching the regular expression.")
    35  	flag.BoolVar(&command.onlyBuild, "onlyBuild", false, "only build all package(not test)")
    36  	flag.Parse()
    37  
    38  	kmgc, err := kmgConfig.LoadEnvFromWd()
    39  	if err == nil {
    40  		command.gopath = kmgc.GOPATH[0]
    41  	} else {
    42  		if kmgConfig.IsNotFound(err) {
    43  			command.gopath = os.Getenv("GOPATH")
    44  		} else {
    45  			kmgConsole.ExitOnErr(err)
    46  		}
    47  	}
    48  	//find root path
    49  	root, err := command.findRootPath()
    50  	kmgConsole.ExitOnErr(err)
    51  	command.buildContext = &build.Context{
    52  		GOPATH:   command.gopath,
    53  		Compiler: build.Default.Compiler,
    54  	}
    55  	if command.onePackage {
    56  		err = command.handlePath(root)
    57  		kmgConsole.ExitOnErr(err)
    58  	}
    59  	err = filepath.Walk(root, func(path string, info os.FileInfo, err error) error {
    60  		if err != nil {
    61  			return err
    62  		}
    63  		if !info.IsDir() {
    64  			return nil
    65  		}
    66  		if kmgFile.IsDotFile(path) {
    67  			return filepath.SkipDir
    68  		}
    69  		return command.handlePath(path)
    70  	})
    71  	kmgConsole.ExitOnErr(err)
    72  }
    73  
    74  /*
    75  递归目录的 go test
    76   TODO 处理多个GOPATH的问题,从GOPATH里面找到这个模块
    77   支持.kmg.yml目录结构提示文件(该文件必须存在)
    78   -v 更详细的描述
    79   -m 一个模块名,从这个模块名开始递归目录测试
    80   -d 一个目录名,从这个目录开始递归目录测试
    81  */
    82  type GoTest struct {
    83  	gopath string
    84  	//context      *console.Context
    85  	v            bool
    86  	dir          string
    87  	moduleName   string
    88  	bench        string
    89  	onePackage   bool
    90  	runArg       string
    91  	buildContext *build.Context
    92  	onlyBuild    bool
    93  }
    94  
    95  func (command *GoTest) findRootPath() (root string, err error) {
    96  	if flag.NArg() == 1 {
    97  		command.moduleName = flag.Arg(0)
    98  	}
    99  	if command.dir != "" {
   100  		root = command.dir
   101  		exist, err := kmgFile.FileExist(root)
   102  		if err != nil {
   103  			return "", err
   104  		}
   105  		if !exist {
   106  			return "", fmt.Errorf("[GoTest] dir path:[%s] not found", root)
   107  		}
   108  		return root, nil
   109  	}
   110  	if command.moduleName != "" {
   111  		//TODO 处理多个GOPATH的问题,从GOPATH里面找到这个模块
   112  		root = filepath.Join(command.gopath, "src", command.moduleName)
   113  		exist, err := kmgFile.FileExist(root)
   114  		if err != nil {
   115  			return "", err
   116  		}
   117  		if !exist {
   118  			return "", fmt.Errorf("[GoTest] module name:[%s] not found", command.moduleName)
   119  		}
   120  		return root, nil
   121  	}
   122  	if root == "" {
   123  		root, err = os.Getwd()
   124  		if err != nil {
   125  			return
   126  		}
   127  	}
   128  	return
   129  }
   130  
   131  func (command *GoTest) handlePath(path string) error {
   132  	pkg, err := command.buildContext.ImportDir(path, build.ImportMode(0))
   133  	if err != nil {
   134  		//仅忽略 不是golang的目录的错误
   135  		_, ok := err.(*build.NoGoError)
   136  		if ok {
   137  			return nil
   138  		}
   139  		return err
   140  	}
   141  	if pkg.IsCommand() {
   142  		return nil
   143  	}
   144  	if command.onlyBuild || len(pkg.TestGoFiles) == 0 {
   145  		//如果没有测试文件,还会尝试build一下这个目录
   146  		return command.gobuild(path)
   147  		//return nil
   148  	}
   149  	return command.gotest(path)
   150  }
   151  
   152  func (command *GoTest) gotest(path string) error {
   153  	fmt.Printf("[gotest] path[%s]\n", path)
   154  	args := []string{"test"}
   155  	if command.v {
   156  		args = append(args, "-v")
   157  	}
   158  	if command.bench != "" {
   159  		args = append(args, "-bench", command.bench)
   160  	}
   161  	if command.runArg != "" {
   162  		args = append(args, "-run", command.runArg)
   163  	}
   164  	return kmgCmd.CmdSlice(append([]string{"go"}, args...)).
   165  		MustSetEnv("GOPATH", command.gopath).
   166  		SetDir(path).
   167  		StdioRun()
   168  }
   169  
   170  func (command *GoTest) gobuild(path string) error {
   171  	fmt.Printf("[gobuild] path[%s]\n", path)
   172  	err := kmgCmd.CmdSlice([]string{"go", "build"}).
   173  		MustSetEnv("GOPATH", command.gopath).
   174  		SetDir(path).
   175  		StdioRun()
   176  	return err
   177  }