From f7c865c4d96468a105979336bf5217fcdd9e7c89 Mon Sep 17 00:00:00 2001 From: Carlos Alexandro Becker Date: Wed, 22 Sep 2021 22:25:26 -0300 Subject: [PATCH] refactor: split go mod into 2 pipes (#2502) Signed-off-by: Carlos Alexandro Becker --- internal/pipe/gomod/doc.go | 3 + internal/pipe/gomod/gomod proxy.go | 163 +++++++++++++++ internal/pipe/gomod/gomod.go | 156 +------------- internal/pipe/gomod/gomod_proxy_test.go | 258 ++++++++++++++++++++++++ internal/pipe/gomod/gomod_test.go | 219 +------------------- internal/pipeline/pipeline.go | 1 + 6 files changed, 427 insertions(+), 373 deletions(-) create mode 100644 internal/pipe/gomod/doc.go create mode 100644 internal/pipe/gomod/gomod proxy.go create mode 100644 internal/pipe/gomod/gomod_proxy_test.go diff --git a/internal/pipe/gomod/doc.go b/internal/pipe/gomod/doc.go new file mode 100644 index 00000000000..6871a086127 --- /dev/null +++ b/internal/pipe/gomod/doc.go @@ -0,0 +1,3 @@ +// Package gomod provides go modules utilities, such as template variables and the ability to proxy the module from +// proxy.golang.org. +package gomod diff --git a/internal/pipe/gomod/gomod proxy.go b/internal/pipe/gomod/gomod proxy.go new file mode 100644 index 00000000000..d03f43935da --- /dev/null +++ b/internal/pipe/gomod/gomod proxy.go @@ -0,0 +1,163 @@ +// Package gomod provides go modules utilities, such as template variables and the ability to proxy the module from +// proxy.golang.org. +package gomod + +import ( + "errors" + "fmt" + "io" + "os" + "os/exec" + "path" + "path/filepath" + "strings" + + "github.com/apex/log" + "github.com/goreleaser/goreleaser/internal/tmpl" + "github.com/goreleaser/goreleaser/pkg/config" + "github.com/goreleaser/goreleaser/pkg/context" +) + +// ProxyPipe for gomod proxy. +type ProxyPipe struct{} + +func (ProxyPipe) String() string { return "proxying go module" } + +func (ProxyPipe) Skip(ctx *context.Context) bool { + return ctx.ModulePath == "" || !ctx.Config.GoMod.Proxy || ctx.Snapshot +} + +// Run the ProxyPipe. +func (ProxyPipe) Run(ctx *context.Context) error { + for i := range ctx.Config.Builds { + build := &ctx.Config.Builds[i] + if err := proxyBuild(ctx, build); err != nil { + return err + } + } + + return nil +} + +const goModTpl = ` +module {{ .BuildID }} + +require {{ .ModulePath }} {{ .Tag }} +` + +const mainGoTpl = ` +// +build main +package main + +import _ "{{ .Main }}" +` + +// ErrProxy happens when something goes wrong while proxying the current go module. +type ErrProxy struct { + err error + details string +} + +func newErrProxy(err error) error { + return ErrProxy{ + err: err, + } +} + +func newDetailedErrProxy(err error, details string) error { + return ErrProxy{ + err: err, + details: details, + } +} + +func (e ErrProxy) Error() string { + out := fmt.Sprintf("failed to proxy module: %v", e.err) + if e.details != "" { + return fmt.Sprintf("%s: %s", out, e.details) + } + return out +} + +func (e ErrProxy) Unwrap() error { + return e.err +} + +func proxyBuild(ctx *context.Context, build *config.Build) error { + mainPackage := path.Join(ctx.ModulePath, build.Main) + if strings.HasSuffix(build.Main, ".go") { + pkg := path.Dir(build.Main) + log.Warnf("guessing package of '%s' to be '%s', if this is incorrect, setup 'build.%s.main' to be the correct package", build.Main, pkg, build.ID) + mainPackage = path.Join(ctx.ModulePath, pkg) + } + template := tmpl.New(ctx).WithExtraFields(tmpl.Fields{ + "Main": mainPackage, + "BuildID": build.ID, + }) + + log.Infof("proxying %s@%s to build %s", ctx.ModulePath, ctx.Git.CurrentTag, mainPackage) + + mod, err := template.Apply(goModTpl) + if err != nil { + return newErrProxy(err) + } + + main, err := template.Apply(mainGoTpl) + if err != nil { + return newErrProxy(err) + } + + dir := filepath.Join(ctx.Config.Dist, "proxy", build.ID) + + log.Debugf("creating needed files") + + if err := os.MkdirAll(dir, 0o755); err != nil { + return newErrProxy(err) + } + + if err := os.WriteFile(filepath.Join(dir, "main.go"), []byte(main), 0o666); err != nil { + return newErrProxy(err) + } + + if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte(mod), 0o666); err != nil { + return newErrProxy(err) + } + + if err := copyGoSum("go.sum", filepath.Join(dir, "go.sum")); err != nil { + return newErrProxy(err) + } + + log.Debugf("tidying") + cmd := exec.CommandContext(ctx, ctx.Config.GoMod.GoBinary, "mod", "tidy") + cmd.Dir = dir + cmd.Env = append(ctx.Config.GoMod.Env, os.Environ()...) + if out, err := cmd.CombinedOutput(); err != nil { + return newDetailedErrProxy(err, string(out)) + } + + build.UnproxiedMain = build.Main + build.UnproxiedDir = build.Dir + build.Main = mainPackage + build.Dir = dir + return nil +} + +func copyGoSum(src, dst string) error { + r, err := os.OpenFile(src, os.O_RDONLY, 0o666) + if err != nil { + if errors.Is(err, os.ErrNotExist) { + return nil + } + return err + } + defer r.Close() + + w, err := os.Create(dst) + if err != nil { + return err + } + defer w.Close() + + _, err = io.Copy(w, r) + return err +} diff --git a/internal/pipe/gomod/gomod.go b/internal/pipe/gomod/gomod.go index ca3878c53b7..25a1db9e3e0 100644 --- a/internal/pipe/gomod/gomod.go +++ b/internal/pipe/gomod/gomod.go @@ -1,21 +1,11 @@ -// Package gomod provides go modules utilities, such as template variables and the ability to proxy the module from -// proxy.golang.org. package gomod import ( - "errors" "fmt" - "io" - "os" "os/exec" - "path" - "path/filepath" "strings" - "github.com/apex/log" "github.com/goreleaser/goreleaser/internal/pipe" - "github.com/goreleaser/goreleaser/internal/tmpl" - "github.com/goreleaser/goreleaser/pkg/config" "github.com/goreleaser/goreleaser/pkg/context" ) @@ -24,7 +14,7 @@ const ( go116NotAGoModuleError = "command-line-arguments" ) -// Pipe for env. +// Pipe for gomod. type Pipe struct{} func (Pipe) String() string { return "loading go mod information" } @@ -49,149 +39,5 @@ func (Pipe) Run(ctx *context.Context) error { } ctx.ModulePath = result - - if !ctx.Config.GoMod.Proxy { - // TODO: check this on Skip? - return pipe.Skip("proxying not enabled") - } - - if ctx.Snapshot { - return pipe.ErrSnapshotEnabled - } - - return setupProxy(ctx) -} - -func setupProxy(ctx *context.Context) error { - for i := range ctx.Config.Builds { - build := &ctx.Config.Builds[i] - if err := proxyBuild(ctx, build); err != nil { - return err - } - } - - return nil -} - -const goModTpl = ` -module {{ .BuildID }} - -require {{ .ModulePath }} {{ .Tag }} -` - -const mainGoTpl = ` -// +build main -package main - -import _ "{{ .Main }}" -` - -// ErrProxy happens when something goes wrong while proxying the current go module. -type ErrProxy struct { - err error - details string -} - -func newErrProxy(err error) error { - return ErrProxy{ - err: err, - } -} - -func newDetailedErrProxy(err error, details string) error { - return ErrProxy{ - err: err, - details: details, - } -} - -func (e ErrProxy) Error() string { - out := fmt.Sprintf("failed to proxy module: %v", e.err) - if e.details != "" { - return fmt.Sprintf("%s: %s", out, e.details) - } - return out -} - -func (e ErrProxy) Unwrap() error { - return e.err -} - -func proxyBuild(ctx *context.Context, build *config.Build) error { - mainPackage := path.Join(ctx.ModulePath, build.Main) - if strings.HasSuffix(build.Main, ".go") { - pkg := path.Dir(build.Main) - log.Warnf("guessing package of '%s' to be '%s', if this is incorrect, setup 'build.%s.main' to be the correct package", build.Main, pkg, build.ID) - mainPackage = path.Join(ctx.ModulePath, pkg) - } - template := tmpl.New(ctx).WithExtraFields(tmpl.Fields{ - "Main": mainPackage, - "BuildID": build.ID, - }) - - log.Infof("proxying %s@%s to build %s", ctx.ModulePath, ctx.Git.CurrentTag, mainPackage) - - mod, err := template.Apply(goModTpl) - if err != nil { - return newErrProxy(err) - } - - main, err := template.Apply(mainGoTpl) - if err != nil { - return newErrProxy(err) - } - - dir := filepath.Join(ctx.Config.Dist, "proxy", build.ID) - - log.Debugf("creating needed files") - - if err := os.MkdirAll(dir, 0o755); err != nil { - return newErrProxy(err) - } - - if err := os.WriteFile(filepath.Join(dir, "main.go"), []byte(main), 0o666); err != nil { - return newErrProxy(err) - } - - if err := os.WriteFile(filepath.Join(dir, "go.mod"), []byte(mod), 0o666); err != nil { - return newErrProxy(err) - } - - if err := copyGoSum("go.sum", filepath.Join(dir, "go.sum")); err != nil { - return newErrProxy(err) - } - - log.Debugf("tidying") - cmd := exec.CommandContext(ctx, ctx.Config.GoMod.GoBinary, "mod", "tidy") - cmd.Dir = dir - cmd.Env = append(ctx.Config.GoMod.Env, os.Environ()...) - if out, err := cmd.CombinedOutput(); err != nil { - return newDetailedErrProxy(err, string(out)) - } - - build.UnproxiedMain = build.Main - build.UnproxiedDir = build.Dir - build.Main = mainPackage - build.Dir = dir return nil } - -func copyGoSum(src, dst string) error { - r, err := os.OpenFile(src, os.O_RDONLY, 0o666) - if err != nil { - if errors.Is(err, os.ErrNotExist) { - return nil - } - return err - } - defer r.Close() - - w, err := os.Create(dst) - if err != nil { - return err - } - defer w.Close() - - _, err = io.Copy(w, r) - return err -} diff --git a/internal/pipe/gomod/gomod_proxy_test.go b/internal/pipe/gomod/gomod_proxy_test.go new file mode 100644 index 00000000000..66b2fa42fd3 --- /dev/null +++ b/internal/pipe/gomod/gomod_proxy_test.go @@ -0,0 +1,258 @@ +package gomod + +import ( + "fmt" + "os" + "path/filepath" + "runtime" + "testing" + + "github.com/goreleaser/goreleaser/internal/testlib" + "github.com/goreleaser/goreleaser/pkg/config" + "github.com/goreleaser/goreleaser/pkg/context" + "github.com/stretchr/testify/require" +) + +func TestGoModProxy(t *testing.T) { + t.Run("goreleaser", func(t *testing.T) { + dir := testlib.Mktmp(t) + dist := filepath.Join(dir, "dist") + ctx := context.New(config.Project{ + Dist: dist, + GoMod: config.GoMod{ + Proxy: true, + GoBinary: "go", + }, + Builds: []config.Build{ + { + ID: "foo", + Goos: []string{runtime.GOOS}, + Goarch: []string{runtime.GOARCH}, + Main: ".", + Dir: ".", + }, + }, + }) + ctx.Git.CurrentTag = "v0.161.1" + + ctx.ModulePath = "github.com/goreleaser/goreleaser" + + fakeGoModAndSum(t, ctx.ModulePath) + require.NoError(t, ProxyPipe{}.Run(ctx)) + requireGoMod(t, ctx.ModulePath, ctx.Git.CurrentTag) + requireMainGo(t, ctx.ModulePath) + require.Equal(t, ctx.ModulePath, ctx.Config.Builds[0].Main) + require.Equal(t, ".", ctx.Config.Builds[0].UnproxiedMain) + require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) + require.Equal(t, ".", ctx.Config.Builds[0].UnproxiedDir) + require.Equal(t, ctx.ModulePath, ctx.ModulePath) + }) + + t.Run("nfpm", func(t *testing.T) { + dir := testlib.Mktmp(t) + dist := filepath.Join(dir, "dist") + ctx := context.New(config.Project{ + Dist: dist, + GoMod: config.GoMod{ + Proxy: true, + GoBinary: "go", + }, + Builds: []config.Build{ + { + ID: "foo", + Goos: []string{runtime.GOOS}, + Goarch: []string{runtime.GOARCH}, + Main: "./cmd/nfpm", + }, + }, + }) + ctx.Git.CurrentTag = "v2.3.1" + + ctx.ModulePath = "github.com/goreleaser/nfpm/v2" + fakeGoModAndSum(t, ctx.ModulePath) + require.NoError(t, ProxyPipe{}.Run(ctx)) + requireGoMod(t, ctx.ModulePath, ctx.Git.CurrentTag) + requireMainGo(t, ctx.ModulePath+"/cmd/nfpm") + require.Equal(t, ctx.ModulePath+"/cmd/nfpm", ctx.Config.Builds[0].Main) + require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) + require.Equal(t, ctx.ModulePath, ctx.ModulePath) + }) + + // this repo does not have a go.sum file, which is ok, a project might not have any dependencies + t.Run("no go.sum", func(t *testing.T) { + dir := testlib.Mktmp(t) + dist := filepath.Join(dir, "dist") + ctx := context.New(config.Project{ + Dist: dist, + GoMod: config.GoMod{ + Proxy: true, + GoBinary: "go", + }, + Builds: []config.Build{ + { + ID: "foo", + Goos: []string{runtime.GOOS}, + Goarch: []string{runtime.GOARCH}, + }, + }, + }) + ctx.Git.CurrentTag = "v0.0.1" + + ctx.ModulePath = "github.com/goreleaser/example-mod-proxy" + fakeGoMod(t, ctx.ModulePath) + require.NoError(t, ProxyPipe{}.Run(ctx)) + requireGoMod(t, ctx.ModulePath, ctx.Git.CurrentTag) + requireMainGo(t, ctx.ModulePath) + require.Equal(t, ctx.ModulePath, ctx.Config.Builds[0].Main) + require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) + require.Equal(t, ctx.ModulePath, ctx.ModulePath) + }) + + t.Run("no perms", func(t *testing.T) { + for file, mode := range map[string]os.FileMode{ + "go.mod": 0o500, + "go.sum": 0o500, + "main.go": 0o500, + "../../../go.sum": 0o300, + } { + t.Run(file, func(t *testing.T) { + dir := testlib.Mktmp(t) + dist := filepath.Join(dir, "dist") + ctx := context.New(config.Project{ + Dist: dist, + GoMod: config.GoMod{ + Proxy: true, + GoBinary: "go", + }, + Builds: []config.Build{ + { + ID: "foo", + Goos: []string{runtime.GOOS}, + Goarch: []string{runtime.GOARCH}, + }, + }, + }) + ctx.Git.CurrentTag = "v0.161.1" + + ctx.ModulePath = "github.com/goreleaser/goreleaser" + + fakeGoModAndSum(t, ctx.ModulePath) + require.NoError(t, ProxyPipe{}.Run(ctx)) // should succeed at first + + // change perms of a file and run again, which should now fail on that file. + require.NoError(t, os.Chmod(filepath.Join(dist, "proxy", "foo", file), mode)) + require.ErrorAs(t, ProxyPipe{}.Run(ctx), &ErrProxy{}) + }) + } + }) + + t.Run("goreleaser with main.go", func(t *testing.T) { + dir := testlib.Mktmp(t) + dist := filepath.Join(dir, "dist") + ctx := context.New(config.Project{ + Dist: dist, + GoMod: config.GoMod{ + Proxy: true, + GoBinary: "go", + }, + Builds: []config.Build{ + { + ID: "foo", + Goos: []string{runtime.GOOS}, + Goarch: []string{runtime.GOARCH}, + Main: "main.go", + }, + }, + }) + ctx.Git.CurrentTag = "v0.161.1" + + ctx.ModulePath = "github.com/goreleaser/goreleaser" + + fakeGoModAndSum(t, ctx.ModulePath) + require.NoError(t, ProxyPipe{}.Run(ctx)) + requireGoMod(t, ctx.ModulePath, ctx.Git.CurrentTag) + requireMainGo(t, ctx.ModulePath) + require.Equal(t, ctx.ModulePath, ctx.Config.Builds[0].Main) + require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) + require.Equal(t, ctx.ModulePath, ctx.ModulePath) + }) +} + +func TestProxyDescription(t *testing.T) { + require.NotEmpty(t, ProxyPipe{}.String()) +} + +func TestSkip(t *testing.T) { + t.Run("skip false gomod.proxy", func(t *testing.T) { + require.True(t, ProxyPipe{}.Skip(context.New(config.Project{}))) + }) + + t.Run("skip snapshot", func(t *testing.T) { + ctx := context.New(config.Project{ + GoMod: config.GoMod{ + Proxy: true, + }, + }) + ctx.ModulePath = "github.com/goreleaser/goreleaser" + ctx.Snapshot = true + require.True(t, ProxyPipe{}.Skip(ctx)) + }) + + t.Run("skip not a go module", func(t *testing.T) { + ctx := context.New(config.Project{ + GoMod: config.GoMod{ + Proxy: true, + }, + }) + ctx.ModulePath = "" + require.True(t, ProxyPipe{}.Skip(ctx)) + }) + + t.Run("dont skip", func(t *testing.T) { + ctx := context.New(config.Project{ + GoMod: config.GoMod{ + Proxy: true, + }, + }) + ctx.ModulePath = "github.com/goreleaser/goreleaser" + require.False(t, ProxyPipe{}.Skip(ctx)) + }) +} + +func requireGoMod(tb testing.TB, module, version string) { + tb.Helper() + + mod, err := os.ReadFile("dist/proxy/foo/go.mod") + require.NoError(tb, err) + require.Contains(tb, string(mod), fmt.Sprintf(`module foo + +go 1.17 + +require %s %s +`, module, version)) +} + +func requireMainGo(tb testing.TB, module string) { + tb.Helper() + + main, err := os.ReadFile("dist/proxy/foo/main.go") + require.NoError(tb, err) + require.Equal(tb, fmt.Sprintf(` +// +build main +package main + +import _ "%s" +`, module), string(main)) +} + +func fakeGoModAndSum(tb testing.TB, module string) { + tb.Helper() + + fakeGoMod(tb, module) + require.NoError(tb, os.WriteFile("go.sum", []byte("\n"), 0o666)) +} + +func fakeGoMod(tb testing.TB, module string) { + tb.Helper() + require.NoError(tb, os.WriteFile("go.mod", []byte(fmt.Sprintf("module %s\n", module)), 0o666)) +} diff --git a/internal/pipe/gomod/gomod_test.go b/internal/pipe/gomod/gomod_test.go index a27a691e869..34fe9ba4abf 100644 --- a/internal/pipe/gomod/gomod_test.go +++ b/internal/pipe/gomod/gomod_test.go @@ -1,10 +1,8 @@ package gomod import ( - "fmt" "os" "path/filepath" - "runtime" "testing" "github.com/goreleaser/goreleaser/internal/testlib" @@ -16,19 +14,7 @@ import ( func TestRun(t *testing.T) { ctx := context.New(config.Project{}) require.NoError(t, Pipe{}.Default(ctx)) - testlib.AssertSkipped(t, Pipe{}.Run(ctx)) - require.Equal(t, "github.com/goreleaser/goreleaser", ctx.ModulePath) -} - -func TestRunSnapshot(t *testing.T) { - ctx := context.New(config.Project{ - GoMod: config.GoMod{ - Proxy: true, - }, - }) - ctx.Snapshot = true - require.NoError(t, Pipe{}.Default(ctx)) - testlib.AssertSkipped(t, Pipe{}.Run(ctx)) + require.NoError(t, Pipe{}.Run(ctx)) require.Equal(t, "github.com/goreleaser/goreleaser", ctx.ModulePath) } @@ -54,206 +40,3 @@ func TestRunCommandError(t *testing.T) { func TestDescription(t *testing.T) { require.NotEmpty(t, Pipe{}.String()) } - -func TestGoModProxy(t *testing.T) { - t.Run("goreleaser", func(t *testing.T) { - dir := testlib.Mktmp(t) - dist := filepath.Join(dir, "dist") - ctx := context.New(config.Project{ - Dist: dist, - GoMod: config.GoMod{ - Proxy: true, - }, - Builds: []config.Build{ - { - ID: "foo", - Goos: []string{runtime.GOOS}, - Goarch: []string{runtime.GOARCH}, - Main: ".", - Dir: ".", - }, - }, - }) - ctx.Git.CurrentTag = "v0.161.1" - - mod := "github.com/goreleaser/goreleaser" - - fakeGoModAndSum(t, mod) - require.NoError(t, Pipe{}.Default(ctx)) - require.NoError(t, Pipe{}.Run(ctx)) - requireGoMod(t, mod, ctx.Git.CurrentTag) - requireMainGo(t, mod) - require.Equal(t, mod, ctx.Config.Builds[0].Main) - require.Equal(t, ".", ctx.Config.Builds[0].UnproxiedMain) - require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) - require.Equal(t, ".", ctx.Config.Builds[0].UnproxiedDir) - require.Equal(t, mod, ctx.ModulePath) - }) - - t.Run("nfpm", func(t *testing.T) { - dir := testlib.Mktmp(t) - dist := filepath.Join(dir, "dist") - ctx := context.New(config.Project{ - Dist: dist, - GoMod: config.GoMod{ - Proxy: true, - }, - Builds: []config.Build{ - { - ID: "foo", - Goos: []string{runtime.GOOS}, - Goarch: []string{runtime.GOARCH}, - Main: "./cmd/nfpm", - }, - }, - }) - ctx.Git.CurrentTag = "v2.3.1" - - mod := "github.com/goreleaser/nfpm/v2" - fakeGoModAndSum(t, mod) - require.NoError(t, Pipe{}.Default(ctx)) - require.NoError(t, Pipe{}.Run(ctx)) - requireGoMod(t, mod, ctx.Git.CurrentTag) - requireMainGo(t, mod+"/cmd/nfpm") - require.Equal(t, mod+"/cmd/nfpm", ctx.Config.Builds[0].Main) - require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) - require.Equal(t, mod, ctx.ModulePath) - }) - - // this repo does not have a go.sum file, which is ok, a project might not have any dependencies - t.Run("no go.sum", func(t *testing.T) { - dir := testlib.Mktmp(t) - dist := filepath.Join(dir, "dist") - ctx := context.New(config.Project{ - Dist: dist, - GoMod: config.GoMod{ - Proxy: true, - }, - Builds: []config.Build{ - { - ID: "foo", - Goos: []string{runtime.GOOS}, - Goarch: []string{runtime.GOARCH}, - }, - }, - }) - ctx.Git.CurrentTag = "v0.0.1" - - mod := "github.com/goreleaser/example-mod-proxy" - fakeGoMod(t, mod) - require.NoError(t, Pipe{}.Default(ctx)) - require.NoError(t, Pipe{}.Run(ctx)) - requireGoMod(t, mod, ctx.Git.CurrentTag) - requireMainGo(t, mod) - require.Equal(t, mod, ctx.Config.Builds[0].Main) - require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) - require.Equal(t, mod, ctx.ModulePath) - }) - - t.Run("no perms", func(t *testing.T) { - for file, mode := range map[string]os.FileMode{ - "go.mod": 0o500, - "go.sum": 0o500, - "main.go": 0o500, - "../../../go.sum": 0o300, - } { - t.Run(file, func(t *testing.T) { - dir := testlib.Mktmp(t) - dist := filepath.Join(dir, "dist") - ctx := context.New(config.Project{ - Dist: dist, - GoMod: config.GoMod{ - Proxy: true, - }, - Builds: []config.Build{ - { - ID: "foo", - Goos: []string{runtime.GOOS}, - Goarch: []string{runtime.GOARCH}, - }, - }, - }) - ctx.Git.CurrentTag = "v0.161.1" - - mod := "github.com/goreleaser/goreleaser" - - fakeGoModAndSum(t, mod) - require.NoError(t, Pipe{}.Default(ctx)) - require.NoError(t, Pipe{}.Run(ctx)) // should succeed at first - - // change perms of a file and run again, which should now fail on that file. - require.NoError(t, os.Chmod(filepath.Join(dist, "proxy", "foo", file), mode)) - require.ErrorAs(t, Pipe{}.Run(ctx), &ErrProxy{}) - }) - } - }) - - t.Run("goreleaser with main.go", func(t *testing.T) { - dir := testlib.Mktmp(t) - dist := filepath.Join(dir, "dist") - ctx := context.New(config.Project{ - Dist: dist, - GoMod: config.GoMod{ - Proxy: true, - }, - Builds: []config.Build{ - { - ID: "foo", - Goos: []string{runtime.GOOS}, - Goarch: []string{runtime.GOARCH}, - Main: "main.go", - }, - }, - }) - ctx.Git.CurrentTag = "v0.161.1" - - mod := "github.com/goreleaser/goreleaser" - - fakeGoModAndSum(t, mod) - require.NoError(t, Pipe{}.Default(ctx)) - require.NoError(t, Pipe{}.Run(ctx)) - requireGoMod(t, mod, ctx.Git.CurrentTag) - requireMainGo(t, mod) - require.Equal(t, mod, ctx.Config.Builds[0].Main) - require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) - require.Equal(t, mod, ctx.ModulePath) - }) -} - -func requireGoMod(tb testing.TB, module, version string) { - tb.Helper() - - mod, err := os.ReadFile("dist/proxy/foo/go.mod") - require.NoError(tb, err) - require.Contains(tb, string(mod), fmt.Sprintf(`module foo - -go 1.17 - -require %s %s -`, module, version)) -} - -func requireMainGo(tb testing.TB, module string) { - tb.Helper() - - main, err := os.ReadFile("dist/proxy/foo/main.go") - require.NoError(tb, err) - require.Equal(tb, fmt.Sprintf(` -// +build main -package main - -import _ "%s" -`, module), string(main)) -} - -func fakeGoModAndSum(tb testing.TB, module string) { - tb.Helper() - - fakeGoMod(tb, module) - require.NoError(tb, os.WriteFile("go.sum", []byte("\n"), 0o666)) -} - -func fakeGoMod(tb testing.TB, module string) { - tb.Helper() - require.NoError(tb, os.WriteFile("go.mod", []byte(fmt.Sprintf("module %s\n", module)), 0o666)) -} diff --git a/internal/pipeline/pipeline.go b/internal/pipeline/pipeline.go index f9021c555fa..65c4d1f14be 100644 --- a/internal/pipeline/pipeline.go +++ b/internal/pipeline/pipeline.go @@ -48,6 +48,7 @@ var BuildPipeline = []Piper{ snapshot.Pipe{}, // snapshot version handling dist.Pipe{}, // ensure ./dist is clean gomod.Pipe{}, // setup gomod-related stuff + gomod.ProxyPipe{}, // proxy gomod if needed effectiveconfig.Pipe{}, // writes the actual config (with defaults et al set) to dist changelog.Pipe{}, // builds the release changelog build.Pipe{}, // build