diff --git a/go.mod b/go.mod index 91b80f1..a4b18ff 100644 --- a/go.mod +++ b/go.mod @@ -16,6 +16,7 @@ require ( github.com/spf13/pflag v1.0.5 github.com/spf13/viper v1.6.2 github.com/stretchr/testify v1.5.1 + golang.org/x/mod v0.3.0 golang.org/x/net v0.0.0-20200625001655-4c5254603344 golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d golang.org/x/tools v0.0.0-20200730221956-1ac65761fe2c diff --git a/go.sum b/go.sum index 722c912..9881f5d 100644 --- a/go.sum +++ b/go.sum @@ -822,6 +822,7 @@ golang.org/x/mod v0.0.0-20190513183733-4bf6d317e70e/go.mod h1:mXi4GBBbnImb6dmsKG golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4= golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= diff --git a/pkg/build/build.go b/pkg/build/build.go index 50b2809..e05cf1b 100644 --- a/pkg/build/build.go +++ b/pkg/build/build.go @@ -41,7 +41,8 @@ type Build struct { // Project Root: // 1. legacy, root == GOPATH // 2. mod, root == go.mod Dir - Target string // the binary name that go build generate + ModRoot string // path for go.mod + Target string // the binary name that go build generate // keep compatible with go commands: // go run [build flags] [-exec xprog] package [arguments...] // go build [-o output] [-i] [build flags] [packages] diff --git a/pkg/build/gomodules.go b/pkg/build/gomodules.go index 8c7e2e3..1c8f2c1 100644 --- a/pkg/build/gomodules.go +++ b/pkg/build/gomodules.go @@ -17,8 +17,13 @@ package build import ( + "io/ioutil" + "path/filepath" + "strings" + "github.com/otiai10/copy" log "github.com/sirupsen/logrus" + "golang.org/x/mod/modfile" ) func (b *Build) cpGoModulesProject() { @@ -36,3 +41,41 @@ func (b *Build) cpGoModulesProject() { } } } + +func (b *Build) updateGoModFile() (string, error) { + tempModfile := filepath.Join(b.TmpDir, "go.mod") + buf, err := ioutil.ReadFile(tempModfile) + if err != nil { + return "", err + } + oriGoModFile, err := modfile.Parse(tempModfile, buf, nil) + if err != nil { + return "", err + } + + for index := range oriGoModFile.Replace { + replace := oriGoModFile.Replace[index] + oldPath := replace.Old.Path + oldVersion := replace.Old.Version + newPath := replace.New.Path + newVersion := replace.New.Version + if strings.HasPrefix(replace.New.Path, "..") { + fullPath := filepath.Join(b.ModRoot, newPath) + absPath, err := filepath.Abs(fullPath) + if err != nil { + return "", err + } + err = oriGoModFile.DropReplace(oldPath, oldVersion) + err = oriGoModFile.AddReplace(oldPath, oldVersion, absPath, newVersion) + if err != nil { + return "", err + } + } + } + oriGoModFile.Cleanup() + newGoModFile, err := oriGoModFile.Format() + if err != nil { + return "", err + } + return string(newGoModFile), nil +} diff --git a/pkg/build/gomodules_test.go b/pkg/build/gomodules_test.go index 12276bd..f59ac91 100644 --- a/pkg/build/gomodules_test.go +++ b/pkg/build/gomodules_test.go @@ -18,7 +18,9 @@ package build import ( "bytes" + "errors" "os" + "path/filepath" "strings" "testing" @@ -53,3 +55,38 @@ func TestModProjectCopyWithUnexistedDir(t *testing.T) { output := captureOutput(b.cpGoModulesProject) assert.Equal(t, strings.Contains(output, "Failed to Copy"), true) } + +// test go mod file udpate +func TestUpdateModFileIfContainsReplace(t *testing.T) { + workingDir := filepath.Join(baseDir, "../../tests/samples/gomod_samples/a") + b := &Build{ + TmpDir: workingDir, + ModRoot: "/aa/bb/cc", + } + + newmod, err := b.updateGoModFile() + assert.Equal(t, err, nil) + assert.Contains(t, newmod, "replace github.com/qiniu/bar => /aa/bb/home/foo/bar") +} + +// test wrong go mod file +func TestWithWrongGoModFile(t *testing.T) { + workingDir := filepath.Join(baseDir, "../../tests/samples/xxxxxxxxxxxx/a") + b := &Build{ + TmpDir: workingDir, + ModRoot: "/aa/bb/cc", + } + + _, err := b.updateGoModFile() + assert.Equal(t, errors.Is(err, os.ErrNotExist), true) + + // a wrong format go mod + workingDir = filepath.Join(baseDir, "../../tests/samples/gomod_samples/b") + b = &Build{ + TmpDir: workingDir, + ModRoot: "/aa/bb/cc", + } + + _, err = b.updateGoModFile() + assert.NotEqual(t, err, nil) +} diff --git a/pkg/build/tmpfolder.go b/pkg/build/tmpfolder.go index f9a027c..fa98786 100644 --- a/pkg/build/tmpfolder.go +++ b/pkg/build/tmpfolder.go @@ -134,6 +134,7 @@ func (b *Build) traversePkgsList() (isMod bool, root string, err error) { return } isMod = true + b.ModRoot = v.Module.Dir return } log.Error(ErrShouldNotReached) diff --git a/tests/samples/gomod_samples/a/go.mod b/tests/samples/gomod_samples/a/go.mod new file mode 100644 index 0000000..1bfcf0c --- /dev/null +++ b/tests/samples/gomod_samples/a/go.mod @@ -0,0 +1,7 @@ +module example.com/gg/a + +replace github.com/qiniu/bar => ../home/foo/bar + +require ( + github.com/qiniu/bar v1.0.0 +) diff --git a/tests/samples/gomod_samples/b/go.mod b/tests/samples/gomod_samples/b/go.mod new file mode 100644 index 0000000..ca70ddd --- /dev/null +++ b/tests/samples/gomod_samples/b/go.mod @@ -0,0 +1,7 @@ +module example.com/gg/a + +replerace github.com/qiniu/bar => ../home/foo/bar + +eggrr ( + github.com/qiniu/bar v1.0.0 +)