goc build init version

This commit is contained in:
lyyyuna 2021-06-20 21:14:21 +08:00
parent 4c9163ce64
commit 8df7498c33
7 changed files with 117 additions and 25 deletions

View File

@ -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")
}

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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 {

View File

@ -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()
}

View File

@ -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 pathfile 在上一步已被排除
// 只考虑 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)
}