Merge remote-tracking branch 'origin' into gh-search-code

This commit is contained in:
Mislav Marohnić 2023-05-10 13:22:11 +02:00
commit 8eb4d1e2eb
No known key found for this signature in database
23 changed files with 784 additions and 372 deletions

View file

@ -5,6 +5,7 @@ import (
"errors"
"fmt"
"strings"
"sync/atomic"
"time"
"github.com/AlecAivazis/survey/v2"
@ -176,7 +177,8 @@ func (a *App) Delete(ctx context.Context, opts deleteOptions) (err error) {
progressLabel = "Deleting codespaces"
}
return a.RunWithProgress(progressLabel, func() error {
var deletedCodespaces uint32
err = a.RunWithProgress(progressLabel, func() error {
var g errgroup.Group
for _, c := range codespacesToDelete {
codespaceName := c.Name
@ -185,15 +187,23 @@ func (a *App) Delete(ctx context.Context, opts deleteOptions) (err error) {
a.errLogger.Printf("error deleting codespace %q: %v\n", codespaceName, err)
return err
}
atomic.AddUint32(&deletedCodespaces, 1)
return nil
})
}
if err := g.Wait(); err != nil {
return errors.New("some codespaces failed to delete")
return fmt.Errorf("%d codespace(s) failed to delete", len(codespacesToDelete)-int(deletedCodespaces))
}
return nil
})
if a.io.IsStdoutTTY() && deletedCodespaces > 0 {
successMsg := fmt.Sprintf("%d codespace(s) deleted successfully\n", deletedCodespaces)
fmt.Fprint(a.io.ErrOut, successMsg)
}
return err
}
func confirmDeletion(p prompter, apiCodespace *api.Codespace, isInteractive bool) (bool, error) {

View file

@ -26,7 +26,7 @@ func TestDelete(t *testing.T) {
codespaces []*api.Codespace
confirms map[string]bool
deleteErr error
wantErr bool
wantErr string
wantDeleted []string
wantStdout string
wantStderr string
@ -42,7 +42,7 @@ func TestDelete(t *testing.T) {
},
},
wantDeleted: []string{"hubot-robawt-abc"},
wantStdout: "",
wantStderr: "1 codespace(s) deleted successfully\n",
},
{
name: "by repo",
@ -70,7 +70,7 @@ func TestDelete(t *testing.T) {
},
},
wantDeleted: []string{"monalisa-spoonknife-123", "monalisa-spoonknife-c4f3"},
wantStdout: "",
wantStderr: "2 codespace(s) deleted successfully\n",
},
{
name: "unused",
@ -93,7 +93,7 @@ func TestDelete(t *testing.T) {
},
},
wantDeleted: []string{"hubot-robawt-abc", "monalisa-spoonknife-c4f3"},
wantStdout: "",
wantStderr: "2 codespace(s) deleted successfully\n",
},
{
name: "deletion failed",
@ -109,12 +109,13 @@ func TestDelete(t *testing.T) {
},
},
deleteErr: errors.New("aborted by test"),
wantErr: true,
wantErr: "2 codespace(s) failed to delete",
wantDeleted: []string{"hubot-robawt-abc", "monalisa-spoonknife-123"},
wantStderr: heredoc.Doc(`
error deleting codespace "hubot-robawt-abc": aborted by test
error deleting codespace "monalisa-spoonknife-123": aborted by test
`),
wantStdout: "",
},
{
name: "with confirm",
@ -149,7 +150,7 @@ func TestDelete(t *testing.T) {
"Codespace hubot-robawt-abc has unsaved changes. OK to delete?": true,
},
wantDeleted: []string{"hubot-robawt-abc", "monalisa-spoonknife-c4f3"},
wantStdout: "",
wantStderr: "2 codespace(s) deleted successfully\n",
},
{
name: "deletion for org codespace by admin succeeds",
@ -174,7 +175,7 @@ func TestDelete(t *testing.T) {
},
},
wantDeleted: []string{"monalisa-spoonknife-123"},
wantStdout: "",
wantStderr: "1 codespace(s) deleted successfully\n",
},
{
name: "deletion for org codespace by admin fails for codespace not found",
@ -200,7 +201,8 @@ func TestDelete(t *testing.T) {
},
wantDeleted: []string{},
wantStdout: "",
wantErr: true,
wantErr: "error fetching codespace information: " +
"codespace not found for user johnDoe with name monalisa-spoonknife-123",
},
{
name: "deletion for org codespace succeeds without username",
@ -215,7 +217,7 @@ func TestDelete(t *testing.T) {
},
},
wantDeleted: []string{"monalisa-spoonknife-123"},
wantStdout: "",
wantStderr: "1 codespace(s) deleted successfully\n",
},
{
name: "by repo owner",
@ -253,6 +255,7 @@ func TestDelete(t *testing.T) {
},
},
wantDeleted: []string{"octocat-spoonknife-123", "octocat-spoonknife-c4f3"},
wantStderr: "2 codespace(s) deleted successfully\n",
wantStdout: "",
},
}
@ -306,8 +309,8 @@ func TestDelete(t *testing.T) {
ios.SetStdoutTTY(true)
app := NewApp(ios, nil, apiMock, nil, nil)
err := app.Delete(context.Background(), opts)
if (err != nil) != tt.wantErr {
t.Errorf("delete() error = %v, wantErr %v", err, tt.wantErr)
if (err != nil) && tt.wantErr != err.Error() {
t.Errorf("delete() error = %v, wantErr = %v", err, tt.wantErr)
}
for _, listArgs := range apiMock.ListCodespacesCalls() {
if listArgs.Opts.OrgName != "" && listArgs.Opts.UserName == "" {

View file

@ -15,7 +15,8 @@
"headRepositoryOwner": {
"login": "OWNER"
},
"isCrossRepository": false
"isCrossRepository": false,
"autoMergeRequest": null
}
}
]
@ -31,7 +32,8 @@
"state": "OPEN",
"url": "https://github.com/cli/cli/pull/8",
"headRefName": "strawberries",
"isDraft": false
"isDraft": false,
"autoMergeRequest": null
}
}
]
@ -46,7 +48,17 @@
"state": "OPEN",
"url": "https://github.com/cli/cli/pull/9",
"headRefName": "apples",
"isDraft": false
"isDraft": false,
"autoMergeRequest": {
"authorEmail": null,
"commitBody": null,
"commitHeadline": null,
"mergeMethod": "SQUASH",
"enabledAt": "2020-08-27T19:00:12Z",
"enabledBy": {
"login": "hubot"
}
}
} }, {
"node": {
"number": 11,
@ -54,7 +66,8 @@
"state": "OPEN",
"url": "https://github.com/cli/cli/pull/1",
"headRefName": "figs",
"isDraft": true
"isDraft": true,
"autoMergeRequest": null
}
}
]

