From 0a5062f61ba142c30e889f88e555efa437c57c09 Mon Sep 17 00:00:00 2001 From: lyyyuna Date: Mon, 21 Feb 2022 20:15:52 +0800 Subject: [PATCH] add support for vendor project with go.mod changed --- pkg/build/build.go | 30 ++++++++++++++++++++++++++++++ pkg/build/build_flags.go | 24 +++++++++++++++++++++++- pkg/build/goenv.go | 19 +++++++++++++++++++ pkg/build/inject.go | 8 ++++++++ pkg/build/install.go | 5 +++++ pkg/build/run.go | 5 +++++ pkg/build/tmpfolder.go | 1 + 7 files changed, 91 insertions(+), 1 deletion(-) diff --git a/pkg/build/build.go b/pkg/build/build.go index 5f7a384..eece0d2 100644 --- a/pkg/build/build.go +++ b/pkg/build/build.go @@ -43,6 +43,9 @@ type Build struct { GoArgs []string // go command line args Packages []string // go command line [packages] + IsVendorMod bool // vendor, readonly, or mod? + IsModEdit bool // is mod file edited? + ImportPath string // the whole import path of the project Pkgs map[string]*Package GlobalCoverVarImportPath string @@ -86,6 +89,11 @@ func (b *Build) Build() { b.updateGoModFile() // 3. inject cover vars b.Inject() + + if b.IsVendorMod && b.IsModEdit { + b.reVendor() + } + // 4. build in the temp project b.doBuildInTemp() } @@ -107,6 +115,10 @@ func (b *Build) doBuildInTemp() { goflags = append(goflags, "-o", b.CurWd) } + if b.IsVendorMod && b.IsModEdit { + b.reVendor() + } + pacakges := b.Packages goflags = append(goflags, pacakges...) @@ -149,3 +161,21 @@ func nicePrintArgs(args []string) []string { return output } + +func (b *Build) reVendor() { + log.StartWait("re-vendoring the project") + cmd := exec.Command("go", "mod", "vendor") + cmd.Dir = b.TmpModProjectDir + cmd.Stdout = os.Stdout + cmd.Stderr = os.Stderr + + if err := cmd.Start(); err != nil { + log.Fatalf("fail to execute go vendor: %v", err) + } + if err := cmd.Wait(); err != nil { + log.Fatalf("fail to execute go vendor: %v", err) + } + + log.StopWait() + log.Donef("re-vendor the project done") +} diff --git a/pkg/build/build_flags.go b/pkg/build/build_flags.go index 5500a63..3f41940 100644 --- a/pkg/build/build_flags.go +++ b/pkg/build/build_flags.go @@ -130,7 +130,18 @@ func (b *Build) buildCmdArgsParse() { } flags = append(flags, "-o", outputDir) } else { - flags = append(flags, "-"+f.Name, f.Value.String()) + if _, ok := booleanFlags[f.Name]; !ok { + flags = append(flags, "-"+f.Name, f.Value.String()) + } else { + flags = append(flags, "-"+f.Name) + } + if f.Name == "mod" { + if f.Value.String() == "vendor" { + b.IsVendorMod = true + } else { + b.IsVendorMod = false + } + } } }) @@ -248,13 +259,18 @@ type goConfig struct { } var goflags goConfig +var booleanFlags map[string]struct{} = make(map[string]struct{}) func addBuildFlags(cmdSet *flag.FlagSet) { cmdSet.BoolVar(&goflags.BuildA, "a", false, "") + booleanFlags["a"] = struct{}{} cmdSet.BoolVar(&goflags.BuildN, "n", false, "") + booleanFlags["n"] = struct{}{} cmdSet.IntVar(&goflags.BuildP, "p", 4, "") cmdSet.BoolVar(&goflags.BuildV, "v", false, "") + booleanFlags["v"] = struct{}{} cmdSet.BoolVar(&goflags.BuildX, "x", false, "") + booleanFlags["x"] = struct{}{} cmdSet.StringVar(&goflags.BuildBuildmode, "buildmode", "default", "") cmdSet.StringVar(&goflags.BuildMod, "mod", "", "") cmdSet.StringVar(&goflags.Installsuffix, "installsuffix", "", "") @@ -266,16 +282,22 @@ func addBuildFlags(cmdSet *flag.FlagSet) { cmdSet.StringVar(&goflags.BuildGccgoflags, "gccgoflags", "", "") // mod related cmdSet.BoolVar(&goflags.ModCacheRW, "modcacherw", false, "") + booleanFlags["modcacherw"] = struct{}{} cmdSet.StringVar(&goflags.ModFile, "modfile", "", "") cmdSet.StringVar(&goflags.BuildLdflags, "ldflags", "", "") cmdSet.BoolVar(&goflags.BuildLinkshared, "linkshared", false, "") + booleanFlags["linkshared"] = struct{}{} cmdSet.StringVar(&goflags.BuildPkgdir, "pkgdir", "", "") cmdSet.BoolVar(&goflags.BuildRace, "race", false, "") + booleanFlags["race"] = struct{}{} cmdSet.BoolVar(&goflags.BuildMSan, "msan", false, "") + booleanFlags["msan"] = struct{}{} cmdSet.StringVar(&goflags.BuildTags, "tags", "", "") cmdSet.StringVar(&goflags.BuildToolexec, "toolexec", "", "") cmdSet.BoolVar(&goflags.BuildTrimpath, "trimpath", false, "") + booleanFlags["trimpath"] = struct{}{} cmdSet.BoolVar(&goflags.BuildWork, "work", false, "") + booleanFlags["work"] = struct{}{} } func addOutputFlags(cmdSet *flag.FlagSet) { diff --git a/pkg/build/goenv.go b/pkg/build/goenv.go index 0b8c078..8ad16a3 100644 --- a/pkg/build/goenv.go +++ b/pkg/build/goenv.go @@ -54,6 +54,9 @@ func (b *Build) readProjectMetaInfo() { b.Pkgs = pkgs } + // check if project is in vendor mod + b.checkIfVendorMod() + // get tmp folder name b.TmpModProjectDir = filepath.Join(os.TempDir(), TmpFolderName(b.CurModProjectDir)) // get working dir in the corresponding tmp dir @@ -69,6 +72,9 @@ func (b *Build) displayProjectMetaInfo() { log.Infof("GOBIN: %v", b.GOBIN) log.Infof("Project Directory: %v", b.CurModProjectDir) log.Infof("Temporary Project Directory: %v", b.TmpModProjectDir) + if b.IsVendorMod { + log.Infof("Project in vendor mod") + } log.Infof("") } @@ -132,3 +138,16 @@ func (b *Build) listPackages(dir string) map[string]*Package { return pkgs } + +func (b *Build) checkIfVendorMod() { + if b.IsVendorMod == true { + return + } + + vendorDir := filepath.Join(b.CurModProjectDir, "vendor") + if _, err := os.Stat(vendorDir); err != nil { + b.IsVendorMod = false + } + + b.IsVendorMod = true +} diff --git a/pkg/build/inject.go b/pkg/build/inject.go index b404eae..8c00b30 100644 --- a/pkg/build/inject.go +++ b/pkg/build/inject.go @@ -139,6 +139,14 @@ func (b *Build) getPkgTmpDir(pkgDir string) string { // 11111_22222_bridge.go 仅仅用于引用 11111_22222_package, where package contains ws agent main logic. // 使用 bridge.go 文件是为了避免插桩逻辑中的变量名污染 main 包 func (b *Build) injectGocAgent(where string, covers []*PackageCover) { + if len(covers) == 0 { + return + } + + if len(covers[0].Vars) == 0 { + return + } + injectPkgName := "goc-cover-agent-apis-auto-generated-11111-22222-package" injectBridgeName := "goc-cover-agent-apis-auto-generated-11111-22222-bridge.go" wherePkg := filepath.Join(where, injectPkgName) diff --git a/pkg/build/install.go b/pkg/build/install.go index 4648503..9a81729 100644 --- a/pkg/build/install.go +++ b/pkg/build/install.go @@ -40,6 +40,11 @@ func (b *Build) Install() { b.updateGoModFile() // 3. inject cover vars b.Inject() + + if b.IsVendorMod && b.IsModEdit { + b.reVendor() + } + // 4. install in the temp project b.doInstallInTemp() } diff --git a/pkg/build/run.go b/pkg/build/run.go index a29763d..7bcf898 100644 --- a/pkg/build/run.go +++ b/pkg/build/run.go @@ -59,6 +59,11 @@ func (b *Build) Run() { b.updateGoModFile() // 3. inject cover vars b.Inject() + + if b.IsVendorMod && b.IsModEdit { + b.reVendor() + } + // 4. run in the temp project go func() { ch := make(chan os.Signal, 1) diff --git a/pkg/build/tmpfolder.go b/pkg/build/tmpfolder.go index 4ab164f..4f4d137 100644 --- a/pkg/build/tmpfolder.go +++ b/pkg/build/tmpfolder.go @@ -145,6 +145,7 @@ func (b *Build) updateGoModFile() (updateFlag bool, newModFile []byte) { if err != nil { log.Fatalf("fail to update go.mod: %v", err) } + b.IsModEdit = true } return }