Repository: goreleaser/goreleaser
Pull request #2030 (2021-01-21 00:12:06)

fix: brew default install when using templates in the binary name
This was a long time TODO that should probably be removed anyway.

In the specific case of using templates in the `builds.binary` field, even if we evaluate it at defaults time, the formula wouldn't work when using multiple platforms, so it would have to be customized anyway.

This simplifies things by removing one complicated, probably wrong default (hence the warning) in favor of a simple probably wrong default (which will still have the warning).

All things considered I think this should be ok.

closes https://github.com/goreleaser/goreleaser/issues/2029
see #2021
see #1936

vercel[bot]: This pull request is being automatically deployed with Vercel ([learn more](https://vercel.link/github-learn-more)).  
To see the status of your deployment, click below or on the icon next to each commit.

🔍 Inspect: [https://vercel.com/goreleaser/goreleaser/o2grz8ts4](https://vercel.com/goreleaser/goreleaser/o2grz8ts4)  
✅ Preview: [https://goreleaser-git-brew-binary-tmpl.goreleaser.vercel.app](https://goreleaser-git-brew-binary-tmpl.goreleaser.vercel.app)


caarlos0: > Am I right that this reduces the number of binaries which would otherwise appear in the Homebrew formula to 1? Not that I think >1 binaries for macOS is common - just checking.

yes.

> I think distributing non-cgo and cgo binary of the same program as shown in the (now removed) test is unlikely to be practical, and other cases should probably be just covered by multiple `brew` statements. If each binary does a different thing, then it probably should be installed separately anyway?

The cgo stuff on the test wasn't doing anything, was just to assert that both builds were added to the formula.

---

a different approach to this would be build the install list in the `Run` part instead of `Default`, but I think this should be OK as the warning was there since forever 🤔 
caarlos0: Also notice it was only adding builds that have `darwin amd64` as target, even if a linuxbrew only formula should work too 🤣 

Patch:
diff --git a/internal/pipe/brew/brew.go b/internal/pipe/brew/brew.go
index 406c183f..3addf83c 100644
--- a/internal/pipe/brew/brew.go
+++ b/internal/pipe/brew/brew.go
@@ -83,28 +83,8 @@ func (Pipe) Default(ctx *context.Context) error {
 		var brew = &ctx.Config.Brews[i]
 
 		if brew.Install == "" {
-			// TODO: maybe replace this with a simpler also optimistic
-			// approach of just doing `bin.install "project_name"`?
-			var installs []string
-			for _, build := range ctx.Config.Builds {
-				if !isBrewBuild(build) {
-					continue
-				}
-				install := fmt.Sprintf(`bin.install "%s"`, build.Binary)
-				// Do not add duplicate "bin.install" statements when binary names overlap.
-				var found bool
-				for _, instruction := range installs {
-					if instruction == install {
-						found = true
-						break
-					}
-				}
-				if !found {
-					installs = append(installs, install)
-				}
-			}
-			brew.Install = strings.Join(installs, "\n")
-			log.Warnf("optimistically guessing `brew[%d].install`, double check", i)
+			brew.Install = fmt.Sprintf(`bin.install "%s"`, ctx.Config.ProjectName)
+			log.Warnf("optimistically guessing `brew[%d].install` to be `%s`", i, brew.Install)
 		}
 		if brew.CommitAuthor.Name == "" {
 			brew.CommitAuthor.Name = "goreleaserbot"
@@ -123,24 +103,6 @@ func (Pipe) Default(ctx *context.Context) error {
 	return nil
 }
 
-func isBrewBuild(build config.Build) bool {
-	for _, ignore := range build.Ignore {
-		if ignore.Goos == "darwin" && ignore.Goarch == "amd64" {
-			return false
-		}
-	}
-	return contains(build.Goos, "darwin") && contains(build.Goarch, "amd64")
-}
-
-func contains(ss []string, s string) bool {
-	for _, zs := range ss {
-		if zs == s {
-			return true
-		}
-	}
-	return false
-}
-
 func doRun(ctx *context.Context, brew config.Homebrew, cl client.Client) error {
 	if brew.Tap.Name == "" {
 		return pipe.Skip("brew section is not configured")


Test patch:
diff --git a/internal/pipe/brew/brew_test.go b/internal/pipe/brew/brew_test.go
index 9742484d..0a939915 100644
--- a/internal/pipe/brew/brew_test.go
+++ b/internal/pipe/brew/brew_test.go
@@ -840,36 +840,6 @@ func TestRunTokenTypeNotImplementedForBrew(t *testing.T) {
 	require.Equal(t, ErrTokenTypeNotImplementedForBrew{TokenType: "gitea"}, doRun(ctx, ctx.Config.Brews[0], client))
 }
 
-func TestDefaultBinInstallUniqueness(t *testing.T) {
-	testlib.Mktmp(t)
-
-	var ctx = &context.Context{
-		TokenType: context.TokenTypeGitHub,
-		Config: config.Project{
-			ProjectName: "myproject",
-			Brews: []config.Homebrew{
-				{},
-			},
-			Builds: []config.Build{
-				{
-					ID:     "macos",
-					Binary: "unique",
-					Goos:   []string{"darwin"},
-					Goarch: []string{"amd64"},
-				},
-				{
-					ID:     "macos-cgo",
-					Binary: "unique",
-					Goos:   []string{"darwin"},
-					Goarch: []string{"amd64"},
-				},
-			},
-		},
-	}
-	require.NoError(t, Pipe{}.Default(ctx))
-	require.Equal(t, `bin.install "unique"`, ctx.Config.Brews[0].Install)
-}
-
 func TestDefault(t *testing.T) {
 	testlib.Mktmp(t)
 
@@ -906,7 +876,7 @@ func TestDefault(t *testing.T) {
 	require.Equal(t, ctx.Config.ProjectName, ctx.Config.Brews[0].Name)
 	require.NotEmpty(t, ctx.Config.Brews[0].CommitAuthor.Name)
 	require.NotEmpty(t, ctx.Config.Brews[0].CommitAuthor.Email)
-	require.Equal(t, `bin.install "foo"`, ctx.Config.Brews[0].Install)
+	require.Equal(t, `bin.install "myproject"`, ctx.Config.Brews[0].Install)
 }
 
 func TestGHFolder(t *testing.T) {
diff --git a/internal/pipe/defaults/defaults_test.go b/internal/pipe/defaults/defaults_test.go
index 0c92245e..e0cb6b7b 100644
--- a/internal/pipe/defaults/defaults_test.go
+++ b/internal/pipe/defaults/defaults_test.go
@@ -94,7 +94,7 @@ func TestFillPartial(t *testing.T) {
 	}
 	require.NoError(t, Pipe{}.Run(ctx))
 	require.Len(t, ctx.Config.Archives[0].Files, 1)
-	require.Equal(t, `bin.install "testreleaser"`, ctx.Config.Brews[0].Install)
+	require.Equal(t, `bin.install "test"`, ctx.Config.Brews[0].Install)
 	require.NotEmpty(t, ctx.Config.Dockers[0].Goos)
 	require.NotEmpty(t, ctx.Config.Dockers[0].Goarch)
 	require.NotEmpty(t, ctx.Config.Dockers[0].Dockerfile)