goc build init version
This commit is contained in:
parent
4c9163ce64
commit
8df7498c33
@ -1,6 +1,10 @@
|
||||
package build
|
||||
|
||||
import (
|
||||
"os"
|
||||
"os/exec"
|
||||
|
||||
"github.com/qiniu/goc/v2/pkg/config"
|
||||
"github.com/qiniu/goc/v2/pkg/cover"
|
||||
"github.com/qiniu/goc/v2/pkg/flag"
|
||||
"github.com/qiniu/goc/v2/pkg/log"
|
||||
@ -17,9 +21,13 @@ type Build struct {
|
||||
// consumes args, get package dirs, read project meta info.
|
||||
func NewBuild(cmd *cobra.Command, args []string) *Build {
|
||||
b := &Build{}
|
||||
// 1. 解析 goc 命令行和 go 命令行
|
||||
remainedArgs := flag.BuildCmdArgsParse(cmd, args)
|
||||
// 2. 解析 go 包位置
|
||||
flag.GetPackagesDir(remainedArgs)
|
||||
// 3. 读取工程元信息:go.mod, pkgs list ...
|
||||
b.readProjectMetaInfo()
|
||||
// 4. 展示元信息
|
||||
b.displayProjectMetaInfo()
|
||||
|
||||
return b
|
||||
@ -31,12 +39,54 @@ func NewBuild(cmd *cobra.Command, args []string) *Build {
|
||||
// 2. inject cover variables and functions into the project,
|
||||
// 3. build the project in temp.
|
||||
func (b *Build) Build() {
|
||||
// 1. 拷贝至临时目录
|
||||
b.copyProjectToTmp()
|
||||
// defer b.clean()
|
||||
log.Donef("project copied to temporary directory")
|
||||
|
||||
// inject cover vars
|
||||
// 2. inject cover vars
|
||||
cover.Inject()
|
||||
|
||||
// build in the temp project
|
||||
// 3. build in the temp project
|
||||
b.doBuildInTemp()
|
||||
}
|
||||
|
||||
func (b *Build) doBuildInTemp() {
|
||||
goflags := config.GocConfig.Goflags
|
||||
// 检查用户是否自定义了 -o
|
||||
oSet := false
|
||||
for _, flag := range goflags {
|
||||
if flag == "-o" {
|
||||
oSet = true
|
||||
}
|
||||
}
|
||||
|
||||
// 如果没被设置就加一个至原命令执行的目录
|
||||
if !oSet {
|
||||
goflags = append(goflags, "-o", config.GocConfig.CurWd)
|
||||
}
|
||||
|
||||
pacakges := config.GocConfig.TmpPkgDir
|
||||
if config.GocConfig.ContainSpecialPattern {
|
||||
pacakges = pacakges + "/..."
|
||||
}
|
||||
|
||||
goflags = append(goflags, pacakges)
|
||||
|
||||
args := []string{"build"}
|
||||
args = append(args, goflags...)
|
||||
// go 命令行由 go build [-o output] [build flags] [packages] 组成
|
||||
cmd := exec.Command("go", args...)
|
||||
cmd.Dir = config.GocConfig.TmpModProjectDir
|
||||
cmd.Stdout = os.Stdout
|
||||
cmd.Stderr = os.Stderr
|
||||
|
||||
log.Infof("go build cmd is: %v", cmd.Args)
|
||||
if err := cmd.Start(); err != nil {
|
||||
log.Fatalf("fail to execute go build: %v", err)
|
||||
}
|
||||
if err := cmd.Wait(); err != nil {
|
||||
log.Fatalf("fail to execute go build: %v", err)
|
||||
}
|
||||
|
||||
// done
|
||||
log.Donef("go build done")
|
||||
}
|
||||
|
@ -19,11 +19,10 @@ func (b *Build) readProjectMetaInfo() {
|
||||
// get gopath & gobin
|
||||
config.GocConfig.GOPATH = b.readGOPATH()
|
||||
config.GocConfig.GOBIN = b.readGOBIN()
|
||||
// 获取当前目录及其依赖的 package list
|
||||
config.GocConfig.Pkgs = b.listPackages(config.GocConfig.CurPkgDir)
|
||||
// 获取 [packages] 及其依赖的 package list
|
||||
pkgs := b.listPackages(config.GocConfig.CurPkgDir)
|
||||
|
||||
// get mod info
|
||||
pkgs := config.GocConfig.Pkgs
|
||||
for _, pkg := range pkgs {
|
||||
// check if go modules is enabled
|
||||
if pkg.Module == nil {
|
||||
@ -36,6 +35,13 @@ func (b *Build) readProjectMetaInfo() {
|
||||
break
|
||||
}
|
||||
|
||||
// 如果包目录不是工程根目录,那再次 go list 一次,获取整个工程的包信息
|
||||
if config.GocConfig.CurPkgDir != config.GocConfig.CurModProjectDir {
|
||||
config.GocConfig.Pkgs = b.listPackages(config.GocConfig.CurModProjectDir)
|
||||
} else {
|
||||
config.GocConfig.Pkgs = pkgs
|
||||
}
|
||||
|
||||
// get tmp folder name
|
||||
config.GocConfig.TmpModProjectDir = filepath.Join(os.TempDir(), tmpFolderName(config.GocConfig.CurModProjectDir))
|
||||
// get cur pkg dir in the corresponding tmp dir
|
||||
@ -47,7 +53,6 @@ func (b *Build) readProjectMetaInfo() {
|
||||
|
||||
// displayProjectMetaInfo prints basic infomation of this project to stdout
|
||||
func (b *Build) displayProjectMetaInfo() {
|
||||
log.Infof("Project Infomation")
|
||||
log.Infof("GOPATH: %v", config.GocConfig.GOPATH)
|
||||
log.Infof("GOBIN: %v", config.GocConfig.GOBIN)
|
||||
log.Infof("Project Directory: %v", config.GocConfig.CurModProjectDir)
|
||||
|
@ -3,17 +3,19 @@ package config
|
||||
import "time"
|
||||
|
||||
type gocConfig struct {
|
||||
Debug bool
|
||||
ImportPath string // import path of the project
|
||||
CurPkgDir string
|
||||
CurModProjectDir string
|
||||
TmpModProjectDir string
|
||||
TmpPkgDir string
|
||||
BinaryName string
|
||||
Pkgs map[string]*Package
|
||||
GOPATH string
|
||||
GOBIN string
|
||||
IsMod bool // deprecated
|
||||
Debug bool
|
||||
CurWd string
|
||||
Goflags []string
|
||||
ImportPath string // import path of the project
|
||||
CurPkgDir string
|
||||
CurModProjectDir string
|
||||
TmpModProjectDir string
|
||||
TmpPkgDir string
|
||||
ContainSpecialPattern bool // 参数中包含 ...
|
||||
Pkgs map[string]*Package
|
||||
GOPATH string
|
||||
GOBIN string
|
||||
IsMod bool // deprecated
|
||||
|
||||
GlobalCoverVarImportPath string
|
||||
GlobalCoverVarImportPathDir string
|
||||
|
@ -56,6 +56,7 @@ func init() {
|
||||
time.Sleep(waitDelay)
|
||||
continue
|
||||
}
|
||||
log.Printf("[goc][Info] connected to goc server")
|
||||
|
||||
rwc := &ReadWriteCloser{ws: ws}
|
||||
s := rpc.NewServer()
|
||||
@ -65,6 +66,7 @@ func init() {
|
||||
// exit rpc server, close ws connection
|
||||
ws.Close()
|
||||
time.Sleep(waitDelay)
|
||||
log.Printf("[goc][Error] connection to goc server broken", )
|
||||
}
|
||||
}
|
||||
|
||||
@ -84,7 +86,7 @@ func (ga *GocAgent) GetProfile(req *ProfileReq, res *ProfileRes) error {
|
||||
}
|
||||
|
||||
w := new(strings.Builder)
|
||||
fmt.Fprint(w, "south north")
|
||||
fmt.Fprint(w, "mode: {{.Mode}}\n")
|
||||
|
||||
counters, blocks := loadValues()
|
||||
var active, total int64
|
||||
|
@ -158,11 +158,13 @@ func injectGocAgent(where string, covers []*config.PackageCover) {
|
||||
GlobalCoverVarImportPath string
|
||||
Package string
|
||||
Host string
|
||||
Mode string
|
||||
}{
|
||||
Covers: covers,
|
||||
GlobalCoverVarImportPath: config.GocConfig.GlobalCoverVarImportPath,
|
||||
Package: injectPkgName,
|
||||
Host: config.GocConfig.Host,
|
||||
Mode: config.GocConfig.Mode,
|
||||
}
|
||||
|
||||
if err := coverMainTmpl.Execute(f, tmplData); err != nil {
|
||||
|
@ -2,7 +2,10 @@ package flag
|
||||
|
||||
import (
|
||||
"flag"
|
||||
"os"
|
||||
"path/filepath"
|
||||
|
||||
"github.com/qiniu/goc/v2/pkg/config"
|
||||
"github.com/qiniu/goc/v2/pkg/log"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/spf13/pflag"
|
||||
@ -15,7 +18,8 @@ The [goc flags] can be placed in anywhere in the command line.
|
||||
However, other flags' order are same with the go official command.
|
||||
`
|
||||
|
||||
// BuildCmdArgsParse parse both go flags and goc flags, it returns all non-flag arguments.
|
||||
// BuildCmdArgsParse parse both go flags and goc flags, it rewrite go flags if
|
||||
// necessary, and returns all non-flag arguments.
|
||||
//
|
||||
// 吞下 [packages] 之前所有的 flags.
|
||||
func BuildCmdArgsParse(cmd *cobra.Command, args []string) []string {
|
||||
@ -52,6 +56,29 @@ func BuildCmdArgsParse(cmd *cobra.Command, args []string) []string {
|
||||
log.Fatalf("%v", err)
|
||||
}
|
||||
|
||||
// 找出设置的 go flag
|
||||
curWd, err := os.Getwd()
|
||||
if err != nil {
|
||||
log.Fatalf("fail to get current working directory: %v", err)
|
||||
}
|
||||
config.GocConfig.CurWd = curWd
|
||||
flags := make([]string, 0)
|
||||
goFlagSets.Visit(func(f *flag.Flag) {
|
||||
// 将用户指定 -o 改成绝对目录
|
||||
if f.Name == "o" {
|
||||
outputDir := f.Value.String()
|
||||
outputDir, err := filepath.Abs(outputDir)
|
||||
if err != nil {
|
||||
log.Fatalf("output flag is not valid: %v", err)
|
||||
}
|
||||
flags = append(flags, "-o", outputDir)
|
||||
} else {
|
||||
flags = append(flags, "-"+f.Name, f.Value.String())
|
||||
}
|
||||
})
|
||||
|
||||
config.GocConfig.Goflags = flags
|
||||
|
||||
return goFlagSets.Args()
|
||||
}
|
||||
|
||||
|
@ -38,7 +38,7 @@ func GetPackagesDir(patterns []string) {
|
||||
// 获取当前 [packages] 所在的目录位置,供后续插桩使用。
|
||||
config.GocConfig.CurPkgDir = filepath.Dir(absp)
|
||||
// 获取二进制名字
|
||||
config.GocConfig.BinaryName = filepath.Base(absp)
|
||||
// config.GocConfig.BinaryName = filepath.Base(absp)
|
||||
return
|
||||
}
|
||||
}
|
||||
@ -51,8 +51,11 @@ func GetPackagesDir(patterns []string) {
|
||||
}
|
||||
|
||||
config.GocConfig.CurPkgDir = coverWd
|
||||
config.GocConfig.BinaryName = ""
|
||||
return
|
||||
|
||||
// 是否包含 ...
|
||||
if strings.Contains(patterns[0], "...") {
|
||||
config.GocConfig.ContainSpecialPattern = true
|
||||
}
|
||||
}
|
||||
|
||||
// goFilesPackage 对一组 go 文件解析,判断是否合法
|
||||
@ -97,7 +100,7 @@ func goFilesPackage(gofiles []string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
// getDirFromImportPaths return the import path's real directory
|
||||
// getDirFromImportPaths return the import path's real abs directory
|
||||
//
|
||||
// 该函数接收到的只有 dir 或 import path,file 在上一步已被排除
|
||||
// 只考虑 go modules 的情况
|
||||
@ -134,6 +137,7 @@ func getDirFromImportPaths(patterns []string) (string, error) {
|
||||
case strings.Contains(pattern, "..."):
|
||||
i := strings.Index(pattern, "...")
|
||||
dir, _ := filepath.Split(pattern[:i])
|
||||
dir, _ = filepath.Abs(dir)
|
||||
if _, err := os.Stat(dir); err != nil {
|
||||
return "", fmt.Errorf("error (%w) get directory from the import path: %v", err, pattern)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user