github.com/goreleaser/goreleaser@v1.25.1/internal/pipe/gomod/gomod_proxy_test.go (about) 1 package gomod 2 3 import ( 4 "fmt" 5 "os" 6 "os/exec" 7 "path/filepath" 8 "runtime" 9 "syscall" 10 "testing" 11 12 "github.com/goreleaser/goreleaser/internal/testctx" 13 "github.com/goreleaser/goreleaser/internal/testlib" 14 "github.com/goreleaser/goreleaser/pkg/config" 15 "github.com/goreleaser/goreleaser/pkg/context" 16 "github.com/stretchr/testify/require" 17 ) 18 19 func TestString(t *testing.T) { 20 require.NotEmpty(t, CheckGoModPipe{}.String()) 21 require.NotEmpty(t, ProxyPipe{}.String()) 22 } 23 24 func TestCheckGoMod(t *testing.T) { 25 t.Run("replace on snapshot", func(t *testing.T) { 26 dir := testlib.Mktmp(t) 27 dist := filepath.Join(dir, "dist") 28 ctx := testctx.NewWithCfg(config.Project{ 29 Dist: dist, 30 GoMod: config.GoMod{ 31 Proxy: true, 32 GoBinary: "go", 33 }, 34 Builds: []config.Build{ 35 { 36 ID: "foo", 37 Goos: []string{runtime.GOOS}, 38 Goarch: []string{runtime.GOARCH}, 39 Main: ".", 40 Dir: ".", 41 }, 42 }, 43 }, testctx.Snapshot, withGoReleaserModulePath) 44 45 fakeGoModAndSum(t, ctx.ModulePath) 46 require.NoError(t, exec.Command("go", "mod", "edit", "-replace", "foo=../bar").Run()) 47 require.NoError(t, CheckGoModPipe{}.Run(ctx)) 48 }) 49 t.Run("no go mod", func(t *testing.T) { 50 dir := testlib.Mktmp(t) 51 dist := filepath.Join(dir, "dist") 52 ctx := testctx.NewWithCfg(config.Project{ 53 Dist: dist, 54 GoMod: config.GoMod{ 55 Proxy: true, 56 GoBinary: "go", 57 }, 58 Builds: []config.Build{ 59 { 60 ID: "foo", 61 Goos: []string{runtime.GOOS}, 62 Goarch: []string{runtime.GOARCH}, 63 Main: ".", 64 Dir: ".", 65 }, 66 }, 67 }, withGoReleaserModulePath) 68 69 require.NoError(t, CheckGoModPipe{}.Run(ctx)) 70 }) 71 t.Run("replace", func(t *testing.T) { 72 dir := testlib.Mktmp(t) 73 dist := filepath.Join(dir, "dist") 74 ctx := testctx.NewWithCfg(config.Project{ 75 Dist: dist, 76 GoMod: config.GoMod{ 77 Proxy: true, 78 GoBinary: "go", 79 }, 80 Builds: []config.Build{ 81 { 82 ID: "foo", 83 Goos: []string{runtime.GOOS}, 84 Goarch: []string{runtime.GOARCH}, 85 Main: ".", 86 Dir: ".", 87 }, 88 }, 89 }, withGoReleaserModulePath) 90 91 fakeGoModAndSum(t, ctx.ModulePath) 92 require.NoError(t, exec.Command("go", "mod", "edit", "-replace", "foo=../bar").Run()) 93 require.ErrorIs(t, CheckGoModPipe{}.Run(ctx), ErrReplaceWithProxy) 94 }) 95 } 96 97 func TestGoModProxy(t *testing.T) { 98 t.Run("goreleaser", func(t *testing.T) { 99 dir := testlib.Mktmp(t) 100 dist := filepath.Join(dir, "dist") 101 ctx := testctx.NewWithCfg(config.Project{ 102 Dist: dist, 103 GoMod: config.GoMod{ 104 Proxy: true, 105 GoBinary: "go", 106 }, 107 Builds: []config.Build{ 108 { 109 ID: "foo", 110 Goos: []string{runtime.GOOS}, 111 Goarch: []string{runtime.GOARCH}, 112 Main: ".", 113 Dir: ".", 114 }, 115 }, 116 }, testctx.WithCurrentTag("v0.161.1"), withGoReleaserModulePath) 117 118 fakeGoModAndSum(t, ctx.ModulePath) 119 require.NoError(t, ProxyPipe{}.Run(ctx)) 120 requireGoMod(t) 121 require.Equal(t, ctx.ModulePath, ctx.Config.Builds[0].Main) 122 require.Equal(t, ".", ctx.Config.Builds[0].UnproxiedMain) 123 require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) 124 require.Equal(t, ".", ctx.Config.Builds[0].UnproxiedDir) 125 }) 126 127 t.Run("nfpm", func(t *testing.T) { 128 dir := testlib.Mktmp(t) 129 dist := filepath.Join(dir, "dist") 130 ctx := testctx.NewWithCfg(config.Project{ 131 Dist: dist, 132 GoMod: config.GoMod{ 133 Proxy: true, 134 GoBinary: "go", 135 }, 136 Builds: []config.Build{ 137 { 138 ID: "foo", 139 Goos: []string{runtime.GOOS}, 140 Goarch: []string{runtime.GOARCH}, 141 Main: "./cmd/nfpm", 142 }, 143 }, 144 }, testctx.WithCurrentTag("v2.3.1"), withNfpmModulePath) 145 fakeGoModAndSum(t, ctx.ModulePath) 146 require.NoError(t, ProxyPipe{}.Run(ctx)) 147 requireGoMod(t) 148 require.Equal(t, ctx.ModulePath+"/cmd/nfpm", ctx.Config.Builds[0].Main) 149 require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) 150 }) 151 152 // this repo does not have a go.sum file, which is ok, a project might not have any dependencies 153 t.Run("no go.sum", func(t *testing.T) { 154 dir := testlib.Mktmp(t) 155 dist := filepath.Join(dir, "dist") 156 ctx := testctx.NewWithCfg(config.Project{ 157 Dist: dist, 158 GoMod: config.GoMod{ 159 Proxy: true, 160 GoBinary: "go", 161 }, 162 Builds: []config.Build{ 163 { 164 ID: "foo", 165 Goos: []string{runtime.GOOS}, 166 Goarch: []string{runtime.GOARCH}, 167 }, 168 }, 169 }, testctx.WithCurrentTag("v0.0.1"), withExampleModulePath) 170 fakeGoMod(t, ctx.ModulePath) 171 require.NoError(t, ProxyPipe{}.Run(ctx)) 172 requireGoMod(t) 173 require.Equal(t, ctx.ModulePath, ctx.Config.Builds[0].Main) 174 require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) 175 }) 176 177 t.Run("no perms", func(t *testing.T) { 178 for file, mode := range map[string]os.FileMode{ 179 "go.mod": 0o500, 180 "go.sum": 0o500, 181 "../../../go.sum": 0o300, 182 } { 183 t.Run(file, func(t *testing.T) { 184 dir := testlib.Mktmp(t) 185 dist := filepath.Join(dir, "dist") 186 ctx := testctx.NewWithCfg(config.Project{ 187 Dist: dist, 188 GoMod: config.GoMod{ 189 Proxy: true, 190 GoBinary: "go", 191 }, 192 Builds: []config.Build{ 193 { 194 ID: "foo", 195 Goos: []string{runtime.GOOS}, 196 Goarch: []string{runtime.GOARCH}, 197 }, 198 }, 199 }, withGoReleaserModulePath, testctx.WithCurrentTag("v0.161.1")) 200 201 fakeGoModAndSum(t, ctx.ModulePath) 202 require.NoError(t, ProxyPipe{}.Run(ctx)) // should succeed at first 203 204 // change perms of a file and run again, which should now fail on that file. 205 require.NoError(t, os.Chmod(filepath.Join(dist, "proxy", "foo", file), mode)) 206 require.ErrorIs(t, ProxyPipe{}.Run(ctx), syscall.EACCES) 207 }) 208 } 209 }) 210 211 t.Run("goreleaser with main.go", func(t *testing.T) { 212 dir := testlib.Mktmp(t) 213 dist := filepath.Join(dir, "dist") 214 ctx := testctx.NewWithCfg(config.Project{ 215 Dist: dist, 216 GoMod: config.GoMod{ 217 Proxy: true, 218 GoBinary: "go", 219 }, 220 Builds: []config.Build{ 221 { 222 ID: "foo", 223 Goos: []string{runtime.GOOS}, 224 Goarch: []string{runtime.GOARCH}, 225 Main: "main.go", 226 }, 227 }, 228 }, withGoReleaserModulePath, testctx.WithCurrentTag("v0.161.1")) 229 230 fakeGoModAndSum(t, ctx.ModulePath) 231 require.NoError(t, ProxyPipe{}.Run(ctx)) 232 requireGoMod(t) 233 require.Equal(t, ctx.ModulePath, ctx.Config.Builds[0].Main) 234 require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) 235 }) 236 } 237 238 func TestProxyDescription(t *testing.T) { 239 require.NotEmpty(t, ProxyPipe{}.String()) 240 } 241 242 func TestSkip(t *testing.T) { 243 t.Run("skip false gomod.proxy", func(t *testing.T) { 244 ctx := testctx.New() 245 require.True(t, ProxyPipe{}.Skip(ctx)) 246 require.True(t, CheckGoModPipe{}.Skip(ctx)) 247 }) 248 249 t.Run("skip snapshot", func(t *testing.T) { 250 ctx := testctx.NewWithCfg(config.Project{ 251 GoMod: config.GoMod{ 252 Proxy: true, 253 }, 254 }, withGoReleaserModulePath, testctx.Snapshot) 255 require.True(t, ProxyPipe{}.Skip(ctx)) 256 require.False(t, CheckGoModPipe{}.Skip(ctx)) 257 }) 258 259 t.Run("skip not a go module", func(t *testing.T) { 260 ctx := testctx.NewWithCfg(config.Project{ 261 GoMod: config.GoMod{ 262 Proxy: true, 263 }, 264 }, func(ctx *context.Context) { ctx.ModulePath = "" }) 265 require.True(t, ProxyPipe{}.Skip(ctx)) 266 require.True(t, CheckGoModPipe{}.Skip(ctx)) 267 }) 268 269 t.Run("dont skip", func(t *testing.T) { 270 ctx := testctx.NewWithCfg(config.Project{ 271 GoMod: config.GoMod{ 272 Proxy: true, 273 }, 274 }, withGoReleaserModulePath) 275 require.False(t, ProxyPipe{}.Skip(ctx)) 276 require.False(t, CheckGoModPipe{}.Skip(ctx)) 277 }) 278 } 279 280 func requireGoMod(tb testing.TB) { 281 tb.Helper() 282 283 mod, err := os.ReadFile("dist/proxy/foo/go.mod") 284 require.NoError(tb, err) 285 require.Contains(tb, string(mod), `module foo 286 287 go 1.22`) 288 } 289 290 func fakeGoModAndSum(tb testing.TB, module string) { 291 tb.Helper() 292 293 fakeGoMod(tb, module) 294 require.NoError(tb, os.WriteFile("go.sum", []byte("\n"), 0o666)) 295 } 296 297 func fakeGoMod(tb testing.TB, module string) { 298 tb.Helper() 299 require.NoError(tb, os.WriteFile("go.mod", []byte(fmt.Sprintf("module %s\n", module)), 0o666)) 300 } 301 302 func withGoReleaserModulePath(ctx *context.Context) { 303 ctx.ModulePath = "github.com/goreleaser/goreleaser" 304 } 305 306 func withNfpmModulePath(ctx *context.Context) { 307 ctx.ModulePath = "github.com/goreleaser/nfpm/v2" 308 } 309 310 func withExampleModulePath(ctx *context.Context) { 311 ctx.ModulePath = "github.com/goreleaser/example-mod-proxy" 312 }