Skip to content

Commit feb4acc

Browse files
committed
Suggest brew upgrade gh when new version detected
When the update notifier is enabled and a new version was detected, show a Homebrew upgrade notice if: - the release was at least 24 hours ago; and - the current `gh` binary is under the Homebrew prefix.
1 parent f43fb26 commit feb4acc

File tree

2 files changed

+33
-6
lines changed

2 files changed

+33
-6
lines changed

cmd/gh/main.go

Lines changed: 30 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,9 @@ import (
88
"os"
99
"os/exec"
1010
"path"
11+
"path/filepath"
1112
"strings"
13+
"time"
1214

1315
surveyCore "github.com/AlecAivazis/survey/v2/core"
1416
"github.com/cli/cli/api"
@@ -161,13 +163,16 @@ func main() {
161163

162164
newRelease := <-updateMessageChan
163165
if newRelease != nil {
164-
msg := fmt.Sprintf("%s %s → %s\n%s",
166+
ghExe, _ := os.Executable()
167+
fmt.Fprintf(stderr, "\n\n%s %s → %s\n",
165168
ansi.Color("A new release of gh is available:", "yellow"),
166169
ansi.Color(buildVersion, "cyan"),
167-
ansi.Color(newRelease.Version, "cyan"),
170+
ansi.Color(newRelease.Version, "cyan"))
171+
if suggestBrewUpgrade(newRelease, ghExe) {
172+
fmt.Fprintf(stderr, "To upgrade, run: %s\n", "brew update && brew upgrade gh")
173+
}
174+
fmt.Fprintf(stderr, "%s\n\n",
168175
ansi.Color(newRelease.URL, "yellow"))
169-
170-
fmt.Fprintf(stderr, "\n\n%s\n\n", msg)
171176
}
172177
}
173178

@@ -259,3 +264,24 @@ func apiVerboseLog() api.ClientOption {
259264
colorize := utils.IsTerminal(os.Stderr)
260265
return api.VerboseLog(colorable.NewColorable(os.Stderr), logTraffic, colorize)
261266
}
267+
268+
// Suggest to `brew upgrade gh` only if gh was found under homebrew prefix and when the release was
269+
// published over 24h ago, allowing homebrew-core ample time to merge the formula bump.
270+
func suggestBrewUpgrade(rel *update.ReleaseInfo, ghBinary string) bool {
271+
if rel.PublishedAt.IsZero() || time.Since(rel.PublishedAt) < time.Duration(time.Hour*24) {
272+
return false
273+
}
274+
275+
brewExe, err := safeexec.LookPath("brew")
276+
if err != nil {
277+
return false
278+
}
279+
280+
brewPrefixBytes, err := exec.Command(brewExe, "--prefix").Output()
281+
if err != nil {
282+
return false
283+
}
284+
285+
brewBinPrefix := filepath.Join(strings.TrimSpace(string(brewPrefixBytes)), "bin") + string(filepath.Separator)
286+
return strings.HasPrefix(ghBinary, brewBinPrefix)
287+
}

internal/update/update.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ var gitDescribeSuffixRE = regexp.MustCompile(`\d+-\d+-g[a-f0-9]{8}$`)
1818

1919
// ReleaseInfo stores information about a release
2020
type ReleaseInfo struct {
21-
Version string `json:"tag_name"`
22-
URL string `json:"html_url"`
21+
Version string `json:"tag_name"`
22+
URL string `json:"html_url"`
23+
PublishedAt time.Time `json:"published_at"`
2324
}
2425

2526
type StateEntry struct {

0 commit comments

Comments
 (0)