diff --git a/cmd/build.go b/cmd/build.go index 360f5bf..076c2a5 100644 --- a/cmd/build.go +++ b/cmd/build.go @@ -17,14 +17,6 @@ package cmd import ( - "flag" - "fmt" - "log" - "os" - "os/exec" - "path/filepath" - "strings" - "github.com/qiniu/goc/pkg/build" "github.com/spf13/cobra" ) @@ -51,69 +43,22 @@ goc build -- -o /to/this/path goc build -- -ldflags "-extldflags -static" -tags="embed kodo" `, Run: func(cmd *cobra.Command, args []string) { - newgopath, newwd, tmpdir, pkgs := build.MvProjectsToTmp(target, args) - doCover(cmd, args, newgopath, tmpdir) - newArgs, modified := modifyOutputArg(args) - doBuild(newArgs, newgopath, newwd) - - // if not modified - // find the binary in temp build dir - // and copy them into original dir - if false == modified { - build.MvBinaryToOri(pkgs, tmpdir) - } + gocbuild := build.NewBuild(buildFlags, packages, buildOutput) + // remove temporary directory if needed + defer gocbuild.RemoveTmpDir() + // doCover with original buildFlags, with new GOPATH( tmp:original ) + // in the tmp directory + doCover(buildFlags, gocbuild.NewGOPATH, gocbuild.TmpDir) + // do install in the temporary directory + gocbuild.Build() + return }, } -func init() { - buildCmd.Flags().StringVarP(¢er, "center", "", "http://127.0.0.1:7777", "cover profile host center") +var buildOutput string +func init() { + addBuildFlags(buildCmd.Flags()) + buildCmd.Flags().StringVar(&buildOutput, "output", "", "it forces build to write the resulting executable or object to the named output file or directory") rootCmd.AddCommand(buildCmd) } - -func doBuild(args []string, newgopath string, newworkingdir string) { - log.Println("Go building in temp...") - newArgs := []string{"build"} - newArgs = append(newArgs, args...) - cmd := exec.Command("go", newArgs...) - cmd.Dir = newworkingdir - - if newgopath != "" { - // Change to temp GOPATH for go install command - cmd.Env = append(os.Environ(), fmt.Sprintf("GOPATH=%v", newgopath)) - } - - out, err := cmd.CombinedOutput() - if err != nil { - log.Fatalf("Fail to execute: go build %v. The error is: %v, the stdout/stderr is: %v", strings.Join(args, " "), err, string(out)) - } - log.Println("Go build exit successful.") -} - -// As we build in the temp build dir, we have to modify the "-o output", -// if output is a relative path, transform it to abspath -func modifyOutputArg(args []string) (newArgs []string, modified bool) { - var output string - fs := flag.NewFlagSet("goc-build", flag.PanicOnError) - fs.StringVar(&output, "o", "", "output dir") - - // parse the go args after "--" - fs.Parse(args) - - // skip if output is not present - if output == "" { - modified = false - newArgs = args - return - } - - abs, err := filepath.Abs(output) - if err != nil { - log.Fatalf("Fail to transform the path: %v to absolute path, the error is: %v", output, err) - } - - // the second -o arg will overwrite the first one - newArgs = append(args, "-o", abs) - modified = true - return -} diff --git a/cmd/clear.go b/cmd/clear.go index 10dba7d..8e1bc93 100644 --- a/cmd/clear.go +++ b/cmd/clear.go @@ -18,7 +18,7 @@ package cmd import ( "fmt" - "log" + log "github.com/sirupsen/logrus" "os" "github.com/qiniu/goc/pkg/cover" @@ -46,6 +46,6 @@ goc clear --center=http://192.168.1.1:8080 } func init() { - clearCmd.Flags().StringVarP(¢er, "center", "", "http://127.0.0.1:7777", "cover profile host center") + addBasicFlags(clearCmd.Flags()) rootCmd.AddCommand(clearCmd) } diff --git a/cmd/commonflags.go b/cmd/commonflags.go new file mode 100644 index 0000000..1371929 --- /dev/null +++ b/cmd/commonflags.go @@ -0,0 +1,46 @@ +package cmd + +import ( + "github.com/spf13/pflag" + "github.com/spf13/viper" +) + +var ( + target string + center string + mode string + debugGoc bool + buildFlags string + packages string + appArgs string +) + +// addBasicFlags adds a +func addBasicFlags(cmdset *pflag.FlagSet) { + cmdset.StringVar(¢er, "center", "http://127.0.0.1:7777", "cover profile host center") + // bind to viper + viper.BindPFlags(cmdset) +} + +func addCommonFlags(cmdset *pflag.FlagSet) { + addBasicFlags(cmdset) + cmdset.StringVar(&mode, "mode", "count", "coverage mode: set, count, atomic") + cmdset.StringVar(&buildFlags, "buildflags", "", "specify the build flags") + // bind to viper + viper.BindPFlags(cmdset) +} + +func addBuildFlags(cmdset *pflag.FlagSet) { + addCommonFlags(cmdset) + cmdset.StringVar(&packages, "packages", ".", "specify the package name, only . and ./... are supported") + // bind to viper + viper.BindPFlags(cmdset) +} + +func addRunFlags(cmdset *pflag.FlagSet) { + addBuildFlags(cmdset) + cmdset.Lookup("packages").Usage = "specify the package name, only ., ./... and *.go are supported" + cmdset.StringVar(&appArgs, "appargs", "", "specify the application's arguments") + // bind to viper + viper.BindPFlags(cmdset) +} diff --git a/cmd/cover.go b/cmd/cover.go index 94d992b..fef9874 100644 --- a/cmd/cover.go +++ b/cmd/cover.go @@ -18,7 +18,8 @@ package cmd import ( "fmt" - "log" + log "github.com/sirupsen/logrus" + "github.com/spf13/viper" "os" "strings" @@ -40,7 +41,10 @@ goc cover --center=http://127.0.0.1:7777 # Do cover for the target path, cover mode: atomic. goc cover --center=http://127.0.0.1:7777 --target=/path/to/target --mode=atomic `, + Hidden: true, Run: func(cmd *cobra.Command, args []string) { + var buildFlags string + buildFlags = viper.GetString("buildflags") if mode == "" { log.Fatalf("Error: flag needs an argument: -mode %v", mode) } @@ -48,39 +52,27 @@ goc cover --center=http://127.0.0.1:7777 --target=/path/to/target --mode=atomic log.Fatalf("unknown -mode %v", mode) } - doCover(cmd, args, "", "") + doCover(buildFlags, "", target) }, } -var ( - target string - center string - mode string -) - func init() { - coverCmd.Flags().StringVarP(¢er, "center", "", "http://127.0.0.1:7777", "cover profile host center") - coverCmd.Flags().StringVarP(&target, "target", "", ".", "target folder to cover") - coverCmd.Flags().StringVarP(&mode, "mode", "", "count", "coverage mode: set, count, atomic") - + coverCmd.Flags().StringVar(&target, "target", ".", "target folder to cover") + addCommonFlags(coverCmd.Flags()) rootCmd.AddCommand(coverCmd) - log.SetFlags(log.LstdFlags | log.Lshortfile) } -func doCover(cmd *cobra.Command, args []string, newgopath string, newtarget string) { - if newtarget != "" { - target = newtarget - } +func doCover(args string, newgopath string, target string) { if !isDirExist(target) { log.Fatalf("target directory %s not exist", target) } - listArgs := []string{"list", "-json"} + listArgs := []string{"-json"} if len(args) != 0 { - listArgs = append(listArgs, args...) + listArgs = append(listArgs, args) } listArgs = append(listArgs, "./...") - pkgs := cover.ListPackages(target, listArgs, newgopath) + pkgs := cover.ListPackages(target, strings.Join(listArgs, " "), newgopath) var seen = make(map[string]*cover.PackageCover) var seenCache = make(map[string]*cover.PackageCover) diff --git a/cmd/init.go b/cmd/init.go index b258737..cd7e0f0 100644 --- a/cmd/init.go +++ b/cmd/init.go @@ -17,7 +17,7 @@ package cmd import ( - "log" + log "github.com/sirupsen/logrus" "github.com/qiniu/goc/pkg/cover" "github.com/spf13/cobra" @@ -34,6 +34,6 @@ var initCmd = &cobra.Command{ } func init() { - initCmd.Flags().StringVarP(¢er, "center", "", "http://127.0.0.1:7777", "cover profile host center") + addBasicFlags(initCmd.Flags()) rootCmd.AddCommand(initCmd) } diff --git a/cmd/install.go b/cmd/install.go index bacd3c5..d30d0a7 100644 --- a/cmd/install.go +++ b/cmd/install.go @@ -17,14 +17,7 @@ package cmd import ( - "fmt" - "log" - "os" - "os/exec" - "strings" - "github.com/qiniu/goc/pkg/build" - "github.com/qiniu/goc/pkg/cover" "github.com/spf13/cobra" ) @@ -38,44 +31,27 @@ To pass origial go build flags to goc command, place them after "--", see exampl `, Example: ` # Install all binaries with cover variables injected. The binary will be installed in $GOPATH/bin or $HOME/go/bin if directory existed. -goc install -- ./... +goc install --packages="./..." # Install the current binary with cover variables injected, and set the registry center to http://127.0.0.1:7777. goc install --center=http://127.0.0.1:7777 # Install the current binary with cover variables injected, and set necessary build flags: -ldflags "-extldflags -static" -tags="embed kodo". -goc build -- -ldflags "-extldflags -static" -tags="embed kodo" +goc build --buildflags="-ldflags '-extldflags -static' -tags='embed kodo'" `, Run: func(cmd *cobra.Command, args []string) { - newgopath, newwd, tmpdir, pkgs := build.MvProjectsToTmp(target, args) - doCover(cmd, args, newgopath, tmpdir) - doInstall(args, newgopath, newwd, pkgs) + gocbuild := build.NewInstall(buildFlags, packages) + // remove temporary directory if needed + defer gocbuild.RemoveTmpDir() + // doCover with original buildFlags, with new GOPATH( tmp:original ) + // in the tmp directory + doCover(buildFlags, gocbuild.NewGOPATH, gocbuild.TmpDir) + // do install in the temporary directory + gocbuild.Install() }, } func init() { - installCmd.Flags().StringVarP(¢er, "center", "", "http://127.0.0.1:7777", "cover profile host center") - + addBuildFlags(installCmd.Flags()) rootCmd.AddCommand(installCmd) } - -func doInstall(args []string, newgopath string, newworkingdir string, pkgs map[string]*cover.Package) { - log.Println("Go building in temp...") - newArgs := []string{"install"} - newArgs = append(newArgs, args...) - cmd := exec.Command("go", newArgs...) - cmd.Dir = newworkingdir - - // Change the temp GOBIN, to force binary install to original place - cmd.Env = append(os.Environ(), fmt.Sprintf("GOBIN=%v", build.FindWhereToInstall(pkgs))) - if newgopath != "" { - // Change to temp GOPATH for go install command - cmd.Env = append(cmd.Env, fmt.Sprintf("GOPATH=%v", newgopath)) - } - - out, err := cmd.CombinedOutput() - if err != nil { - log.Fatalf("Fail to execute: go install %v. The error is: %v, the stdout/stderr is: %v", strings.Join(args, " "), err, string(out)) - } - log.Printf("Go install successful. Binary installed in: %v", build.FindWhereToInstall(pkgs)) -} diff --git a/cmd/profile.go b/cmd/profile.go index d130abc..c1d0918 100644 --- a/cmd/profile.go +++ b/cmd/profile.go @@ -19,8 +19,8 @@ package cmd import ( "bytes" "fmt" + log "github.com/sirupsen/logrus" "io" - "log" "os" "github.com/qiniu/goc/pkg/cover" @@ -70,6 +70,6 @@ var output string func init() { profileCmd.Flags().StringVarP(&output, "output", "o", "", "download cover profile") - profileCmd.Flags().StringVarP(¢er, "center", "", "http://127.0.0.1:7777", "cover profile host center") + addBasicFlags(profileCmd.Flags()) rootCmd.AddCommand(profileCmd) } diff --git a/cmd/root.go b/cmd/root.go index 37fcc98..3974e4c 100644 --- a/cmd/root.go +++ b/cmd/root.go @@ -17,9 +17,13 @@ package cmd import ( - "log" - + log "github.com/sirupsen/logrus" "github.com/spf13/cobra" + "github.com/spf13/viper" + "io/ioutil" + "path/filepath" + "runtime" + "strconv" ) var rootCmd = &cobra.Command{ @@ -28,8 +32,31 @@ var rootCmd = &cobra.Command{ Long: `goc is a comprehensive coverage testing tool for go language. Find more information at: - https://github.com/qbox/goc + https://github.com/qiniu/goc `, + PersistentPreRun: func(cmd *cobra.Command, args []string) { + log.SetReportCaller(true) + log.SetFormatter(&log.TextFormatter{ + FullTimestamp: true, + CallerPrettyfier: func(f *runtime.Frame) (string, string) { + dirname, filename := filepath.Split(f.File) + lastelem := filepath.Base(dirname) + filename = filepath.Join(lastelem, filename) + line := strconv.Itoa(f.Line) + return "", "[" + filename + ":" + line + "]" + }, + }) + if debugGoc == false { + // we only need log in debug mode + log.SetOutput(ioutil.Discard) + } + }, +} + +func init() { + rootCmd.PersistentFlags().BoolVar(&debugGoc, "debuggoc", false, "turn goc into debug mode") + rootCmd.PersistentFlags().MarkHidden("debuggoc") + viper.BindPFlags(rootCmd.PersistentFlags()) } // Execute the goc tool diff --git a/go.mod b/go.mod index 79e1eca..b6fec6a 100644 --- a/go.mod +++ b/go.mod @@ -14,8 +14,10 @@ require ( github.com/onsi/gomega v1.8.1 github.com/otiai10/copy v1.0.2 github.com/qiniu/api.v7/v7 v7.5.0 - github.com/sirupsen/logrus v1.4.2 + github.com/sirupsen/logrus v1.6.0 github.com/spf13/cobra v1.0.0 + github.com/spf13/pflag v1.0.5 + github.com/spf13/viper v1.6.2 github.com/stretchr/testify v1.5.1 golang.org/x/net v0.0.0-20200301022130-244492dfa37a golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d diff --git a/go.sum b/go.sum index c1b07ba..23b3c55 100644 --- a/go.sum +++ b/go.sum @@ -410,6 +410,7 @@ github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8= github.com/hashicorp/golang-lru v0.5.3/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= github.com/hashicorp/golang-lru v0.5.4/go.mod h1:iADmTwqILo4mZ8BN3D2Q6+9jd8WM5uGBxy+E8yxSoD4= +github.com/hashicorp/hcl v1.0.0 h1:0Anlzjpi4vEasTeNFn2mLJgTSwt0+6sfsiTG8qcWGx4= github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T20WEQ= github.com/hpcloud/tail v1.0.0 h1:nfCOvKYfkgYP8hkirhJocXT2+zOD8yUNjXaWfTlyFKI= github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU= @@ -460,6 +461,7 @@ github.com/klauspost/pgzip v1.2.1/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQ github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/konsorten/go-windows-terminal-sequences v1.0.2 h1:DB17ag19krx9CFsz4o3enTrPXyIXCl+2iCXH/aMAp9s= github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= +github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ= github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pretty v0.2.0 h1:s5hAObm+yFO5uHYt5dYjxi2rXrsnmRpJx4OYvIWUaQs= @@ -512,6 +514,7 @@ github.com/mitchellh/copystructure v1.0.0/go.mod h1:SNtv71yrdKgLRyLFxmLdkAbkKEFW github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo= github.com/mitchellh/ioprogress v0.0.0-20180201004757-6a23b12fa88e/go.mod h1:waEya8ee1Ro/lgxpVhkJI4BVASzkm3UZqkx/cFJiYHM= +github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE= github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y= github.com/mitchellh/osext v0.0.0-20151018003038-5e2d6d41470f/go.mod h1:OkQIRizQZAeMln+1tSwduZz7+Af5oFlKirV/MSYes2A= github.com/mitchellh/reflectwalk v1.0.0/go.mod h1:mSTlrgnPZtwu0c4WaC2kGObEpuNDbx0jmZXqmk4esnw= @@ -576,6 +579,7 @@ github.com/otiai10/mint v1.3.0/go.mod h1:F5AjcsTsWUqX+Na9fpHb52P8pcRX2CI6A3ctIT9 github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= github.com/pelletier/go-buffruneio v0.2.0/go.mod h1:JkE26KsDizTr40EUHkXVtNPvgGtbSNq5BcowyYOWdKo= github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= +github.com/pelletier/go-toml v1.6.0 h1:aetoXYr0Tv7xRU/V4B4IZJ2QcbtMUFoNb3ORp7TzIK4= github.com/pelletier/go-toml v1.6.0/go.mod h1:5N711Q9dKgbdkxHL+MEfF31hpT7l0S0s/t2kKREewys= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= @@ -649,6 +653,8 @@ github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPx github.com/sirupsen/logrus v1.4.1/go.mod h1:ni0Sbl8bgC9z8RoU9G6nDWqqs/fq4eDPysMBDgk/93Q= github.com/sirupsen/logrus v1.4.2 h1:SPIRibHv4MatM3XXNO2BJeFLZwZ2LvZgfQ5+UNI2im4= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= +github.com/sirupsen/logrus v1.6.0 h1:UBcNElsrwanuuMsnGSlYmtmgbb23qDR5dG+6X6Oo89I= +github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v0.0.0-20190330032615-68dc04aab96a/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= github.com/smartystreets/goconvey v0.0.0-20190731233626-505e41936337/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= @@ -656,8 +662,10 @@ github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9 github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= +github.com/spf13/afero v1.2.2 h1:5jhuqJyZCZf2JRofRvN/nIFgIWNzPa3/Vz8mYylgbWc= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cast v1.3.1 h1:nFm6S0SMdyzrzcmThSipiEubIDy8WEXKNZ0UOgiRpng= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cobra v0.0.2-0.20171109065643-2da4a54c5cee/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ= @@ -666,6 +674,7 @@ github.com/spf13/cobra v0.0.6/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHN github.com/spf13/cobra v1.0.0 h1:6m/oheQuQ13N9ks4hubMG6BnvwOeaJrqSPLahSnczz8= github.com/spf13/cobra v1.0.0/go.mod h1:/6GTrnGXV9HjY+aR4k0oJ5tcvakLuG6EuKReYlHNrgE= github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= +github.com/spf13/jwalterweatherman v1.1.0 h1:ue6voC5bR5F8YxI5S67j9i582FU4Qvo2bmqnqMYADFk= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.1-0.20171106142849-4c012f6dcd95/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= @@ -676,6 +685,7 @@ github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/yZzE= +github.com/spf13/viper v1.6.2 h1:7aKfF+e8/k68gda3LOjo5RxiUqddoFxVq4BKBPrxk5E= github.com/spf13/viper v1.6.2/go.mod h1:t3iDnF5Jlj76alVNuyFBk5oUMCvsrkbvZK0WQdfDi5k= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/streadway/amqp v0.0.0-20190404075320-75d898a42a94/go.mod h1:AZpEONHx3DKn8O/DFsRAY58/XVQiIPMTMB1SddzLXVw= @@ -688,6 +698,7 @@ github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UV github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81PSLYec5m4= github.com/stretchr/testify v1.5.1 h1:nOGnQDM7FYENwehXlg/kFVnos3rEvtKTjRvOWSzb6H4= github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5cxcmMvtA= +github.com/subosito/gotenv v1.2.0 h1:Slr1R9HxAlEKefgq5jn9U+DnETlIUa6HfgEzj0g5d7s= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= github.com/syndtr/gocapability v0.0.0-20170704070218-db04d3cc01c8/go.mod h1:hkRG7XYTFWNJGYcbNJQlaLq0fg1yr4J4t/NcTQtrfww= github.com/tektoncd/pipeline v0.11.0/go.mod h1:hlkH32S92+/UODROH0dmxzyuMxfRFp/Nc3e29MewLn8= @@ -1009,6 +1020,7 @@ gopkg.in/inf.v0 v0.9.0/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= gopkg.in/ini.v1 v1.46.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= +gopkg.in/ini.v1 v1.52.0 h1:j+Lt/M1oPPejkniCg1TkWE2J3Eh1oZTsHSXzMTzUXn4= gopkg.in/ini.v1 v1.52.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/jcmturner/aescts.v1 v1.0.1/go.mod h1:nsR8qBOg+OucoIW+WMhB3GspUQXq9XorLnQb9XtvcOo= gopkg.in/jcmturner/dnsutils.v1 v1.0.1/go.mod h1:m3v+5svpVOhtFAP/wSz+yzh4Mc0Fg7eRhxkJMWSIz9Q= diff --git a/pkg/build/binarymove.go b/pkg/build/binarymove.go deleted file mode 100644 index b638bd5..0000000 --- a/pkg/build/binarymove.go +++ /dev/null @@ -1,77 +0,0 @@ -/* - Copyright 2020 Qiniu Cloud (qiniu.com) - - Licensed under the Apache License, Version 2.0 (the "License"); - you may not use this file except in compliance with the License. - You may obtain a copy of the License at - - http://www.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, software - distributed under the License is distributed on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. - See the License for the specific language governing permissions and - limitations under the License. -*/ - -package build - -import ( - "log" - "os" - "path/filepath" - - "github.com/otiai10/copy" - "github.com/qiniu/goc/pkg/cover" -) - -func MvBinaryToOri(pkgs map[string]*cover.Package, newgopath string) { - for _, pkg := range pkgs { - if pkg.Name == "main" { - _, binaryTarget := filepath.Split(pkg.Target) - - binaryTmpPath := filepath.Join(getTmpwd(newgopath, pkgs, !checkIfLegacyProject(pkgs)), binaryTarget) - - if false == checkIfFileExist(binaryTmpPath) { - continue - } - - curwd, err := os.Getwd() - if err != nil { - log.Fatalf("Cannot get current working directoy, the error is: %v", err) - } - binaryOriPath := filepath.Join(curwd, binaryTarget) - - if checkIfFileExist(binaryOriPath) { - // if we have file in the original place with same name, - // but this file is not a binary, - // then we skip it - if false == checkIfExecutable(binaryOriPath) { - log.Printf("Skipping binary: %v, as we find a file in the original place with same name but not executable.", binaryOriPath) - continue - } - } - - log.Printf("Generating binary: %v", binaryOriPath) - if err = copy.Copy(binaryTmpPath, binaryOriPath); err != nil { - log.Println(err) - } - } - } -} - -func checkIfExecutable(path string) bool { - fileInfo, err := os.Lstat(path) - if err != nil { - return false - } - return fileInfo.Mode()&0100 != 0 -} - -func checkIfFileExist(path string) bool { - fileInfo, err := os.Stat(path) - if os.IsNotExist(err) { - return false - } - return !fileInfo.IsDir() -} diff --git a/pkg/build/build.go b/pkg/build/build.go new file mode 100644 index 0000000..d40ea88 --- /dev/null +++ b/pkg/build/build.go @@ -0,0 +1,114 @@ +/* + Copyright 2020 Qiniu Cloud (qiniu.com) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package build + +import ( + "fmt" + "os" + "os/exec" + "path/filepath" + "strings" + + "github.com/qiniu/goc/pkg/cover" + log "github.com/sirupsen/logrus" +) + +// Build is to describe the building/installing process of a goc build/install +type Build struct { + Pkgs map[string]*cover.Package // Pkg list parsed from "go list -json ./..." command + NewGOPATH string // the new GOPATH + OriGOPATH string // the original GOPATH + TmpDir string // the temporary directory to build the project + TmpWorkingDir string // the working directory in the temporary directory, which is corresponding to the current directory in the project directory + IsMod bool // determine whether it is a Mod project + BuildFlags string // Build flags + Packages string // Packages that needs to build + Root string // Project Root + Target string // the binary name that go build generate +} + +// NewBuild creates a Build struct which can build from goc temporary directory, +// and generate binary in current working directory +func NewBuild(buildflags string, packages string, outputDir string) *Build { + // buildflags = buildflags + " -o " + outputDir + b := &Build{ + BuildFlags: buildflags, + Packages: packages, + } + if false == b.validatePackageForBuild() { + log.Fatalln("packages only support \".\"") + } + b.MvProjectsToTmp() + b.Target = b.determineOutputDir(outputDir) + return b +} + +func (b *Build) Build() { + log.Infoln("Go building in temp...") + // new -o will overwrite previous ones + b.BuildFlags = b.BuildFlags + " -o " + b.Target + cmd := exec.Command("/bin/bash", "-c", "go build "+b.BuildFlags+" "+b.Packages) + cmd.Dir = b.TmpWorkingDir + + if b.NewGOPATH != "" { + // Change to temp GOPATH for go install command + cmd.Env = append(os.Environ(), fmt.Sprintf("GOPATH=%v", b.NewGOPATH)) + } + + log.Printf("go build cmd is: %v", cmd.Args) + out, err := cmd.CombinedOutput() + if err != nil { + log.Fatalf("Fail to execute: %v. The error is: %v, the stdout/stderr is: %v", cmd.Args, err, string(out)) + } + log.Println("Go build exit successful.") +} + +// determineOutputDir, as we only allow . as package name, +// the binary name is always same as the directory name of current directory +func (b *Build) determineOutputDir(outputDir string) string { + if b.TmpDir == "" { + log.Fatalln("Can only be called after Build.MvProjectsToTmp().") + } + curWorkingDir, err := os.Getwd() + if err != nil { + log.Fatalf("Cannot get current working directory, the err: %v.", err) + } + // if + if outputDir == "" { + _, last := filepath.Split(curWorkingDir) + if b.IsMod { + // in mod, special rule + // replace "_" with "-" in the import path + last = strings.ReplaceAll(last, "_", "-") + } + return filepath.Join(curWorkingDir, last) + } + abs, err := filepath.Abs(outputDir) + if err != nil { + log.Fatalf("Fail to transform the path: %v to absolute path, the error is: %v", outputDir, err) + } + return abs +} + +// validatePackageForBuild only allow . as package name +func (b *Build) validatePackageForBuild() bool { + if b.Packages == "." { + return true + } else { + return false + } +} diff --git a/pkg/build/gomodules.go b/pkg/build/gomodules.go index e136250..f593c8d 100644 --- a/pkg/build/gomodules.go +++ b/pkg/build/gomodules.go @@ -17,16 +17,15 @@ package build import ( - "log" + log "github.com/sirupsen/logrus" "github.com/otiai10/copy" - "github.com/qiniu/goc/pkg/cover" ) -func cpGoModulesProject(tmpBuildDir string, pkgs map[string]*cover.Package) { - for _, v := range pkgs { +func (b *Build) cpGoModulesProject() { + for _, v := range b.Pkgs { if v.Name == "main" { - dst := tmpBuildDir + dst := b.TmpDir src := v.Module.Dir if err := copy.Copy(src, dst); err != nil { diff --git a/pkg/build/install.go b/pkg/build/install.go new file mode 100644 index 0000000..cb11720 --- /dev/null +++ b/pkg/build/install.go @@ -0,0 +1,65 @@ +/* + Copyright 2020 Qiniu Cloud (qiniu.com) + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package build + +import ( + "fmt" + log "github.com/sirupsen/logrus" + "os" + "os/exec" +) + +// NewInstall creates a Build struct which can install from goc temporary directory +func NewInstall(buildflags string, packages string) *Build { + b := &Build{ + BuildFlags: buildflags, + Packages: packages, + } + if false == b.validatePackageForInstall() { + log.Fatalln("packages only support . and ./...") + } + b.MvProjectsToTmp() + return b +} + +func (b *Build) Install() { + log.Println("Go building in temp...") + cmd := exec.Command("/bin/bash", "-c", "go install "+b.BuildFlags+" "+b.Packages) + cmd.Dir = b.TmpWorkingDir + + // Change the temp GOBIN, to force binary install to original place + cmd.Env = append(os.Environ(), fmt.Sprintf("GOBIN=%v", b.findWhereToInstall())) + if b.NewGOPATH != "" { + // Change to temp GOPATH for go install command + cmd.Env = append(cmd.Env, fmt.Sprintf("GOPATH=%v", b.NewGOPATH)) + } + + log.Printf("go install cmd is: %v", cmd.Args) + out, err := cmd.CombinedOutput() + if err != nil { + log.Fatalf("Fail to execute: %v. The error is: %v, the stdout/stderr is: %v", cmd.Args, err, string(out)) + } + log.Printf("Go install successful. Binary installed in: %v", b.findWhereToInstall()) +} + +func (b *Build) validatePackageForInstall() bool { + if b.Packages == "." || b.Packages == "./..." { + return true + } else { + return false + } +} diff --git a/pkg/build/legacy.go b/pkg/build/legacy.go index cc40e84..ed6244a 100644 --- a/pkg/build/legacy.go +++ b/pkg/build/legacy.go @@ -17,7 +17,7 @@ package build import ( - "log" + log "github.com/sirupsen/logrus" "os" "path/filepath" @@ -25,10 +25,10 @@ import ( "github.com/qiniu/goc/pkg/cover" ) -func cpLegacyProject(tmpBuildDir string, pkgs map[string]*cover.Package) { +func (b *Build) cpLegacyProject() { visited := make(map[string]bool) - for k, v := range pkgs { - dst := filepath.Join(tmpBuildDir, "src", k) + for k, v := range b.Pkgs { + dst := filepath.Join(b.TmpDir, "src", k) src := v.Dir if _, ok := visited[src]; ok { @@ -42,13 +42,13 @@ func cpLegacyProject(tmpBuildDir string, pkgs map[string]*cover.Package) { visited[src] = true - cpDepPackages(tmpBuildDir, v, visited) + b.cpDepPackages(v, visited) } } // only cp dependency in root(current gopath), // skip deps in other GOPATHs -func cpDepPackages(tmpBuildDir string, pkg *cover.Package, visited map[string]bool) { +func (b *Build) cpDepPackages(pkg *cover.Package, visited map[string]bool) { /* oriGOPATH := os.Getenv("GOPATH") if oriGOPATH == "" { @@ -70,7 +70,7 @@ func cpDepPackages(tmpBuildDir string, pkg *cover.Package, visited map[string]bo continue } - dst := filepath.Join(tmpBuildDir, "src", dep) + dst := filepath.Join(b.TmpDir, "src", dep) if err := copy.Copy(src, dst); err != nil { log.Printf("Failed to Copy the folder from %v to %v, the error is: %v ", src, dst, err) diff --git a/pkg/build/tmpfolder.go b/pkg/build/tmpfolder.go index 078fd78..b4b5a6a 100644 --- a/pkg/build/tmpfolder.go +++ b/pkg/build/tmpfolder.go @@ -19,7 +19,8 @@ package build import ( "crypto/sha256" "fmt" - "log" + log "github.com/sirupsen/logrus" + "github.com/spf13/viper" "os" "path/filepath" "strings" @@ -27,56 +28,58 @@ import ( "github.com/qiniu/goc/pkg/cover" ) -func MvProjectsToTmp(target string, args []string) (newGopath string, newWorkingDir string, tmpBuildDir string, pkgs map[string]*cover.Package) { - listArgs := []string{"list", "-json"} - if len(args) != 0 { - listArgs = append(listArgs, args...) +func (b *Build) MvProjectsToTmp() { + listArgs := []string{"-json"} + if len(b.BuildFlags) != 0 { + listArgs = append(listArgs, b.BuildFlags) } listArgs = append(listArgs, "./...") - pkgs = cover.ListPackages(target, listArgs, "") + b.Pkgs = cover.ListPackages(".", strings.Join(listArgs, " "), "") - tmpBuildDir, newWorkingDir, isMod := mvProjectsToTmp(pkgs) - oriGopath := os.Getenv("GOPATH") - if isMod == true { - newGopath = "" - } else if oriGopath == "" { - newGopath = tmpBuildDir + b.mvProjectsToTmp() + b.OriGOPATH = os.Getenv("GOPATH") + if b.IsMod == true { + b.NewGOPATH = "" + } else if b.OriGOPATH == "" { + b.NewGOPATH = b.TmpDir } else { - newGopath = fmt.Sprintf("%v:%v", tmpBuildDir, oriGopath) + b.NewGOPATH = fmt.Sprintf("%v:%v", b.TmpDir, b.OriGOPATH) } - log.Printf("New GOPATH: %v", newGopath) + // fix #14: unable to build project not in GOPATH in legacy mode + // this kind of project does not have a pkg.Root value + if b.Root == "" { + b.NewGOPATH = b.OriGOPATH + } + log.Printf("New GOPATH: %v", b.NewGOPATH) return } -func mvProjectsToTmp(pkgs map[string]*cover.Package) (string, string, bool) { +func (b *Build) mvProjectsToTmp() { path, err := os.Getwd() if err != nil { log.Fatalf("Cannot get current working directoy, the error is: %v", err) } - tmpBuildDir := filepath.Join(os.TempDir(), TmpFolderName(path)) + b.TmpDir = filepath.Join(os.TempDir(), TmpFolderName(path)) // Delete previous tmp folder and its content - os.RemoveAll(tmpBuildDir) + os.RemoveAll(b.TmpDir) // Create a new tmp folder - err = os.MkdirAll(filepath.Join(tmpBuildDir, "src"), os.ModePerm) + err = os.MkdirAll(filepath.Join(b.TmpDir, "src"), os.ModePerm) if err != nil { log.Fatalf("Fail to create the temporary build directory. The err is: %v", err) } - log.Printf("Temp project generated in: %v", tmpBuildDir) + log.Printf("Tmp project generated in: %v", b.TmpDir) - isMod := false - var tmpWorkingDir string - if checkIfLegacyProject(pkgs) { - cpLegacyProject(tmpBuildDir, pkgs) - tmpWorkingDir = getTmpwd(tmpBuildDir, pkgs, false) + // set Build.IsMod flag, so we dont have to call checkIfLegacyProject another time + if b.checkIfLegacyProject() { + b.cpLegacyProject() } else { - cpGoModulesProject(tmpBuildDir, pkgs) - tmpWorkingDir = getTmpwd(tmpBuildDir, pkgs, true) - isMod = true + b.IsMod = true + b.cpGoModulesProject() } + b.getTmpwd() - log.Printf("New working/building directory in: %v", tmpWorkingDir) - return tmpBuildDir, tmpWorkingDir, isMod + log.Printf("New workingdir in tmp directory in: %v", b.TmpWorkingDir) } func TmpFolderName(path string) string { @@ -86,11 +89,13 @@ func TmpFolderName(path string) string { return "goc-" + h } -// Check if it is go module project +// checkIfLegacyProject Check if it is go module project // true legacy // false go mod -func checkIfLegacyProject(pkgs map[string]*cover.Package) bool { - for _, v := range pkgs { +func (b *Build) checkIfLegacyProject() bool { + for _, v := range b.Pkgs { + // get root + b.Root = v.Root if v.Module == nil { return true } @@ -100,8 +105,10 @@ func checkIfLegacyProject(pkgs map[string]*cover.Package) bool { return false } -func getTmpwd(tmpBuildDir string, pkgs map[string]*cover.Package, isMod bool) string { - for _, pkg := range pkgs { +// getTmpwd get the corresponding working directory in the temporary working directory +// and store it in the Build.tmpWorkdingDir +func (b *Build) getTmpwd() { + for _, pkg := range b.Pkgs { path, err := os.Getwd() if err != nil { log.Fatalf("Cannot get current working directory, the error is: %v", err) @@ -109,7 +116,7 @@ func getTmpwd(tmpBuildDir string, pkgs map[string]*cover.Package, isMod bool) st index := -1 var parentPath string - if isMod == false { + if b.IsMod == false { index = strings.Index(path, pkg.Root) parentPath = pkg.Root } else { @@ -120,24 +127,24 @@ func getTmpwd(tmpBuildDir string, pkgs map[string]*cover.Package, isMod bool) st if index == -1 { log.Fatalf("goc install not executed in project directory.") } - tmpwd := filepath.Join(tmpBuildDir, path[len(parentPath):]) + b.TmpWorkingDir = filepath.Join(b.TmpDir, path[len(parentPath):]) // log.Printf("New building directory in: %v", tmpwd) - return tmpwd + return } log.Fatalln("Should never be reached....") - return "" + return } -func FindWhereToInstall(pkgs map[string]*cover.Package) string { +func (b *Build) findWhereToInstall() string { if GOBIN := os.Getenv("GOBIN"); GOBIN != "" { return GOBIN } // old GOPATH dir GOPATH := os.Getenv("GOPATH") - if true == checkIfLegacyProject(pkgs) { - for _, v := range pkgs { + if false == b.IsMod { + for _, v := range b.Pkgs { return filepath.Join(v.Root, "bin") } } @@ -146,3 +153,12 @@ func FindWhereToInstall(pkgs map[string]*cover.Package) string { } return filepath.Join(os.Getenv("HOME"), "go", "bin") } + +func (b *Build) RemoveTmpDir() { + debuggoc := viper.GetBool("debuggoc") + if debuggoc == false { + if b.TmpDir != "" { + os.RemoveAll(b.TmpDir) + } + } +} diff --git a/pkg/build/tmpfolder_test.go b/pkg/build/tmpfolder_test.go index 596021d..1feb9bb 100644 --- a/pkg/build/tmpfolder_test.go +++ b/pkg/build/tmpfolder_test.go @@ -17,102 +17,13 @@ package build import ( - "encoding/json" "fmt" "os" "path/filepath" "strings" "testing" - - "github.com/qiniu/goc/pkg/cover" ) -const TEST_GO_LIST_LEGACY = `{ - "Dir": "/Users/lyyyuna/gitup/linking/src/qiniu.com/linking/api/linking.v1", - "ImportPath": "qiniu.com/linking/api/linking.v1", - "Name": "linking", - "Target": "/Users/lyyyuna/gitup/linking/pkg/darwin_amd64/qiniu.com/linking/api/linking.v1.a", - "Root": "/Users/lyyyuna/gitup/linking", - "Match": [ - "./..." - ], - "Stale": true, - "StaleReason": "stale dependency: vendor/github.com/modern-go/concurrent", - "GoFiles": [ - "client.go" - ], - "Imports": [ - "vendor/github.com/json-iterator/go", - "github.com/qiniu/rpc.v2", - "vendor/github.com/qiniu/xlog.v1", - "vendor/qiniu.com/auth/qiniumac.v1" - ], - "ImportMap": { - "github.com/json-iterator/go": "vendor/github.com/json-iterator/go", - "github.com/qiniu/xlog.v1": "vendor/github.com/qiniu/xlog.v1", - "qiniu.com/auth/qiniumac.v1": "vendor/qiniu.com/auth/qiniumac.v1" - }, - "Deps": [ - "bufio" - ] -}` - -const TEST_GO_LIST_MOD = `{ - "Dir": "/Users/lyyyuna/gitup/tonghu-chat", - "ImportPath": "github.com/lyyyuna/tonghu-chat", - "Name": "main", - "Target": "/Users/lyyyuna/go/bin/tonghu-chat", - "Root": "/Users/lyyyuna/gitup/tonghu-chat", - "Module": { - "Path": "github.com/lyyyuna/tonghu-chat", - "Main": true, - "Dir": "/Users/lyyyuna/gitup/tonghu-chat", - "GoMod": "/Users/lyyyuna/gitup/tonghu-chat/go.mod", - "GoVersion": "1.14" - }, - "Match": [ - "./..." - ], - "Stale": true, - "StaleReason": "not installed but available in build cache", - "GoFiles": [ - "main.go" - ], - "Imports": [ - "github.com/gin-gonic/gin", - "github.com/gorilla/websocket" - ], - "Deps": [ - "bufio" - ] -}` - -func constructPkg(raw string) *cover.Package { - var pkg cover.Package - if err := json.Unmarshal([]byte(raw), &pkg); err != nil { - panic(err) - } - return &pkg -} - -func TestLegacyProjectJudgement(t *testing.T) { - pkgs := make(map[string]*cover.Package) - pkg := constructPkg(TEST_GO_LIST_LEGACY) - pkgs[pkg.ImportPath] = pkg - if expect, got := true, checkIfLegacyProject(pkgs); expect != got { - t.Fatalf("Expected %v, but got %v.", expect, got) - } -} - -func TestModProjectJudgement(t *testing.T) { - pkgs := make(map[string]*cover.Package) - pkg := constructPkg(TEST_GO_LIST_MOD) - pkgs[pkg.ImportPath] = pkg - if expect, got := false, checkIfLegacyProject(pkgs); expect != got { - t.Fatalf("Expected %v, but got %v.", expect, got) - } -} - func TestNewDirParseInLegacyProject(t *testing.T) { workingDir := "../../tests/samples/simple_gopath_project/src/qiniu.com/simple_gopath_project" gopath, _ := filepath.Abs("../../tests/samples/simple_gopath_project") @@ -122,12 +33,64 @@ func TestNewDirParseInLegacyProject(t *testing.T) { os.Setenv("GOPATH", gopath) os.Setenv("GO111MODULE", "off") - newgopath, newwd, tmpdir, _ := MvProjectsToTmp(".", nil) - if -1 == strings.Index(newwd, tmpdir) { - t.Fatalf("Directory parse error. newwd: %v, tmpdir: %v", newwd, tmpdir) + b := NewInstall("", ".") + if -1 == strings.Index(b.TmpWorkingDir, b.TmpDir) { + t.Fatalf("Directory parse error. newwd: %v, tmpdir: %v", b.TmpWorkingDir, b.TmpDir) } - if -1 == strings.Index(newgopath, ":") || -1 == strings.Index(newgopath, tmpdir) { - t.Fatalf("The New GOPATH is wrong. newgopath: %v, tmpdir: %v", newgopath, tmpdir) + if -1 == strings.Index(b.NewGOPATH, ":") || -1 == strings.Index(b.NewGOPATH, b.TmpDir) { + t.Fatalf("The New GOPATH is wrong. newgopath: %v, tmpdir: %v", b.NewGOPATH, b.TmpDir) + } + + b = NewBuild("", ".", "") + if -1 == strings.Index(b.TmpWorkingDir, b.TmpDir) { + t.Fatalf("Directory parse error. newwd: %v, tmpdir: %v", b.TmpWorkingDir, b.TmpDir) + } + + if -1 == strings.Index(b.NewGOPATH, ":") || -1 == strings.Index(b.NewGOPATH, b.TmpDir) { + t.Fatalf("The New GOPATH is wrong. newgopath: %v, tmpdir: %v", b.NewGOPATH, b.TmpDir) + } +} + +func TestNewDirParseInModProject(t *testing.T) { + workingDir := "../../tests/samples/simple_project" + gopath := "" + + os.Chdir(workingDir) + fmt.Println(gopath) + os.Setenv("GOPATH", gopath) + os.Setenv("GO111MODULE", "on") + + b := NewInstall("", ".") + if -1 == strings.Index(b.TmpWorkingDir, b.TmpDir) { + t.Fatalf("Directory parse error. newwd: %v, tmpdir: %v", b.TmpWorkingDir, b.TmpDir) + } + + if b.NewGOPATH != "" { + t.Fatalf("The New GOPATH is wrong. newgopath: %v, tmpdir: %v", b.NewGOPATH, b.TmpDir) + } + + b = NewBuild("", ".", "") + if -1 == strings.Index(b.TmpWorkingDir, b.TmpDir) { + t.Fatalf("Directory parse error. newwd: %v, tmpdir: %v", b.TmpWorkingDir, b.TmpDir) + } + + if b.NewGOPATH != "" { + t.Fatalf("The New GOPATH is wrong. newgopath: %v, tmpdir: %v", b.NewGOPATH, b.TmpDir) + } +} + +// Test #14 +func TestLegacyProjectNotInGoPATH(t *testing.T) { + workingDir := "../../tests/samples/simple_gopath_project/src/qiniu.com/simple_gopath_project" + gopath := "" + + os.Chdir(workingDir) + fmt.Println(gopath) + os.Setenv("GOPATH", gopath) + os.Setenv("GO111MODULE", "off") + b := NewBuild("", ".", "") + if b.OriGOPATH != b.NewGOPATH { + t.Fatalf("New GOPATH should be same with old GOPATH, for this kind of project. New: %v, old: %v", b.NewGOPATH, b.OriGOPATH) } } diff --git a/pkg/cover/cover.go b/pkg/cover/cover.go index 71e868c..d06b558 100644 --- a/pkg/cover/cover.go +++ b/pkg/cover/cover.go @@ -22,9 +22,9 @@ import ( "crypto/sha256" "encoding/json" "fmt" + log "github.com/sirupsen/logrus" "io" "io/ioutil" - "log" "os" "os/exec" "path" @@ -113,17 +113,18 @@ type PackageError struct { } // ListPackages list all packages under specific via go list command -func ListPackages(dir string, args []string, newgopath string) map[string]*Package { - cmd := exec.Command("go", args...) +// The argument newgopath is if you need to go list in a different GOPATH +func ListPackages(dir string, args string, newgopath string) map[string]*Package { + cmd := exec.Command("/bin/bash", "-c", "go list "+args) log.Printf("go list cmd is: %v", cmd.Args) cmd.Dir = dir if newgopath != "" { cmd.Env = append(os.Environ(), fmt.Sprintf("GOPATH=%v", newgopath)) } - out, _ := cmd.Output() - // if err != nil { - // log.Fatalf("excute `go list -json ./...` command failed, err: %v, out: %v", err, string(out)) - // } + out, err := cmd.CombinedOutput() + if err != nil { + log.Fatalf("excute `go list -json ./...` command failed, err: %v, out: %v", err, string(out)) + } dec := json.NewDecoder(bytes.NewReader(out)) pkgs := make(map[string]*Package, 0) diff --git a/pkg/cover/cover_test.go b/pkg/cover/cover_test.go index 27081d6..05dfb3d 100644 --- a/pkg/cover/cover_test.go +++ b/pkg/cover/cover_test.go @@ -18,7 +18,7 @@ package cover import ( "fmt" - "log" + log "github.com/sirupsen/logrus" "os" "os/exec" "path/filepath" diff --git a/pkg/cover/server.go b/pkg/cover/server.go index debe0e1..721ee05 100644 --- a/pkg/cover/server.go +++ b/pkg/cover/server.go @@ -19,9 +19,9 @@ package cover import ( "bytes" "fmt" + log "github.com/sirupsen/logrus" "io" "io/ioutil" - "log" "net" "net/http" "net/url" diff --git a/pkg/cover/store.go b/pkg/cover/store.go index 2d6f971..f69d51f 100644 --- a/pkg/cover/store.go +++ b/pkg/cover/store.go @@ -19,7 +19,7 @@ package cover import ( "bufio" "fmt" - "log" + log "github.com/sirupsen/logrus" "os" "strings" "sync" diff --git a/pkg/qiniu/qnPresubmit.go b/pkg/qiniu/qnPresubmit.go index fdd75aa..203cb88 100644 --- a/pkg/qiniu/qnPresubmit.go +++ b/pkg/qiniu/qnPresubmit.go @@ -19,7 +19,7 @@ package qiniu import ( "encoding/json" "fmt" - "log" + log "github.com/sirupsen/logrus" "os" "path" "sort" diff --git a/tests/e2e/simple_project_test.go b/tests/e2e/simple_project_test.go index 8173df5..370838f 100644 --- a/tests/e2e/simple_project_test.go +++ b/tests/e2e/simple_project_test.go @@ -55,7 +55,7 @@ var _ = Describe("E2E", func() { By("goc build") testProjDir := filepath.Join(TESTS_ROOT, "samples/simple_project") - cmd := exec.Command("goc", "build") + cmd := exec.Command("goc", "build", "--debuggoc") cmd.Dir = testProjDir out, err := cmd.CombinedOutput() @@ -63,7 +63,7 @@ var _ = Describe("E2E", func() { By("goc install") testProjDir = filepath.Join(TESTS_ROOT, "samples/simple_project") - cmd = exec.Command("goc", "install", "./...") + cmd = exec.Command("goc", "install", "--debuggoc") cmd.Dir = testProjDir out, err = cmd.CombinedOutput() @@ -84,7 +84,7 @@ var _ = Describe("E2E", func() { obj := filepath.Join(dir, "simple-project") fInfo, err := os.Lstat(obj) Expect(err).To(BeNil()) - Expect(startTime.Before(fInfo.ModTime())).To(Equal(true), "new binary should be generated, not the old one") + Expect(startTime.Before(fInfo.ModTime())).To(Equal(true), obj+"new binary should be generated, not the old one") cmd := exec.Command("go", "tool", "objdump", "simple-project") cmd.Dir = dir @@ -114,17 +114,18 @@ var _ = Describe("E2E", func() { GOPATH = testProjDir By("goc build") - cmd := exec.Command("goc", "build") + cmd := exec.Command("goc", "build", "--debuggoc") cmd.Dir = oriWorkingDir // use GOPATH mode to compile project cmd.Env = append(os.Environ(), fmt.Sprintf("GOPATH=%v", GOPATH), "GO111MODULE=off") out, err := cmd.CombinedOutput() + fmt.Println(string(out)) Expect(err).To(BeNil(), "goc build on this project should be successful", string(out), cmd.Dir) By("goc install") testProjDir = filepath.Join(TESTS_ROOT, "samples/simple_gopath_project") - cmd = exec.Command("goc", "install", "./...") + cmd = exec.Command("goc", "install", "--debuggoc") cmd.Dir = filepath.Join(testProjDir, "src/qiniu.com/simple_gopath_project") // use GOPATH mode to compile project cmd.Env = append(os.Environ(), fmt.Sprintf("GOPATH=%v", testProjDir), "GO111MODULE=off") diff --git a/tests/samples/simple_gopath_project/go.mod b/tests/samples/simple_gopath_project/go.mod index e69de29..610643a 100644 --- a/tests/samples/simple_gopath_project/go.mod +++ b/tests/samples/simple_gopath_project/go.mod @@ -0,0 +1,3 @@ +module example.com/simple-project + +go 1.11