Skip to content

Commit

Permalink
Merge remote-tracking branch 'origin' into cancel-error-status
Browse files Browse the repository at this point in the history
  • Loading branch information
mislav committed Mar 2, 2021
2 parents 2ebdde1 + 50c49df commit dd34cae
Show file tree
Hide file tree
Showing 42 changed files with 1,856 additions and 207 deletions.
10 changes: 7 additions & 3 deletions api/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,13 @@ func (fs *fileStorage) store(key string, res *http.Response) error {
defer f.Close()

var origBody io.ReadCloser
origBody, res.Body = copyStream(res.Body)
defer res.Body.Close()
if res.Body != nil {
origBody, res.Body = copyStream(res.Body)
defer res.Body.Close()
}
err = res.Write(f)
res.Body = origBody
if origBody != nil {
res.Body = origBody
}
return err
}
22 changes: 14 additions & 8 deletions cmd/gh/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -169,12 +169,19 @@ func main() {

newRelease := <-updateMessageChan
if newRelease != nil {
ghExe, _ := os.Executable()
isHomebrew := false
if ghExe, err := os.Executable(); err == nil {
isHomebrew = isUnderHomebrew(ghExe)
}
if isHomebrew && isRecentRelease(newRelease.PublishedAt) {
// do not notify Homebrew users before the version bump had a chance to get merged into homebrew-core
return
}
fmt.Fprintf(stderr, "\n\n%s %s → %s\n",
ansi.Color("A new release of gh is available:", "yellow"),
ansi.Color(buildVersion, "cyan"),
ansi.Color(newRelease.Version, "cyan"))
if suggestBrewUpgrade(newRelease, ghExe) {
if isHomebrew {
fmt.Fprintf(stderr, "To upgrade, run: %s\n", "brew update && brew upgrade gh")
}
fmt.Fprintf(stderr, "%s\n\n",
Expand Down Expand Up @@ -267,13 +274,12 @@ func apiVerboseLog() api.ClientOption {
return api.VerboseLog(colorable.NewColorable(os.Stderr), logTraffic, colorize)
}

// Suggest to `brew upgrade gh` only if gh was found under homebrew prefix and when the release was
// published over 24h ago, allowing homebrew-core ample time to merge the formula bump.
func suggestBrewUpgrade(rel *update.ReleaseInfo, ghBinary string) bool {
if rel.PublishedAt.IsZero() || time.Since(rel.PublishedAt) < time.Duration(time.Hour*24) {
return false
}
func isRecentRelease(publishedAt time.Time) bool {
return !publishedAt.IsZero() && time.Since(publishedAt) < time.Hour*24
}

// Check whether the gh binary was found under the Homebrew prefix
func isUnderHomebrew(ghBinary string) bool {
brewExe, err := safeexec.LookPath("brew")
if err != nil {
return false
Expand Down
1 change: 1 addition & 0 deletions git/fixtures/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.git/COMMIT_EDITMSG
1 change: 1 addition & 0 deletions git/fixtures/simple.git/HEAD
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
ref: refs/heads/main
9 changes: 9 additions & 0 deletions git/fixtures/simple.git/config
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[core]
repositoryformatversion = 0
filemode = true
;bare = true
ignorecase = true
precomposeunicode = true
[user]
name = Mona the Cat
email = monalisa@github.com
Binary file added git/fixtures/simple.git/index
Binary file not shown.
2 changes: 2 additions & 0 deletions git/fixtures/simple.git/logs/HEAD
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
0000000000000000000000000000000000000000 d1e0abfb7d158ed544a202a6958c62d4fc22e12f Mona the Cat <monalisa@github.com> 1614174263 +0100 commit (initial): Initial commit
d1e0abfb7d158ed544a202a6958c62d4fc22e12f 6f1a2405cace1633d89a79c74c65f22fe78f9659 Mona the Cat <monalisa@github.com> 1614174275 +0100 commit: Second commit
2 changes: 2 additions & 0 deletions git/fixtures/simple.git/logs/refs/heads/main
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
0000000000000000000000000000000000000000 d1e0abfb7d158ed544a202a6958c62d4fc22e12f Mona the Cat <monalisa@github.com> 1614174263 +0100 commit (initial): Initial commit
d1e0abfb7d158ed544a202a6958c62d4fc22e12f 6f1a2405cace1633d89a79c74c65f22fe78f9659 Mona the Cat <monalisa@github.com> 1614174275 +0100 commit: Second commit
Binary file not shown.
Binary file not shown.
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
x�NK
�0t�S�� ILc
"�+�@���M�뢷7"^@�� �b�Z�xF��h���b轴;�l��K����r�3<��3��3�Kc#-��"�k8�Z.��2�d�=�^*)ES�&�iq��ɏ��i��ϋP�j��A�y��3*H/
Expand Down
1 change: 1 addition & 0 deletions git/fixtures/simple.git/refs/heads/main
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
6f1a2405cace1633d89a79c74c65f22fe78f9659
35 changes: 11 additions & 24 deletions git/git.go
Original file line number Diff line number Diff line change
Expand Up @@ -180,43 +180,30 @@ func Commits(baseRef, headRef string) ([]*Commit, error) {
return commits, nil
}

func LastCommit() (*Commit, error) {
logCmd, err := GitCommand("-c", "log.ShowSignature=false", "log", "--pretty=format:%H,%s", "-1")
func lookupCommit(sha, format string) ([]byte, error) {
logCmd, err := GitCommand("-c", "log.ShowSignature=false", "show", "-s", "--pretty=format:"+format, sha)
if err != nil {
return nil, err
}
return run.PrepareCmd(logCmd).Output()
}

output, err := run.PrepareCmd(logCmd).Output()
func LastCommit() (*Commit, error) {
output, err := lookupCommit("HEAD", "%H,%s")
if err != nil {
return nil, err
}

lines := outputLines(output)
if len(lines) != 1 {
return nil, ErrNotOnAnyBranch
}

split := strings.SplitN(lines[0], ",", 2)
if len(split) != 2 {
return nil, ErrNotOnAnyBranch
}

idx := bytes.IndexByte(output, ',')
return &Commit{
Sha: split[0],
Title: split[1],
Sha: string(output[0:idx]),
Title: strings.TrimSpace(string(output[idx+1:])),
}, nil
}

func CommitBody(sha string) (string, error) {
showCmd, err := GitCommand("-c", "log.ShowSignature=false", "show", "-s", "--pretty=format:%b", sha)
if err != nil {
return "", err
}
output, err := run.PrepareCmd(showCmd).Output()
if err != nil {
return "", err
}
return string(output), nil
output, err := lookupCommit(sha, "%b")
return string(output), err
}

// Push publishes a git ref to a remote and sets up upstream configuration
Expand Down
41 changes: 41 additions & 0 deletions git/git_test.go
Original file line number Diff line number Diff line change
@@ -1,12 +1,53 @@
package git

import (
"os"
"reflect"
"testing"

"github.com/cli/cli/internal/run"
)

func setGitDir(t *testing.T, dir string) {
// TODO: also set XDG_CONFIG_HOME, GIT_CONFIG_NOSYSTEM
old_GIT_DIR := os.Getenv("GIT_DIR")
os.Setenv("GIT_DIR", dir)
t.Cleanup(func() {
os.Setenv("GIT_DIR", old_GIT_DIR)
})
}

func TestLastCommit(t *testing.T) {
setGitDir(t, "./fixtures/simple.git")
c, err := LastCommit()
if err != nil {
t.Fatalf("LastCommit error: %v", err)
}
if c.Sha != "6f1a2405cace1633d89a79c74c65f22fe78f9659" {
t.Errorf("expected sha %q, got %q", "6f1a2405cace1633d89a79c74c65f22fe78f9659", c.Sha)
}
if c.Title != "Second commit" {
t.Errorf("expected title %q, got %q", "Second commit", c.Title)
}
}

func TestCommitBody(t *testing.T) {
setGitDir(t, "./fixtures/simple.git")
body, err := CommitBody("6f1a2405cace1633d89a79c74c65f22fe78f9659")
if err != nil {
t.Fatalf("CommitBody error: %v", err)
}
if body != "I'm starting to get the hang of things\n" {
t.Errorf("expected %q, got %q", "I'm starting to get the hang of things\n", body)
}
}

/*
NOTE: below this are stubbed git tests, i.e. those that do not actually invoke `git`. If possible, utilize
`setGitDir()` to allow new tests to interact with `git`. For write operations, you can use `t.TempDir()` to
host a temporary git repository that is safe to be changed.
*/

func Test_UncommittedChangeCount(t *testing.T) {
type c struct {
Label string
Expand Down
7 changes: 7 additions & 0 deletions pkg/cmd/api/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,10 @@ import (
"strconv"
"strings"
"syscall"
"time"

"github.com/MakeNowJust/heredoc"
"github.com/cli/cli/api"
"github.com/cli/cli/internal/ghinstance"
"github.com/cli/cli/internal/ghrepo"
"github.com/cli/cli/pkg/cmdutil"
Expand All @@ -38,6 +40,7 @@ type ApiOptions struct {
ShowResponseHeaders bool
Paginate bool
Silent bool
CacheTTL time.Duration

HttpClient func() (*http.Client, error)
BaseRepo func() (ghrepo.Interface, error)
Expand Down Expand Up @@ -176,6 +179,7 @@ func NewCmdApi(f *cmdutil.Factory, runF func(*ApiOptions) error) *cobra.Command
cmd.Flags().BoolVar(&opts.Paginate, "paginate", false, "Make additional HTTP requests to fetch all pages of results")
cmd.Flags().StringVar(&opts.RequestInputFile, "input", "", "The `file` to use as body for the HTTP request")
cmd.Flags().BoolVar(&opts.Silent, "silent", false, "Do not print the response body")
cmd.Flags().DurationVar(&opts.CacheTTL, "cache", 0, "Cache the response, e.g. \"3600s\", \"60m\", \"1h\"")
return cmd
}

Expand Down Expand Up @@ -219,6 +223,9 @@ func apiRun(opts *ApiOptions) error {
if err != nil {
return err
}
if opts.CacheTTL > 0 {
httpClient = api.NewCachedClient(httpClient, opts.CacheTTL)
}

headersOutputStream := opts.IO.Out
if opts.Silent {
Expand Down
Loading

0 comments on commit dd34cae

Please sign in to comment.