View file

@ -191,7 +191,7 @@ func pullRequestFragment(hostname string, conflictStatus bool) (string, error) {
fields := []string{
"number", "title", "state", "url", "isDraft", "isCrossRepository",
"headRefName", "headRepositoryOwner", "mergeStateStatus",
"statusCheckRollup", "requiresStrictStatusChecks",
"statusCheckRollup", "requiresStrictStatusChecks", "autoMergeRequest",
}
if conflictStatus {

View file

@ -284,6 +284,10 @@ func printPrs(io *iostreams.IOStreams, totalCount int, prs ...api.PullRequest) {
}
}
if pr.AutoMergeRequest != nil {
fmt.Fprintf(w, " %s", cs.Green("✓ Auto-merge enabled"))
}
} else {
fmt.Fprintf(w, " - %s", shared.StateTitleWithColor(cs, pr))
}

View file

@ -91,7 +91,7 @@ func TestPRStatus(t *testing.T) {
expectedPrs := []*regexp.Regexp{
regexp.MustCompile(`#8.*\[strawberries\]`),
regexp.MustCompile(`#9.*\[apples\]`),
regexp.MustCompile(`#9.*\[apples\].*✓ Auto-merge enabled`),
regexp.MustCompile(`#10.*\[blueberries\]`),
regexp.MustCompile(`#11.*\[figs\]`),
}

View file

@ -0,0 +1,55 @@
{
"data": {
"repository": {
"pullRequest": {
"number": 12,
"title": "Blueberries are from a fork",
"state": "OPEN",
"body": "**blueberries taste good**",
"url": "https://github.com/OWNER/REPO/pull/12",
"author": {
"login": "nobody"
},
"autoMergeRequest": {
"authorEmail": null,
"commitBody": null,
"commitHeadline": null,
"mergeMethod": "SQUASH",
"enabledAt": "2020-08-27T19:00:12Z",
"enabledBy": {
"login": "hubot"
}
},
"additions": 100,
"deletions": 10,
"reviewRequests": {
"nodes": [],
"totalcount": 0
},
"assignees": {
"nodes": [],
"totalcount": 0
},
"labels": {
"nodes": [],
"totalcount": 0
},
"projectcards": {
"nodes": [],
"totalcount": 0
},
"milestone": {},
"commits": {
"totalCount": 12
},
"baseRefName": "master",
"headRefName": "blueberries",
"headRepositoryOwner": {
"login": "hubot"
},
"isCrossRepository": true,
"isDraft": false
}
}
}
}

View file

@ -77,7 +77,7 @@ func NewCmdView(f *cmdutil.Factory, runF func(*ViewOptions) error) *cobra.Comman
}
var defaultFields = []string{
"url", "number", "title", "state", "body", "author",
"url", "number", "title", "state", "body", "author", "autoMergeRequest",
"isDraft", "maintainerCanModify", "mergeable", "additions", "deletions", "commitsCount",
"baseRefName", "headRefName", "headRepositoryOwner", "headRepository", "isCrossRepository",
"reviewRequests", "reviews", "assignees", "labels", "projectCards", "milestone",
@ -157,6 +157,15 @@ func printRawPrPreview(io *iostreams.IOStreams, pr *api.PullRequest) error {
fmt.Fprintf(out, "url:\t%s\n", pr.URL)
fmt.Fprintf(out, "additions:\t%s\n", cs.Green(strconv.Itoa(pr.Additions)))
fmt.Fprintf(out, "deletions:\t%s\n", cs.Red(strconv.Itoa(pr.Deletions)))
var autoMerge string
if pr.AutoMergeRequest == nil {
autoMerge = "disabled"
} else {
autoMerge = fmt.Sprintf("enabled\t%s\t%s",
pr.AutoMergeRequest.EnabledBy.Login,
strings.ToLower(pr.AutoMergeRequest.MergeMethod))
}
fmt.Fprintf(out, "auto-merge:\t%s\n", autoMerge)
fmt.Fprintln(out, "--")
fmt.Fprintln(out, pr.Body)
@ -223,6 +232,29 @@ func printHumanPrPreview(opts *ViewOptions, pr *api.PullRequest) error {
fmt.Fprintln(out, pr.Milestone.Title)
}
// Auto-Merge status
autoMerge := pr.AutoMergeRequest
if autoMerge != nil {
var mergeMethod string
switch autoMerge.MergeMethod {
case "MERGE":
mergeMethod = "a merge commit"
case "REBASE":
mergeMethod = "rebase and merge"
case "SQUASH":
mergeMethod = "squash and merge"
default:
mergeMethod = fmt.Sprintf("an unknown merge method (%s)", autoMerge.MergeMethod)
}
fmt.Fprintf(out,
"%s %s by %s, using %s\n",
cs.Bold("Auto-merge:"),
cs.Green("enabled"),
autoMerge.EnabledBy.Login,
mergeMethod,
)
}
// Body
var md string
var err error

View file

@ -314,6 +314,25 @@ func TestPRView_Preview_nontty(t *testing.T) {
`\*\*blueberries taste good\*\*`,
},
},
"PR with auto-merge enabled": {
branch: "master",
args: "12",
fixtures: map[string]string{
"PullRequestByNumber": "./fixtures/prViewPreviewWithAutoMergeEnabled.json",
},
expectedOutputs: []string{
`title:\tBlueberries are from a fork\n`,
`state:\tOPEN\n`,
`author:\tnobody\n`,
`labels:\t\n`,
`assignees:\t\n`,
`projects:\t\n`,
`milestone:\t\n`,
`additions:\t100\n`,
`deletions:\t10\n`,
`auto-merge:\tenabled\thubot\tsquash\n`,
},
},
}
for name, tc := range tests {
@ -504,6 +523,20 @@ func TestPRView_Preview(t *testing.T) {
`View this pull request on GitHub: https://github.com/OWNER/REPO/pull/12`,
},
},
"PR with auto-merge enabled": {
branch: "master",
args: "12",
fixtures: map[string]string{
"PullRequestByNumber": "./fixtures/prViewPreviewWithAutoMergeEnabled.json",
},
expectedOutputs: []string{
`Blueberries are from a fork #12\n`,
`Open.*nobody wants to merge 12 commits into master from blueberries . about X years ago`,
`Auto-merge:.*enabled.* by hubot, using squash and merge`,
`blueberries taste good`,
`View this pull request on GitHub: https://github.com/OWNER/REPO/pull/12`,
},
},
}
for name, tc := range tests {