goc build init version
This commit is contained in:
parent
4c9163ce64
commit
8df7498c33
@ -1,6 +1,10 @@
|
|||||||
package build
|
package build
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"os"
|
||||||
|
"os/exec"
|
||||||
|
|
||||||
|
"github.com/qiniu/goc/v2/pkg/config"
|
||||||
"github.com/qiniu/goc/v2/pkg/cover"
|
"github.com/qiniu/goc/v2/pkg/cover"
|
||||||
"github.com/qiniu/goc/v2/pkg/flag"
|
"github.com/qiniu/goc/v2/pkg/flag"
|
||||||
"github.com/qiniu/goc/v2/pkg/log"
|
"github.com/qiniu/goc/v2/pkg/log"
|
||||||
@ -17,9 +21,13 @@ type Build struct {
|
|||||||
// consumes args, get package dirs, read project meta info.
|
// consumes args, get package dirs, read project meta info.
|
||||||
func NewBuild(cmd *cobra.Command, args []string) *Build {
|
func NewBuild(cmd *cobra.Command, args []string) *Build {
|
||||||
b := &Build{}
|
b := &Build{}
|
||||||
|
// 1. 解析 goc 命令行和 go 命令行
|
||||||
remainedArgs := flag.BuildCmdArgsParse(cmd, args)
|
remainedArgs := flag.BuildCmdArgsParse(cmd, args)
|
||||||
|
// 2. 解析 go 包位置
|
||||||
flag.GetPackagesDir(remainedArgs)
|
flag.GetPackagesDir(remainedArgs)
|
||||||
|
// 3. 读取工程元信息:go.mod, pkgs list ...
|
||||||
b.readProjectMetaInfo()
|
b.readProjectMetaInfo()
|
||||||
|
// 4. 展示元信息
|
||||||
b.displayProjectMetaInfo()
|
b.displayProjectMetaInfo()
|
||||||
|
|
||||||
return b
|
return b
|
||||||
@ -31,12 +39,54 @@ func NewBuild(cmd *cobra.Command, args []string) *Build {
|
|||||||
// 2. inject cover variables and functions into the project,
|
// 2. inject cover variables and functions into the project,
|
||||||
// 3. build the project in temp.
|
// 3. build the project in temp.
|
||||||
func (b *Build) Build() {
|
func (b *Build) Build() {
|
||||||
|
// 1. 拷贝至临时目录
|
||||||
b.copyProjectToTmp()
|
b.copyProjectToTmp()
|
||||||
// defer b.clean()
|
// defer b.clean()
|
||||||
log.Donef("project copied to temporary directory")
|
log.Donef("project copied to temporary directory")
|
||||||
|
// 2. inject cover vars
|
||||||
// inject cover vars
|
|
||||||
cover.Inject()
|
cover.Inject()
|
||||||
|
// 3. build in the temp project
|
||||||
// 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
|
// get gopath & gobin
|
||||||
config.GocConfig.GOPATH = b.readGOPATH()
|
config.GocConfig.GOPATH = b.readGOPATH()
|
||||||
config.GocConfig.GOBIN = b.readGOBIN()
|
config.GocConfig.GOBIN = b.readGOBIN()
|
||||||
// 获取当前目录及其依赖的 package list
|
// 获取 [packages] 及其依赖的 package list
|
||||||
config.GocConfig.Pkgs = b.listPackages(config.GocConfig.CurPkgDir)
|
pkgs := b.listPackages(config.GocConfig.CurPkgDir)
|
||||||
|
|
||||||
// get mod info
|
// get mod info
|
||||||
pkgs := config.GocConfig.Pkgs
|
|
||||||
for _, pkg := range pkgs {
|
for _, pkg := range pkgs {
|
||||||
// check if go modules is enabled
|
// check if go modules is enabled
|
||||||
if pkg.Module == nil {
|
if pkg.Module == nil {
|
||||||
@ -36,6 +35,13 @@ func (b *Build) readProjectMetaInfo() {
|
|||||||
break
|
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
|
// get tmp folder name
|
||||||
config.GocConfig.TmpModProjectDir = filepath.Join(os.TempDir(), tmpFolderName(config.GocConfig.CurModProjectDir))
|
config.GocConfig.TmpModProjectDir = filepath.Join(os.TempDir(), tmpFolderName(config.GocConfig.CurModProjectDir))
|
||||||
// get cur pkg dir in the corresponding tmp dir
|
// 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
|
// displayProjectMetaInfo prints basic infomation of this project to stdout
|
||||||
func (b *Build) displayProjectMetaInfo() {
|
func (b *Build) displayProjectMetaInfo() {
|
||||||
log.Infof("Project Infomation")
|
|
||||||
log.Infof("GOPATH: %v", config.GocConfig.GOPATH)
|
log.Infof("GOPATH: %v", config.GocConfig.GOPATH)
|
||||||
log.Infof("GOBIN: %v", config.GocConfig.GOBIN)
|
log.Infof("GOBIN: %v", config.GocConfig.GOBIN)
|
||||||
log.Infof("Project Directory: %v", config.GocConfig.CurModProjectDir)
|
log.Infof("Project Directory: %v", config.GocConfig.CurModProjectDir)
|
||||||
|
@ -3,17 +3,19 @@ package config
|
|||||||
import "time"
|
import "time"
|
||||||
|
|
||||||
type gocConfig struct {
|
type gocConfig struct {
|
||||||
Debug bool
|
Debug bool
|
||||||
ImportPath string // import path of the project
|
CurWd string
|
||||||
CurPkgDir string
|
Goflags []string
|
||||||
CurModProjectDir string
|
ImportPath string // import path of the project
|
||||||
TmpModProjectDir string
|
CurPkgDir string
|
||||||
TmpPkgDir string
|
CurModProjectDir string
|
||||||
BinaryName string
|
TmpModProjectDir string
|
||||||
Pkgs map[string]*Package
|
TmpPkgDir string
|
||||||
GOPATH string
|
ContainSpecialPattern bool // 参数中包含 ...
|
||||||
GOBIN string
|
Pkgs map[string]*Package
|
||||||
IsMod bool // deprecated
|
GOPATH string
|
||||||
|
GOBIN string
|
||||||
|
IsMod bool // deprecated
|
||||||
|
|
||||||
GlobalCoverVarImportPath string
|
GlobalCoverVarImportPath string
|
||||||
GlobalCoverVarImportPathDir string
|
GlobalCoverVarImportPathDir string
|
||||||
|
@ -56,6 +56,7 @@ func init() {
|
|||||||
time.Sleep(waitDelay)
|
time.Sleep(waitDelay)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
log.Printf("[goc][Info] connected to goc server")
|
||||||
|
|
||||||
rwc := &ReadWriteCloser{ws: ws}
|
rwc := &ReadWriteCloser{ws: ws}
|
||||||
s := rpc.NewServer()
|
s := rpc.NewServer()
|
||||||
@ -65,6 +66,7 @@ func init() {
|
|||||||
// exit rpc server, close ws connection
|
// exit rpc server, close ws connection
|
||||||
ws.Close()
|
ws.Close()
|
||||||
time.Sleep(waitDelay)
|
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)
|
w := new(strings.Builder)
|
||||||
fmt.Fprint(w, "south north")
|
fmt.Fprint(w, "mode: {{.Mode}}\n")
|
||||||
|
|
||||||
counters, blocks := loadValues()
|
counters, blocks := loadValues()
|
||||||
var active, total int64
|
var active, total int64
|
||||||
|
@ -158,11 +158,13 @@ func injectGocAgent(where string, covers []*config.PackageCover) {
|
|||||||
GlobalCoverVarImportPath string
|
GlobalCoverVarImportPath string
|
||||||
Package string
|
Package string
|
||||||
Host string
|
Host string
|
||||||
|
Mode string
|
||||||
}{
|
}{
|
||||||
Covers: covers,
|
Covers: covers,
|
||||||
GlobalCoverVarImportPath: config.GocConfig.GlobalCoverVarImportPath,
|
GlobalCoverVarImportPath: config.GocConfig.GlobalCoverVarImportPath,
|
||||||
Package: injectPkgName,
|
Package: injectPkgName,
|
||||||
Host: config.GocConfig.Host,
|
Host: config.GocConfig.Host,
|
||||||
|
Mode: config.GocConfig.Mode,
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := coverMainTmpl.Execute(f, tmplData); err != nil {
|
if err := coverMainTmpl.Execute(f, tmplData); err != nil {
|
||||||
|
@ -2,7 +2,10 @@ package flag
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"flag"
|
"flag"
|
||||||
|
"os"
|
||||||
|
"path/filepath"
|
||||||
|
|
||||||
|
"github.com/qiniu/goc/v2/pkg/config"
|
||||||
"github.com/qiniu/goc/v2/pkg/log"
|
"github.com/qiniu/goc/v2/pkg/log"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
"github.com/spf13/pflag"
|
"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.
|
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.
|
// 吞下 [packages] 之前所有的 flags.
|
||||||
func BuildCmdArgsParse(cmd *cobra.Command, args []string) []string {
|
func BuildCmdArgsParse(cmd *cobra.Command, args []string) []string {
|
||||||
@ -52,6 +56,29 @@ func BuildCmdArgsParse(cmd *cobra.Command, args []string) []string {
|
|||||||
log.Fatalf("%v", err)
|
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()
|
return goFlagSets.Args()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ func GetPackagesDir(patterns []string) {
|
|||||||
// 获取当前 [packages] 所在的目录位置,供后续插桩使用。
|
// 获取当前 [packages] 所在的目录位置,供后续插桩使用。
|
||||||
config.GocConfig.CurPkgDir = filepath.Dir(absp)
|
config.GocConfig.CurPkgDir = filepath.Dir(absp)
|
||||||
// 获取二进制名字
|
// 获取二进制名字
|
||||||
config.GocConfig.BinaryName = filepath.Base(absp)
|
// config.GocConfig.BinaryName = filepath.Base(absp)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -51,8 +51,11 @@ func GetPackagesDir(patterns []string) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
config.GocConfig.CurPkgDir = coverWd
|
config.GocConfig.CurPkgDir = coverWd
|
||||||
config.GocConfig.BinaryName = ""
|
|
||||||
return
|
// 是否包含 ...
|
||||||
|
if strings.Contains(patterns[0], "...") {
|
||||||
|
config.GocConfig.ContainSpecialPattern = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// goFilesPackage 对一组 go 文件解析,判断是否合法
|
// goFilesPackage 对一组 go 文件解析,判断是否合法
|
||||||
@ -97,7 +100,7 @@ func goFilesPackage(gofiles []string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// getDirFromImportPaths return the import path's real directory
|
// getDirFromImportPaths return the import path's real abs directory
|
||||||
//
|
//
|
||||||
// 该函数接收到的只有 dir 或 import path,file 在上一步已被排除
|
// 该函数接收到的只有 dir 或 import path,file 在上一步已被排除
|
||||||
// 只考虑 go modules 的情况
|
// 只考虑 go modules 的情况
|
||||||
@ -134,6 +137,7 @@ func getDirFromImportPaths(patterns []string) (string, error) {
|
|||||||
case strings.Contains(pattern, "..."):
|
case strings.Contains(pattern, "..."):
|
||||||
i := strings.Index(pattern, "...")
|
i := strings.Index(pattern, "...")
|
||||||
dir, _ := filepath.Split(pattern[:i])
|
dir, _ := filepath.Split(pattern[:i])
|
||||||
|
dir, _ = filepath.Abs(dir)
|
||||||
if _, err := os.Stat(dir); err != nil {
|
if _, err := os.Stat(dir); err != nil {
|
||||||
return "", fmt.Errorf("error (%w) get directory from the import path: %v", err, pattern)
|
return "", fmt.Errorf("error (%w) get directory from the import path: %v", err, pattern)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user