fix #14
This commit is contained in:
parent
103dafe41d
commit
57498dd11f
19
cmd/build.go
19
cmd/build.go
@ -20,6 +20,7 @@ import (
|
|||||||
"github.com/qiniu/goc/pkg/build"
|
"github.com/qiniu/goc/pkg/build"
|
||||||
"github.com/qiniu/goc/pkg/cover"
|
"github.com/qiniu/goc/pkg/cover"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
var buildCmd = &cobra.Command{
|
var buildCmd = &cobra.Command{
|
||||||
@ -27,9 +28,7 @@ var buildCmd = &cobra.Command{
|
|||||||
Short: "Do cover for all go files and execute go build command",
|
Short: "Do cover for all go files and execute go build command",
|
||||||
Long: `
|
Long: `
|
||||||
First of all, this build command will copy the project code and its necessary dependencies to a temporary directory, then do cover for the target in this temporary directory, finally go build command will be executed and binaries generated to their original place.
|
First of all, this build command will copy the project code and its necessary dependencies to a temporary directory, then do cover for the target in this temporary directory, finally go build command will be executed and binaries generated to their original place.
|
||||||
|
`,
|
||||||
To pass original go build flags to goc command, place them after "--", see examples below for reference.
|
|
||||||
`,
|
|
||||||
Example: `
|
Example: `
|
||||||
# Build the current binary with cover variables injected. The binary will be generated in the current folder.
|
# Build the current binary with cover variables injected. The binary will be generated in the current folder.
|
||||||
goc build
|
goc build
|
||||||
@ -38,20 +37,26 @@ goc build
|
|||||||
goc build --center=http://127.0.0.1:7777
|
goc build --center=http://127.0.0.1:7777
|
||||||
|
|
||||||
# Build the current binary with cover variables injected, and redirect output to /to/this/path.
|
# Build the current binary with cover variables injected, and redirect output to /to/this/path.
|
||||||
goc build -- -o /to/this/path
|
goc build --output /to/this/path
|
||||||
|
|
||||||
# Build the current binary with cover variables injected, and set necessary build flags: -ldflags "-extldflags -static" -tags="embed kodo".
|
# Build 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) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
gocBuild := build.NewBuild(buildFlags, packages, buildOutput)
|
gocBuild, err := build.NewBuild(buildFlags, packages, buildOutput)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Fail to NewBuild: %v", err)
|
||||||
|
}
|
||||||
// remove temporary directory if needed
|
// remove temporary directory if needed
|
||||||
defer gocBuild.Clean()
|
defer gocBuild.Clean()
|
||||||
// doCover with original buildFlags, with new GOPATH( tmp:original )
|
// doCover with original buildFlags, with new GOPATH( tmp:original )
|
||||||
// in the tmp directory
|
// in the tmp directory
|
||||||
cover.Execute(buildFlags, gocBuild.NewGOPATH, gocBuild.TmpDir, mode, center)
|
cover.Execute(buildFlags, gocBuild.NewGOPATH, gocBuild.TmpDir, mode, center)
|
||||||
// do install in the temporary directory
|
// do install in the temporary directory
|
||||||
gocBuild.Build()
|
err = gocBuild.Build()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Fail to build: %v", err)
|
||||||
|
}
|
||||||
return
|
return
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"github.com/qiniu/goc/pkg/build"
|
"github.com/qiniu/goc/pkg/build"
|
||||||
"github.com/qiniu/goc/pkg/cover"
|
"github.com/qiniu/goc/pkg/cover"
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
"github.com/spf13/cobra"
|
"github.com/spf13/cobra"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -27,8 +28,6 @@ var installCmd = &cobra.Command{
|
|||||||
Short: "Do cover for all go files and execute go install command",
|
Short: "Do cover for all go files and execute go install command",
|
||||||
Long: `
|
Long: `
|
||||||
First of all, this install command will copy the project code and its necessary dependencies to a temporary directory, then do cover for the target in this temporary directory, finally go install command will be executed and binaries generated to their original place.
|
First of all, this install command will copy the project code and its necessary dependencies to a temporary directory, then do cover for the target in this temporary directory, finally go install command will be executed and binaries generated to their original place.
|
||||||
|
|
||||||
To pass original go build flags to goc command, place them after "--", see examples below for reference.
|
|
||||||
`,
|
`,
|
||||||
Example: `
|
Example: `
|
||||||
# Install all binaries with cover variables injected. The binary will be installed in $GOPATH/bin or $HOME/go/bin if directory existed.
|
# Install all binaries with cover variables injected. The binary will be installed in $GOPATH/bin or $HOME/go/bin if directory existed.
|
||||||
@ -41,14 +40,21 @@ goc install --center=http://127.0.0.1:7777
|
|||||||
goc build --buildflags="-ldflags '-extldflags -static' -tags='embed kodo'"
|
goc build --buildflags="-ldflags '-extldflags -static' -tags='embed kodo'"
|
||||||
`,
|
`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
gocBuild := build.NewInstall(buildFlags, packages)
|
gocBuild, err := build.NewInstall(buildFlags, packages)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Fail to NewInstall: %v", err)
|
||||||
|
}
|
||||||
// remove temporary directory if needed
|
// remove temporary directory if needed
|
||||||
defer gocBuild.Clean()
|
defer gocBuild.Clean()
|
||||||
// doCover with original buildFlags, with new GOPATH( tmp:original )
|
// doCover with original buildFlags, with new GOPATH( tmp:original )
|
||||||
// in the tmp directory
|
// in the tmp directory
|
||||||
cover.Execute(buildFlags, gocBuild.NewGOPATH, gocBuild.TmpDir, mode, center)
|
cover.Execute(buildFlags, gocBuild.NewGOPATH, gocBuild.TmpDir, mode, center)
|
||||||
// do install in the temporary directory
|
// do install in the temporary directory
|
||||||
gocBuild.Install()
|
err = gocBuild.Install()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("Fail to install: %v", err)
|
||||||
|
}
|
||||||
|
return
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ It is exactly behave as 'go run .' in addition of some internal goc features.`,
|
|||||||
goc run .
|
goc run .
|
||||||
`,
|
`,
|
||||||
Run: func(cmd *cobra.Command, args []string) {
|
Run: func(cmd *cobra.Command, args []string) {
|
||||||
gocBuild := build.NewBuild(buildFlags, packages, buildOutput)
|
gocBuild, _ := build.NewBuild(buildFlags, packages, buildOutput)
|
||||||
gocBuild.GoRunExecFlag = goRunExecFlag
|
gocBuild.GoRunExecFlag = goRunExecFlag
|
||||||
gocBuild.GoRunArguments = goRunArguments
|
gocBuild.GoRunArguments = goRunArguments
|
||||||
defer gocBuild.Clean()
|
defer gocBuild.Clean()
|
||||||
|
@ -35,9 +35,11 @@ type Build struct {
|
|||||||
TmpDir string // the temporary directory to build the project
|
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
|
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
|
IsMod bool // determine whether it is a Mod project
|
||||||
Root string // Project Root
|
Root string
|
||||||
Target string // the binary name that go build generate
|
// Project Root:
|
||||||
|
// 1. legacy, root == GOPATH
|
||||||
|
// 2. mod, root == go.mod Dir
|
||||||
|
Target string // the binary name that go build generate
|
||||||
// keep compatible with go commands:
|
// keep compatible with go commands:
|
||||||
// go run [build flags] [-exec xprog] package [arguments...]
|
// go run [build flags] [-exec xprog] package [arguments...]
|
||||||
// go build [-o output] [-i] [build flags] [packages]
|
// go build [-o output] [-i] [build flags] [packages]
|
||||||
@ -50,26 +52,33 @@ type Build struct {
|
|||||||
|
|
||||||
// NewBuild creates a Build struct which can build from goc temporary directory,
|
// NewBuild creates a Build struct which can build from goc temporary directory,
|
||||||
// and generate binary in current working directory
|
// and generate binary in current working directory
|
||||||
func NewBuild(buildflags string, packages string, outputDir string) *Build {
|
func NewBuild(buildflags string, packages string, outputDir string) (*Build, error) {
|
||||||
// buildflags = buildflags + " -o " + outputDir
|
// buildflags = buildflags + " -o " + outputDir
|
||||||
b := &Build{
|
b := &Build{
|
||||||
BuildFlags: buildflags,
|
BuildFlags: buildflags,
|
||||||
Packages: packages,
|
Packages: packages,
|
||||||
}
|
}
|
||||||
if false == b.validatePackageForBuild() {
|
if false == b.validatePackageForBuild() {
|
||||||
log.Fatalln("packages only support \".\"")
|
log.Errorln(ErrWrongPackageTypeForBuild)
|
||||||
|
return nil, ErrWrongPackageTypeForBuild
|
||||||
}
|
}
|
||||||
b.MvProjectsToTmp()
|
b.MvProjectsToTmp()
|
||||||
b.Target = b.determineOutputDir(outputDir)
|
dir, err := b.determineOutputDir(outputDir)
|
||||||
return b
|
b.Target = dir
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Build) Build() {
|
func (b *Build) Build() error {
|
||||||
log.Infoln("Go building in temp...")
|
log.Infoln("Go building in temp...")
|
||||||
// new -o will overwrite previous ones
|
// new -o will overwrite previous ones
|
||||||
b.BuildFlags = b.BuildFlags + " -o " + b.Target
|
b.BuildFlags = b.BuildFlags + " -o " + b.Target
|
||||||
cmd := exec.Command("/bin/bash", "-c", "go build "+b.BuildFlags+" "+b.Packages)
|
cmd := exec.Command("/bin/bash", "-c", "go build "+b.BuildFlags+" "+b.Packages)
|
||||||
cmd.Dir = b.TmpWorkingDir
|
cmd.Dir = b.TmpWorkingDir
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
if b.NewGOPATH != "" {
|
if b.NewGOPATH != "" {
|
||||||
// Change to temp GOPATH for go install command
|
// Change to temp GOPATH for go install command
|
||||||
@ -77,22 +86,30 @@ func (b *Build) Build() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("go build cmd is: %v", cmd.Args)
|
log.Printf("go build cmd is: %v", cmd.Args)
|
||||||
out, err := cmd.CombinedOutput()
|
err := cmd.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Fail to execute: %v. The error is: %v, the stdout/stderr is: %v", cmd.Args, err, string(out))
|
log.Errorf("Fail to execute: %v. The error is: %v", cmd.Args, err)
|
||||||
|
return fmt.Errorf("fail to execute: %v: %w", cmd.Args, err)
|
||||||
|
}
|
||||||
|
if err = cmd.Wait(); err != nil {
|
||||||
|
log.Errorf("go build failed. The error is: %v", err)
|
||||||
|
return fmt.Errorf("go build faileds: %w", err)
|
||||||
}
|
}
|
||||||
log.Println("Go build exit successful.")
|
log.Println("Go build exit successful.")
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// determineOutputDir, as we only allow . as package name,
|
// determineOutputDir, as we only allow . as package name,
|
||||||
// the binary name is always same as the directory name of current directory
|
// the binary name is always same as the directory name of current directory
|
||||||
func (b *Build) determineOutputDir(outputDir string) string {
|
func (b *Build) determineOutputDir(outputDir string) (string, error) {
|
||||||
if b.TmpDir == "" {
|
if b.TmpDir == "" {
|
||||||
log.Fatalln("Can only be called after Build.MvProjectsToTmp().")
|
log.Errorf("Can only be called after Build.MvProjectsToTmp()", ErrWrongCallSequence)
|
||||||
|
return "", fmt.Errorf("can only be called after Build.MvProjectsToTmp(): %w", ErrWrongCallSequence)
|
||||||
}
|
}
|
||||||
curWorkingDir, err := os.Getwd()
|
curWorkingDir, err := os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Cannot get current working directory, the err: %v.", err)
|
log.Errorf("Cannot get current working directory: %v", err)
|
||||||
|
return "", fmt.Errorf("cannot get current working directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if outputDir == "" {
|
if outputDir == "" {
|
||||||
@ -102,13 +119,14 @@ func (b *Build) determineOutputDir(outputDir string) string {
|
|||||||
// replace "_" with "-" in the import path
|
// replace "_" with "-" in the import path
|
||||||
last = strings.ReplaceAll(last, "_", "-")
|
last = strings.ReplaceAll(last, "_", "-")
|
||||||
}
|
}
|
||||||
return filepath.Join(curWorkingDir, last)
|
return filepath.Join(curWorkingDir, last), nil
|
||||||
}
|
}
|
||||||
abs, err := filepath.Abs(outputDir)
|
abs, err := filepath.Abs(outputDir)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Fail to transform the path: %v to absolute path, the error is: %v", outputDir, err)
|
log.Errorf("Fail to transform the path: %v to absolute path: %v", outputDir, err)
|
||||||
|
return "", fmt.Errorf("fail to transform the path %v to absolute path: %w", outputDir, err)
|
||||||
}
|
}
|
||||||
return abs
|
return abs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// validatePackageForBuild only allow . as package name
|
// validatePackageForBuild only allow . as package name
|
||||||
|
14
pkg/build/errors.go
Normal file
14
pkg/build/errors.go
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
package build
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
ErrShouldNotReached = errors.New("should never be reached")
|
||||||
|
ErrGocShouldExecInProject = errors.New("goc not executed in project directory")
|
||||||
|
ErrWrongPackageTypeForInstall = errors.New("packages only support \".\" and \"./...\"")
|
||||||
|
ErrWrongPackageTypeForBuild = errors.New("packages only support \".\"")
|
||||||
|
ErrWrongCallSequence = errors.New("function should be called in a specified sequence")
|
||||||
|
ErrNoplaceToInstall = errors.New("no go env")
|
||||||
|
)
|
@ -28,7 +28,7 @@ func (b *Build) cpGoModulesProject() {
|
|||||||
src := v.Module.Dir
|
src := v.Module.Dir
|
||||||
|
|
||||||
if err := copy.Copy(src, dst); err != nil {
|
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)
|
log.Errorf("Failed to Copy the folder from %v to %v, the error is: %v ", src, dst, err)
|
||||||
}
|
}
|
||||||
break
|
break
|
||||||
} else {
|
} else {
|
||||||
|
@ -25,36 +25,50 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
// NewInstall creates a Build struct which can install from goc temporary directory
|
// NewInstall creates a Build struct which can install from goc temporary directory
|
||||||
func NewInstall(buildflags string, packages string) *Build {
|
func NewInstall(buildflags string, packages string) (*Build, error) {
|
||||||
b := &Build{
|
b := &Build{
|
||||||
BuildFlags: buildflags,
|
BuildFlags: buildflags,
|
||||||
Packages: packages,
|
Packages: packages,
|
||||||
}
|
}
|
||||||
if false == b.validatePackageForInstall() {
|
if false == b.validatePackageForInstall() {
|
||||||
log.Fatalln("packages only support . and ./...")
|
log.Errorln(ErrWrongPackageTypeForInstall)
|
||||||
|
return nil, ErrWrongPackageTypeForInstall
|
||||||
}
|
}
|
||||||
b.MvProjectsToTmp()
|
b.MvProjectsToTmp()
|
||||||
return b
|
return b, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Build) Install() {
|
func (b *Build) Install() error {
|
||||||
log.Println("Go building in temp...")
|
log.Println("Go building in temp...")
|
||||||
cmd := exec.Command("/bin/bash", "-c", "go install "+b.BuildFlags+" "+b.Packages)
|
cmd := exec.Command("/bin/bash", "-c", "go install "+b.BuildFlags+" "+b.Packages)
|
||||||
cmd.Dir = b.TmpWorkingDir
|
cmd.Dir = b.TmpWorkingDir
|
||||||
|
cmd.Stdout = os.Stdout
|
||||||
|
cmd.Stderr = os.Stderr
|
||||||
|
|
||||||
|
whereToInstall, err := b.findWhereToInstall()
|
||||||
|
if err != nil {
|
||||||
|
// ignore the err
|
||||||
|
log.Errorf("No place to install: %v", err)
|
||||||
|
}
|
||||||
// Change the temp GOBIN, to force binary install to original place
|
// Change the temp GOBIN, to force binary install to original place
|
||||||
cmd.Env = append(os.Environ(), fmt.Sprintf("GOBIN=%v", b.findWhereToInstall()))
|
cmd.Env = append(os.Environ(), fmt.Sprintf("GOBIN=%v", whereToInstall))
|
||||||
if b.NewGOPATH != "" {
|
if b.NewGOPATH != "" {
|
||||||
// Change to temp GOPATH for go install command
|
// Change to temp GOPATH for go install command
|
||||||
cmd.Env = append(cmd.Env, fmt.Sprintf("GOPATH=%v", b.NewGOPATH))
|
cmd.Env = append(cmd.Env, fmt.Sprintf("GOPATH=%v", b.NewGOPATH))
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Printf("go install cmd is: %v", cmd.Args)
|
log.Infof("go install cmd is: %v", cmd.Args)
|
||||||
out, err := cmd.CombinedOutput()
|
err = cmd.Start()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Fail to execute: %v. The error is: %v, the stdout/stderr is: %v", cmd.Args, err, string(out))
|
log.Errorf("Fail to execute: %v. The error is: %v", cmd.Args, err)
|
||||||
|
return fmt.Errorf("fail to execute: %v: %w", cmd.Args, err)
|
||||||
}
|
}
|
||||||
log.Printf("Go install successful. Binary installed in: %v", b.findWhereToInstall())
|
if err = cmd.Wait(); err != nil {
|
||||||
|
log.Errorf("go install failed. The error is: %v", err)
|
||||||
|
return fmt.Errorf("go install failed: %w", err)
|
||||||
|
}
|
||||||
|
log.Infof("Go install successful. Binary installed in: %v", whereToInstall)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Build) validatePackageForInstall() bool {
|
func (b *Build) validatePackageForInstall() bool {
|
||||||
|
@ -20,9 +20,10 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
|
log "github.com/sirupsen/logrus"
|
||||||
|
|
||||||
"github.com/otiai10/copy"
|
"github.com/otiai10/copy"
|
||||||
"github.com/qiniu/goc/pkg/cover"
|
"github.com/qiniu/goc/pkg/cover"
|
||||||
log "github.com/sirupsen/logrus"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func (b *Build) cpLegacyProject() {
|
func (b *Build) cpLegacyProject() {
|
||||||
@ -37,7 +38,7 @@ func (b *Build) cpLegacyProject() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if err := copy.Copy(src, dst); err != nil {
|
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)
|
log.Errorf("Failed to Copy the folder from %v to %v, the error is: %v ", src, dst, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
visited[src] = true
|
visited[src] = true
|
||||||
@ -73,9 +74,25 @@ func (b *Build) cpDepPackages(pkg *cover.Package, visited map[string]bool) {
|
|||||||
dst := filepath.Join(b.TmpDir, "src", dep)
|
dst := filepath.Join(b.TmpDir, "src", dep)
|
||||||
|
|
||||||
if err := copy.Copy(src, dst); err != nil {
|
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)
|
log.Errorf("Failed to Copy the folder from %v to %v, the error is: %v ", src, dst, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
visited[src] = true
|
visited[src] = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (b *Build) cpNonStandardLegacy() {
|
||||||
|
for _, v := range b.Pkgs {
|
||||||
|
if v.Name == "main" {
|
||||||
|
dst := b.TmpDir
|
||||||
|
src := v.Dir
|
||||||
|
|
||||||
|
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)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
} else {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -18,6 +18,7 @@ package build
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
@ -54,10 +55,11 @@ func (b *Build) MvProjectsToTmp() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Build) mvProjectsToTmp() {
|
func (b *Build) mvProjectsToTmp() error {
|
||||||
path, err := os.Getwd()
|
path, err := os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Cannot get current working directory, the error is: %v", err)
|
log.Errorf("Cannot get current working directory, the error is: %v", err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
b.TmpDir = filepath.Join(os.TempDir(), TmpFolderName(path))
|
b.TmpDir = filepath.Join(os.TempDir(), TmpFolderName(path))
|
||||||
|
|
||||||
@ -66,20 +68,39 @@ func (b *Build) mvProjectsToTmp() {
|
|||||||
// Create a new tmp folder
|
// Create a new tmp folder
|
||||||
err = os.MkdirAll(filepath.Join(b.TmpDir, "src"), os.ModePerm)
|
err = os.MkdirAll(filepath.Join(b.TmpDir, "src"), os.ModePerm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Fail to create the temporary build directory. The err is: %v", err)
|
log.Errorf("Fail to create the temporary build directory. The err is: %v", err)
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
log.Printf("Tmp project generated in: %v", b.TmpDir)
|
log.Printf("Tmp project generated in: %v", b.TmpDir)
|
||||||
|
|
||||||
// set Build.IsMod flag, so we don't have to call checkIfLegacyProject another time
|
// traverse pkg list to get project meta info
|
||||||
if b.checkIfLegacyProject() {
|
b.IsMod, b.Root, err = b.traversePkgsList()
|
||||||
b.cpLegacyProject()
|
if errors.Is(err, ErrShouldNotReached) {
|
||||||
} else {
|
return fmt.Errorf("mvProjectsToTmp with a empty project: %w", err)
|
||||||
b.IsMod = true
|
}
|
||||||
b.cpGoModulesProject()
|
// we should get corresponding working directory in temporary directory
|
||||||
|
b.TmpWorkingDir, err = b.getTmpwd()
|
||||||
|
if err != nil {
|
||||||
|
log.Errorf("fail to get workding directory in temporary directory: %v", err)
|
||||||
|
return fmt.Errorf("fail to get workding directory in temporary directory: %w", err)
|
||||||
|
}
|
||||||
|
// issue #14
|
||||||
|
// if b.Root == "", then the project is non-standard project
|
||||||
|
// known cases:
|
||||||
|
// 1. a legacy project, but not in any GOPATH, will cause the b.Root == ""
|
||||||
|
if b.IsMod == false && b.Root != "" {
|
||||||
|
b.cpLegacyProject()
|
||||||
|
} else if b.IsMod == true && b.Root != "" {
|
||||||
|
b.cpGoModulesProject()
|
||||||
|
} else if b.IsMod == false && b.Root == "" {
|
||||||
|
b.TmpWorkingDir = b.TmpDir
|
||||||
|
b.cpNonStandardLegacy()
|
||||||
|
} else {
|
||||||
|
return fmt.Errorf("unknown project type: %w", ErrShouldNotReached)
|
||||||
}
|
}
|
||||||
b.getTmpwd()
|
|
||||||
|
|
||||||
log.Printf("New workingdir in tmp directory in: %v", b.TmpWorkingDir)
|
log.Infof("New workingdir in tmp directory in: %v", b.TmpWorkingDir)
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TmpFolderName(path string) string {
|
func TmpFolderName(path string) string {
|
||||||
@ -89,29 +110,35 @@ func TmpFolderName(path string) string {
|
|||||||
return "goc-" + h
|
return "goc-" + h
|
||||||
}
|
}
|
||||||
|
|
||||||
// checkIfLegacyProject Check if it is go module project
|
// traversePkgsList travse the Build.Pkgs list
|
||||||
// true legacy
|
// return Build.IsMod, tell if the project is a mod project
|
||||||
// false go mod
|
// return Build.Root:
|
||||||
func (b *Build) checkIfLegacyProject() bool {
|
// 1. the project root if it is a mod project,
|
||||||
|
// 2. current GOPATH if it is a legacy project,
|
||||||
|
// 3. some non-standard project, which Build.IsMod == false, Build.Root == nil
|
||||||
|
func (b *Build) traversePkgsList() (isMod bool, root string, err error) {
|
||||||
for _, v := range b.Pkgs {
|
for _, v := range b.Pkgs {
|
||||||
// get root
|
// get root
|
||||||
b.Root = v.Root
|
root = v.Root
|
||||||
if v.Module == nil {
|
if v.Module == nil {
|
||||||
return true
|
return
|
||||||
}
|
}
|
||||||
return false
|
isMod = true
|
||||||
|
return
|
||||||
}
|
}
|
||||||
log.Fatalln("Should never be reached....")
|
log.Error("should not reach here")
|
||||||
return false
|
err = ErrShouldNotReached
|
||||||
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// getTmpwd get the corresponding working directory in the temporary working directory
|
// getTmpwd get the corresponding working directory in the temporary working directory
|
||||||
// and store it in the Build.tmpWorkdingDir
|
// and store it in the Build.tmpWorkdingDir
|
||||||
func (b *Build) getTmpwd() {
|
func (b *Build) getTmpwd() (string, error) {
|
||||||
for _, pkg := range b.Pkgs {
|
for _, pkg := range b.Pkgs {
|
||||||
path, err := os.Getwd()
|
path, err := os.Getwd()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("Cannot get current working directory, the error is: %v", err)
|
log.Errorf("cannot get current working directory: %v", err)
|
||||||
|
return "", fmt.Errorf("cannot get current working directory: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
index := -1
|
index := -1
|
||||||
@ -125,33 +152,32 @@ func (b *Build) getTmpwd() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if index == -1 {
|
if index == -1 {
|
||||||
log.Fatalf("goc install not executed in project directory.")
|
return "", ErrGocShouldExecInProject
|
||||||
}
|
}
|
||||||
b.TmpWorkingDir = filepath.Join(b.TmpDir, path[len(parentPath):])
|
// b.TmpWorkingDir = filepath.Join(b.TmpDir, path[len(parentPath):])
|
||||||
// log.Printf("New building directory in: %v", tmpwd)
|
return filepath.Join(b.TmpDir, path[len(parentPath):]), nil
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
log.Fatalln("Should never be reached....")
|
return "", ErrShouldNotReached
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b *Build) findWhereToInstall() string {
|
func (b *Build) findWhereToInstall() (string, error) {
|
||||||
if GOBIN := os.Getenv("GOBIN"); GOBIN != "" {
|
if GOBIN := os.Getenv("GOBIN"); GOBIN != "" {
|
||||||
return GOBIN
|
return GOBIN, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// old GOPATH dir
|
// old GOPATH dir
|
||||||
GOPATH := os.Getenv("GOPATH")
|
GOPATH := os.Getenv("GOPATH")
|
||||||
if false == b.IsMod {
|
if false == b.IsMod {
|
||||||
for _, v := range b.Pkgs {
|
if b.Root == "" {
|
||||||
return filepath.Join(v.Root, "bin")
|
return "", ErrNoplaceToInstall
|
||||||
}
|
}
|
||||||
|
return filepath.Join(b.Root, "bin"), nil
|
||||||
}
|
}
|
||||||
if GOPATH != "" {
|
if GOPATH != "" {
|
||||||
return filepath.Join(strings.Split(GOPATH, ":")[0], "bin")
|
return filepath.Join(strings.Split(GOPATH, ":")[0], "bin"), nil
|
||||||
}
|
}
|
||||||
return filepath.Join(os.Getenv("HOME"), "go", "bin")
|
return filepath.Join(os.Getenv("HOME"), "go", "bin"), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Clean clears up the temporary workspace
|
// Clean clears up the temporary workspace
|
||||||
|
@ -33,7 +33,7 @@ func TestNewDirParseInLegacyProject(t *testing.T) {
|
|||||||
os.Setenv("GOPATH", gopath)
|
os.Setenv("GOPATH", gopath)
|
||||||
os.Setenv("GO111MODULE", "off")
|
os.Setenv("GO111MODULE", "off")
|
||||||
|
|
||||||
b := NewInstall("", ".")
|
b, _ := NewInstall("", ".")
|
||||||
if -1 == strings.Index(b.TmpWorkingDir, b.TmpDir) {
|
if -1 == strings.Index(b.TmpWorkingDir, b.TmpDir) {
|
||||||
t.Fatalf("Directory parse error. newwd: %v, tmpdir: %v", b.TmpWorkingDir, b.TmpDir)
|
t.Fatalf("Directory parse error. newwd: %v, tmpdir: %v", b.TmpWorkingDir, b.TmpDir)
|
||||||
}
|
}
|
||||||
@ -42,7 +42,7 @@ func TestNewDirParseInLegacyProject(t *testing.T) {
|
|||||||
t.Fatalf("The New GOPATH is wrong. newgopath: %v, tmpdir: %v", b.NewGOPATH, b.TmpDir)
|
t.Fatalf("The New GOPATH is wrong. newgopath: %v, tmpdir: %v", b.NewGOPATH, b.TmpDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
b = NewBuild("", ".", "")
|
b, _ = NewBuild("", ".", "")
|
||||||
if -1 == strings.Index(b.TmpWorkingDir, b.TmpDir) {
|
if -1 == strings.Index(b.TmpWorkingDir, b.TmpDir) {
|
||||||
t.Fatalf("Directory parse error. newwd: %v, tmpdir: %v", b.TmpWorkingDir, b.TmpDir)
|
t.Fatalf("Directory parse error. newwd: %v, tmpdir: %v", b.TmpWorkingDir, b.TmpDir)
|
||||||
}
|
}
|
||||||
@ -61,7 +61,7 @@ func TestNewDirParseInModProject(t *testing.T) {
|
|||||||
os.Setenv("GOPATH", gopath)
|
os.Setenv("GOPATH", gopath)
|
||||||
os.Setenv("GO111MODULE", "on")
|
os.Setenv("GO111MODULE", "on")
|
||||||
|
|
||||||
b := NewInstall("", ".")
|
b, _ := NewInstall("", ".")
|
||||||
if -1 == strings.Index(b.TmpWorkingDir, b.TmpDir) {
|
if -1 == strings.Index(b.TmpWorkingDir, b.TmpDir) {
|
||||||
t.Fatalf("Directory parse error. newwd: %v, tmpdir: %v", b.TmpWorkingDir, b.TmpDir)
|
t.Fatalf("Directory parse error. newwd: %v, tmpdir: %v", b.TmpWorkingDir, b.TmpDir)
|
||||||
}
|
}
|
||||||
@ -70,7 +70,7 @@ func TestNewDirParseInModProject(t *testing.T) {
|
|||||||
t.Fatalf("The New GOPATH is wrong. newgopath: %v, tmpdir: %v", b.NewGOPATH, b.TmpDir)
|
t.Fatalf("The New GOPATH is wrong. newgopath: %v, tmpdir: %v", b.NewGOPATH, b.TmpDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
b = NewBuild("", ".", "")
|
b, _ = NewBuild("", ".", "")
|
||||||
if -1 == strings.Index(b.TmpWorkingDir, b.TmpDir) {
|
if -1 == strings.Index(b.TmpWorkingDir, b.TmpDir) {
|
||||||
t.Fatalf("Directory parse error. newwd: %v, tmpdir: %v", b.TmpWorkingDir, b.TmpDir)
|
t.Fatalf("Directory parse error. newwd: %v, tmpdir: %v", b.TmpWorkingDir, b.TmpDir)
|
||||||
}
|
}
|
||||||
@ -89,7 +89,7 @@ func TestLegacyProjectNotInGoPATH(t *testing.T) {
|
|||||||
fmt.Println(gopath)
|
fmt.Println(gopath)
|
||||||
os.Setenv("GOPATH", gopath)
|
os.Setenv("GOPATH", gopath)
|
||||||
os.Setenv("GO111MODULE", "off")
|
os.Setenv("GO111MODULE", "off")
|
||||||
b := NewBuild("", ".", "")
|
b, _ := NewBuild("", ".", "")
|
||||||
if b.OriGOPATH != b.NewGOPATH {
|
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)
|
t.Fatalf("New GOPATH should be same with old GOPATH, for this kind of project. New: %v, old: %v", b.NewGOPATH, b.OriGOPATH)
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user