github.com/windmeup/goreleaser@v1.21.95/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/stretchr/testify/require" 13 "github.com/windmeup/goreleaser/internal/testctx" 14 "github.com/windmeup/goreleaser/internal/testlib" 15 "github.com/windmeup/goreleaser/pkg/config" 16 "github.com/windmeup/goreleaser/pkg/context" 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 require.Equal(t, ctx.ModulePath, ctx.ModulePath) 127 }) 128 129 t.Run("nfpm", func(t *testing.T) { 130 dir := testlib.Mktmp(t) 131 dist := filepath.Join(dir, "dist") 132 ctx := testctx.NewWithCfg(config.Project{ 133 Dist: dist, 134 GoMod: config.GoMod{ 135 Proxy: true, 136 GoBinary: "go", 137 }, 138 Builds: []config.Build{ 139 { 140 ID: "foo", 141 Goos: []string{runtime.GOOS}, 142 Goarch: []string{runtime.GOARCH}, 143 Main: "./cmd/nfpm", 144 }, 145 }, 146 }, testctx.WithCurrentTag("v2.3.1"), withNfpmModulePath) 147 fakeGoModAndSum(t, ctx.ModulePath) 148 require.NoError(t, ProxyPipe{}.Run(ctx)) 149 requireGoMod(t) 150 require.Equal(t, ctx.ModulePath+"/cmd/nfpm", ctx.Config.Builds[0].Main) 151 require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) 152 require.Equal(t, ctx.ModulePath, ctx.ModulePath) 153 }) 154 155 // this repo does not have a go.sum file, which is ok, a project might not have any dependencies 156 t.Run("no go.sum", func(t *testing.T) { 157 dir := testlib.Mktmp(t) 158 dist := filepath.Join(dir, "dist") 159 ctx := testctx.NewWithCfg(config.Project{ 160 Dist: dist, 161 GoMod: config.GoMod{ 162 Proxy: true, 163 GoBinary: "go", 164 }, 165 Builds: []config.Build{ 166 { 167 ID: "foo", 168 Goos: []string{runtime.GOOS}, 169 Goarch: []string{runtime.GOARCH}, 170 }, 171 }, 172 }, testctx.WithCurrentTag("v0.0.1"), withExampleModulePath) 173 fakeGoMod(t, ctx.ModulePath) 174 require.NoError(t, ProxyPipe{}.Run(ctx)) 175 requireGoMod(t) 176 require.Equal(t, ctx.ModulePath, ctx.Config.Builds[0].Main) 177 require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) 178 require.Equal(t, ctx.ModulePath, ctx.ModulePath) 179 }) 180 181 t.Run("no perms", func(t *testing.T) { 182 for file, mode := range map[string]os.FileMode{ 183 "go.mod": 0o500, 184 "go.sum": 0o500, 185 "../../../go.sum": 0o300, 186 } { 187 t.Run(file, func(t *testing.T) { 188 dir := testlib.Mktmp(t) 189 dist := filepath.Join(dir, "dist") 190 ctx := testctx.NewWithCfg(config.Project{ 191 Dist: dist, 192 GoMod: config.GoMod{ 193 Proxy: true, 194 GoBinary: "go", 195 }, 196 Builds: []config.Build{ 197 { 198 ID: "foo", 199 Goos: []string{runtime.GOOS}, 200 Goarch: []string{runtime.GOARCH}, 201 }, 202 }, 203 }, withGoReleaserModulePath, testctx.WithCurrentTag("v0.161.1")) 204 205 fakeGoModAndSum(t, ctx.ModulePath) 206 require.NoError(t, ProxyPipe{}.Run(ctx)) // should succeed at first 207 208 // change perms of a file and run again, which should now fail on that file. 209 require.NoError(t, os.Chmod(filepath.Join(dist, "proxy", "foo", file), mode)) 210 require.ErrorIs(t, ProxyPipe{}.Run(ctx), syscall.EACCES) 211 }) 212 } 213 }) 214 215 t.Run("goreleaser with main.go", func(t *testing.T) { 216 dir := testlib.Mktmp(t) 217 dist := filepath.Join(dir, "dist") 218 ctx := testctx.NewWithCfg(config.Project{ 219 Dist: dist, 220 GoMod: config.GoMod{ 221 Proxy: true, 222 GoBinary: "go", 223 }, 224 Builds: []config.Build{ 225 { 226 ID: "foo", 227 Goos: []string{runtime.GOOS}, 228 Goarch: []string{runtime.GOARCH}, 229 Main: "main.go", 230 }, 231 }, 232 }, withGoReleaserModulePath, testctx.WithCurrentTag("v0.161.1")) 233 234 fakeGoModAndSum(t, ctx.ModulePath) 235 require.NoError(t, ProxyPipe{}.Run(ctx)) 236 requireGoMod(t) 237 require.Equal(t, ctx.ModulePath, ctx.Config.Builds[0].Main) 238 require.Equal(t, filepath.Join(dist, "proxy", "foo"), ctx.Config.Builds[0].Dir) 239 require.Equal(t, ctx.ModulePath, ctx.ModulePath) 240 }) 241 } 242 243 func TestProxyDescription(t *testing.T) { 244 require.NotEmpty(t, ProxyPipe{}.String()) 245 } 246 247 func TestSkip(t *testing.T) { 248 t.Run("skip false gomod.proxy", func(t *testing.T) { 249 ctx := testctx.New() 250 require.True(t, ProxyPipe{}.Skip(ctx)) 251 require.True(t, CheckGoModPipe{}.Skip(ctx)) 252 }) 253 254 t.Run("skip snapshot", func(t *testing.T) { 255 ctx := testctx.NewWithCfg(config.Project{ 256 GoMod: config.GoMod{ 257 Proxy: true, 258 }, 259 }, withGoReleaserModulePath, testctx.Snapshot) 260 require.True(t, ProxyPipe{}.Skip(ctx)) 261 require.False(t, CheckGoModPipe{}.Skip(ctx)) 262 }) 263 264 t.Run("skip not a go module", func(t *testing.T) { 265 ctx := testctx.NewWithCfg(config.Project{ 266 GoMod: config.GoMod{ 267 Proxy: true, 268 }, 269 }, func(ctx *context.Context) { ctx.ModulePath = "" }) 270 require.True(t, ProxyPipe{}.Skip(ctx)) 271 require.True(t, CheckGoModPipe{}.Skip(ctx)) 272 }) 273 274 t.Run("dont skip", func(t *testing.T) { 275 ctx := testctx.NewWithCfg(config.Project{ 276 GoMod: config.GoMod{ 277 Proxy: true, 278 }, 279 }, withGoReleaserModulePath) 280 require.False(t, ProxyPipe{}.Skip(ctx)) 281 require.False(t, CheckGoModPipe{}.Skip(ctx)) 282 }) 283 } 284 285 func requireGoMod(tb testing.TB) { 286 tb.Helper() 287 288 mod, err := os.ReadFile("dist/proxy/foo/go.mod") 289 require.NoError(tb, err) 290 require.Contains(tb, string(mod), `module foo 291 292 go 1.21`) 293 } 294 295 func fakeGoModAndSum(tb testing.TB, module string) { 296 tb.Helper() 297 298 fakeGoMod(tb, module) 299 require.NoError(tb, os.WriteFile("go.sum", []byte("\n"), 0o666)) 300 } 301 302 func fakeGoMod(tb testing.TB, module string) { 303 tb.Helper() 304 require.NoError(tb, os.WriteFile("go.mod", []byte(fmt.Sprintf("module %s\n", module)), 0o666)) 305 } 306 307 func withGoReleaserModulePath(ctx *context.Context) { 308 ctx.ModulePath = "github.com/windmeup/goreleaser" 309 } 310 311 func withNfpmModulePath(ctx *context.Context) { 312 ctx.ModulePath = "github.com/goreleaser/nfpm/v2" 313 } 314 315 func withExampleModulePath(ctx *context.Context) { 316 ctx.ModulePath = "github.com/goreleaser/example-mod-proxy" 317 }