Merge branch 'master' into reviewers-in-pr-view

This commit is contained in:
Toshiya Doi 2020-04-22 22:00:02 +09:00
commit 1ce09ff758
36 changed files with 1287 additions and 311 deletions

112
command/config.go Normal file
View file

@ -0,0 +1,112 @@
package command
import (
"fmt"
"github.com/spf13/cobra"
)
func init() {
RootCmd.AddCommand(configCmd)
configCmd.AddCommand(configGetCmd)
configCmd.AddCommand(configSetCmd)
configGetCmd.Flags().StringP("host", "h", "", "Get per-host setting")
configSetCmd.Flags().StringP("host", "h", "", "Set per-host setting")
// TODO reveal and add usage once we properly support multiple hosts
_ = configGetCmd.Flags().MarkHidden("host")
// TODO reveal and add usage once we properly support multiple hosts
_ = configSetCmd.Flags().MarkHidden("host")
}
var configCmd = &cobra.Command{
Use: "config",
Short: "Set and get gh settings",
Long: `Get and set key/value strings.
Current respected settings:
- git_protocol: https or ssh. Default is https.
- editor: if unset, defaults to environment variables.
`,
}
var configGetCmd = &cobra.Command{
Use: "get <key>",
Short: "Prints the value of a given configuration key.",
Long: `Get the value for a given configuration key.
Examples:
$ gh config get git_protocol
https
`,
Args: cobra.ExactArgs(1),
RunE: configGet,
}
var configSetCmd = &cobra.Command{
Use: "set <key> <value>",
Short: "Updates configuration with the value of a given key.",
Long: `Update the configuration by setting a key to a value.
Examples:
$ gh config set editor vim
`,
Args: cobra.ExactArgs(2),
RunE: configSet,
}
func configGet(cmd *cobra.Command, args []string) error {
key := args[0]
hostname, err := cmd.Flags().GetString("host")
if err != nil {
return err
}
ctx := contextForCommand(cmd)
cfg, err := ctx.Config()
if err != nil {
return err
}
val, err := cfg.Get(hostname, key)
if err != nil {
return err
}
if val != "" {
out := colorableOut(cmd)
fmt.Fprintf(out, "%s\n", val)
}
return nil
}
func configSet(cmd *cobra.Command, args []string) error {
key := args[0]
value := args[1]
hostname, err := cmd.Flags().GetString("host")
if err != nil {
return err
}
ctx := contextForCommand(cmd)
cfg, err := ctx.Config()
if err != nil {
return err
}
err = cfg.Set(hostname, key, value)
if err != nil {
return fmt.Errorf("failed to set %q to %q: %w", key, value, err)
}
err = cfg.Write()
if err != nil {
return fmt.Errorf("failed to write config to disk: %w", err)
}
return nil
}

191
command/config_test.go Normal file
View file

@ -0,0 +1,191 @@
package command
import (
"bytes"
"testing"
"github.com/cli/cli/internal/config"
)
func TestConfigGet(t *testing.T) {
cfg := `---
hosts:
github.com:
user: OWNER
oauth_token: MUSTBEHIGHCUZIMATOKEN
editor: ed
`
initBlankContext(cfg, "OWNER/REPO", "master")
output, err := RunCommand(configGetCmd, "config get editor")
if err != nil {
t.Fatalf("error running command `config get editor`: %v", err)
}
eq(t, output.String(), "ed\n")
}
func TestConfigGet_default(t *testing.T) {
initBlankContext("", "OWNER/REPO", "master")
output, err := RunCommand(configGetCmd, "config get git_protocol")
if err != nil {
t.Fatalf("error running command `config get git_protocol`: %v", err)
}
eq(t, output.String(), "https\n")
}
func TestConfigGet_not_found(t *testing.T) {
initBlankContext("", "OWNER/REPO", "master")
output, err := RunCommand(configGetCmd, "config get missing")
if err != nil {
t.Fatalf("error running command `config get missing`: %v", err)
}
eq(t, output.String(), "")
}
func TestConfigSet(t *testing.T) {
initBlankContext("", "OWNER/REPO", "master")
buf := bytes.NewBufferString("")
defer config.StubWriteConfig(buf)()
output, err := RunCommand(configSetCmd, "config set editor ed")
if err != nil {
t.Fatalf("error running command `config set editor ed`: %v", err)
}
eq(t, output.String(), "")
expected := `hosts:
github.com:
user: OWNER
oauth_token: 1234567890
editor: ed
`
eq(t, buf.String(), expected)
}
func TestConfigSet_update(t *testing.T) {
cfg := `---
hosts:
github.com:
user: OWNER
oauth_token: MUSTBEHIGHCUZIMATOKEN
editor: ed
`
initBlankContext(cfg, "OWNER/REPO", "master")
buf := bytes.NewBufferString("")
defer config.StubWriteConfig(buf)()
output, err := RunCommand(configSetCmd, "config set editor vim")
if err != nil {
t.Fatalf("error running command `config get editor`: %v", err)
}
eq(t, output.String(), "")
expected := `hosts:
github.com:
user: OWNER
oauth_token: MUSTBEHIGHCUZIMATOKEN
editor: vim
`
eq(t, buf.String(), expected)
}
func TestConfigGetHost(t *testing.T) {
cfg := `---
hosts:
github.com:
git_protocol: ssh
user: OWNER
oauth_token: MUSTBEHIGHCUZIMATOKEN
editor: ed
git_protocol: https
`
initBlankContext(cfg, "OWNER/REPO", "master")
output, err := RunCommand(configGetCmd, "config get -hgithub.com git_protocol")
if err != nil {
t.Fatalf("error running command `config get editor`: %v", err)
}
eq(t, output.String(), "ssh\n")
}
func TestConfigGetHost_unset(t *testing.T) {
cfg := `---
hosts:
github.com:
user: OWNER
oauth_token: MUSTBEHIGHCUZIMATOKEN
editor: ed
git_protocol: ssh
`
initBlankContext(cfg, "OWNER/REPO", "master")
output, err := RunCommand(configGetCmd, "config get -hgithub.com git_protocol")
if err != nil {
t.Fatalf("error running command `config get -hgithub.com git_protocol`: %v", err)
}
eq(t, output.String(), "ssh\n")
}
func TestConfigSetHost(t *testing.T) {
initBlankContext("", "OWNER/REPO", "master")
buf := bytes.NewBufferString("")
defer config.StubWriteConfig(buf)()
output, err := RunCommand(configSetCmd, "config set -hgithub.com git_protocol ssh")
if err != nil {
t.Fatalf("error running command `config set editor ed`: %v", err)
}
eq(t, output.String(), "")
expected := `hosts:
github.com:
user: OWNER
oauth_token: 1234567890
git_protocol: ssh
`
eq(t, buf.String(), expected)
}
func TestConfigSetHost_update(t *testing.T) {
cfg := `---
hosts:
github.com:
git_protocol: ssh
user: OWNER
oauth_token: MUSTBEHIGHCUZIMATOKEN
`
initBlankContext(cfg, "OWNER/REPO", "master")
buf := bytes.NewBufferString("")
defer config.StubWriteConfig(buf)()
output, err := RunCommand(configSetCmd, "config set -hgithub.com git_protocol https")
if err != nil {
t.Fatalf("error running command `config get editor`: %v", err)
}
eq(t, output.String(), "")
expected := `hosts:
github.com:
git_protocol: https
user: OWNER
oauth_token: MUSTBEHIGHCUZIMATOKEN
`
eq(t, buf.String(), expected)
}

View file

@ -259,8 +259,9 @@ func printIssuePreview(out io.Writer, issue *api.Issue) error {
now := time.Now()
ago := now.Sub(issue.CreatedAt)
// Header (Title and State)
fmt.Fprintln(out, utils.Bold(issue.Title))
fmt.Fprintf(out, "%s", issueStateTitleWithColor(issue.State))
fmt.Fprint(out, issueStateTitleWithColor(issue.State))
fmt.Fprintln(out, utils.Gray(fmt.Sprintf(
" • %s opened %s • %s",
issue.Author.Login,
@ -268,6 +269,26 @@ func printIssuePreview(out io.Writer, issue *api.Issue) error {
utils.Pluralize(issue.Comments.TotalCount, "comment"),
)))
// Metadata
fmt.Fprintln(out)
if assignees := issueAssigneeList(*issue); assignees != "" {
fmt.Fprint(out, utils.Bold("Assignees: "))
fmt.Fprintln(out, assignees)
}
if labels := issueLabelList(*issue); labels != "" {
fmt.Fprint(out, utils.Bold("Labels: "))
fmt.Fprintln(out, labels)
}
if projects := issueProjectList(*issue); projects != "" {
fmt.Fprint(out, utils.Bold("Projects: "))
fmt.Fprintln(out, projects)
}
if issue.Milestone.Title != "" {
fmt.Fprint(out, utils.Bold("Milestone: "))
fmt.Fprintln(out, issue.Milestone.Title)
}
// Body
if issue.Body != "" {
fmt.Fprintln(out)
md, err := utils.RenderMarkdown(issue.Body)
@ -275,9 +296,10 @@ func printIssuePreview(out io.Writer, issue *api.Issue) error {
return err
}
fmt.Fprintln(out, md)
fmt.Fprintln(out)
}
fmt.Fprintln(out)
// Footer
fmt.Fprintf(out, utils.Gray("View this issue on GitHub: %s\n"), issue.URL)
return nil
}
@ -422,7 +444,7 @@ func printIssues(w io.Writer, prefix string, totalCount int, issues []api.Issue)
issueNum = "#" + issueNum
}
issueNum = prefix + issueNum
labels := labelList(issue)
labels := issueLabelList(issue)
if labels != "" && table.IsTTY() {
labels = fmt.Sprintf("(%s)", labels)
}
@ -441,7 +463,24 @@ func printIssues(w io.Writer, prefix string, totalCount int, issues []api.Issue)
}
}
func labelList(issue api.Issue) string {
func issueAssigneeList(issue api.Issue) string {
if len(issue.Assignees.Nodes) == 0 {
return ""
}
AssigneeNames := make([]string, 0, len(issue.Assignees.Nodes))
for _, assignee := range issue.Assignees.Nodes {
AssigneeNames = append(AssigneeNames, assignee.Login)
}
list := strings.Join(AssigneeNames, ", ")
if issue.Assignees.TotalCount > len(issue.Assignees.Nodes) {
list += ", …"
}
return list
}
func issueLabelList(issue api.Issue) string {
if len(issue.Labels.Nodes) == 0 {
return ""
}
@ -458,6 +497,23 @@ func labelList(issue api.Issue) string {
return list
}
func issueProjectList(issue api.Issue) string {
if len(issue.ProjectCards.Nodes) == 0 {
return ""
}
projectNames := make([]string, 0, len(issue.ProjectCards.Nodes))
for _, project := range issue.ProjectCards.Nodes {
projectNames = append(projectNames, fmt.Sprintf("%s (%s)", project.Project.Name, project.Column.Name))
}
list := strings.Join(projectNames, ", ")
if issue.ProjectCards.TotalCount > len(issue.ProjectCards.Nodes) {
list += ", …"
}
return list
}
func displayURL(urlStr string) string {
u, err := url.Parse(urlStr)
if err != nil {

View file

@ -16,7 +16,7 @@ import (
)
func TestIssueStatus(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -45,7 +45,7 @@ func TestIssueStatus(t *testing.T) {
}
func TestIssueStatus_blankSlate(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -82,7 +82,7 @@ Issues opened by you
}
func TestIssueStatus_disabledIssues(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -99,7 +99,7 @@ func TestIssueStatus_disabledIssues(t *testing.T) {
}
func TestIssueList(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -132,7 +132,7 @@ Showing 3 of 3 issues in OWNER/REPO
}
func TestIssueList_withFlags(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -172,7 +172,7 @@ No issues match your search in OWNER/REPO
}
func TestIssueList_nullAssigneeLabels(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -201,7 +201,7 @@ func TestIssueList_nullAssigneeLabels(t *testing.T) {
}
func TestIssueList_disabledIssues(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -218,7 +218,7 @@ func TestIssueList_disabledIssues(t *testing.T) {
}
func TestIssueView_web(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -252,7 +252,7 @@ func TestIssueView_web(t *testing.T) {
}
func TestIssueView_web_numberArgWithHash(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -292,26 +292,30 @@ func TestIssueView_Preview(t *testing.T) {
fixture string
expectedOutputs []string
}{
"Open issue": {
"Open issue without metadata": {
ownerRepo: "master",
command: "issue view 123",
fixture: "../test/fixtures/issueView_preview.json",
expectedOutputs: []string{
"ix of coins",
"Open • marseilles opened about 292 years ago • 9 comments",
"bold story",
"View this issue on GitHub: https://github.com/OWNER/REPO/issues/123",
`ix of coins`,
`Open • marseilles opened about 292 years ago • 9 comments`,
`bold story`,
`View this issue on GitHub: https://github.com/OWNER/REPO/issues/123`,
},
},
"Open issue with no label": {
"Open issue with metadata": {
ownerRepo: "master",
command: "issue view 123",
fixture: "../test/fixtures/issueView_previewNoLabel.json",
fixture: "../test/fixtures/issueView_previewWithMetadata.json",
expectedOutputs: []string{
"ix of coins",
"Open • marseilles opened about 292 years ago • 9 comments",
"bold story",
"View this issue on GitHub: https://github.com/OWNER/REPO/issues/123",
`ix of coins`,
`Open • marseilles opened about 292 years ago • 9 comments`,
`Assignees: marseilles, monaco\n`,
`Labels: one, two, three, four, five\n`,
`Projects: Project 1 \(column A\), Project 2 \(column B\), Project 3 \(column C\)\n`,
`Milestone: uluru\n`,
`bold story`,
`View this issue on GitHub: https://github.com/OWNER/REPO/issues/123`,
},
},
"Open issue with empty body": {
@ -319,9 +323,9 @@ func TestIssueView_Preview(t *testing.T) {
command: "issue view 123",
fixture: "../test/fixtures/issueView_previewWithEmptyBody.json",
expectedOutputs: []string{
"ix of coins",
"Open • marseilles opened about 292 years ago • 9 comments",
"View this issue on GitHub: https://github.com/OWNER/REPO/issues/123",
`ix of coins`,
`Open • marseilles opened about 292 years ago • 9 comments`,
`View this issue on GitHub: https://github.com/OWNER/REPO/issues/123`,
},
},
"Closed issue": {
@ -329,16 +333,16 @@ func TestIssueView_Preview(t *testing.T) {
command: "issue view 123",
fixture: "../test/fixtures/issueView_previewClosedState.json",
expectedOutputs: []string{
"ix of coins",
"Closed • marseilles opened about 292 years ago • 9 comments",
"bold story",
"View this issue on GitHub: https://github.com/OWNER/REPO/issues/123",
`ix of coins`,
`Closed • marseilles opened about 292 years ago • 9 comments`,
`bold story`,
`View this issue on GitHub: https://github.com/OWNER/REPO/issues/123`,
},
},
}
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
initBlankContext("OWNER/REPO", tc.ownerRepo)
initBlankContext("", "OWNER/REPO", tc.ownerRepo)
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -359,7 +363,7 @@ func TestIssueView_Preview(t *testing.T) {
}
func TestIssueView_web_notFound(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubResponse(200, bytes.NewBufferString(`
@ -386,7 +390,7 @@ func TestIssueView_web_notFound(t *testing.T) {
}
func TestIssueView_disabledIssues(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -404,7 +408,7 @@ func TestIssueView_disabledIssues(t *testing.T) {
}
func TestIssueView_web_urlArg(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -437,7 +441,7 @@ func TestIssueView_web_urlArg(t *testing.T) {
}
func TestIssueCreate(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -478,7 +482,7 @@ func TestIssueCreate(t *testing.T) {
}
func TestIssueCreate_disabledIssues(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -496,7 +500,7 @@ func TestIssueCreate_disabledIssues(t *testing.T) {
}
func TestIssueCreate_web(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -522,7 +526,7 @@ func TestIssueCreate_web(t *testing.T) {
}
func TestIssueCreate_webTitleBody(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")

View file

@ -13,7 +13,7 @@ import (
)
func TestPRCreate(t *testing.T) {
initBlankContext("OWNER/REPO", "feature")
initBlankContext("", "OWNER/REPO", "feature")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
http.StubResponse(200, bytes.NewBufferString(`
@ -66,7 +66,7 @@ func TestPRCreate(t *testing.T) {
}
func TestPRCreate_withForking(t *testing.T) {
initBlankContext("OWNER/REPO", "feature")
initBlankContext("", "OWNER/REPO", "feature")
http := initFakeHTTP()
http.StubRepoResponseWithPermission("OWNER", "REPO", "READ")
http.StubResponse(200, bytes.NewBufferString(`
@ -109,7 +109,7 @@ func TestPRCreate_withForking(t *testing.T) {
}
func TestPRCreate_alreadyExists(t *testing.T) {
initBlankContext("OWNER/REPO", "feature")
initBlankContext("", "OWNER/REPO", "feature")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
http.StubResponse(200, bytes.NewBufferString(`
@ -142,7 +142,7 @@ func TestPRCreate_alreadyExists(t *testing.T) {
}
func TestPRCreate_alreadyExistsDifferentBase(t *testing.T) {
initBlankContext("OWNER/REPO", "feature")
initBlankContext("", "OWNER/REPO", "feature")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
http.StubResponse(200, bytes.NewBufferString(`
@ -174,7 +174,7 @@ func TestPRCreate_alreadyExistsDifferentBase(t *testing.T) {
}
func TestPRCreate_web(t *testing.T) {
initBlankContext("OWNER/REPO", "feature")
initBlankContext("", "OWNER/REPO", "feature")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
http.StubResponse(200, bytes.NewBufferString(`
@ -205,7 +205,7 @@ func TestPRCreate_web(t *testing.T) {
}
func TestPRCreate_ReportsUncommittedChanges(t *testing.T) {
initBlankContext("OWNER/REPO", "feature")
initBlankContext("", "OWNER/REPO", "feature")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -330,7 +330,7 @@ func TestPRCreate_cross_repo_same_branch(t *testing.T) {
}
func TestPRCreate_survey_defaults_multicommit(t *testing.T) {
initBlankContext("OWNER/REPO", "cool_bug-fixes")
initBlankContext("", "OWNER/REPO", "cool_bug-fixes")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
http.StubResponse(200, bytes.NewBufferString(`
@ -361,17 +361,17 @@ func TestPRCreate_survey_defaults_multicommit(t *testing.T) {
defer surveyTeardown()
as.Stub([]*QuestionStub{
&QuestionStub{
{
Name: "title",
Default: true,
},
&QuestionStub{
{
Name: "body",
Default: true,
},
})
as.Stub([]*QuestionStub{
&QuestionStub{
{
Name: "confirmation",
Value: 1,
},
@ -406,7 +406,7 @@ func TestPRCreate_survey_defaults_multicommit(t *testing.T) {
}
func TestPRCreate_survey_defaults_monocommit(t *testing.T) {
initBlankContext("OWNER/REPO", "feature")
initBlankContext("", "OWNER/REPO", "feature")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
http.StubResponse(200, bytes.NewBufferString(`
@ -438,17 +438,17 @@ func TestPRCreate_survey_defaults_monocommit(t *testing.T) {
defer surveyTeardown()
as.Stub([]*QuestionStub{
&QuestionStub{
{
Name: "title",
Default: true,
},
&QuestionStub{
{
Name: "body",
Default: true,
},
})
as.Stub([]*QuestionStub{
&QuestionStub{
{
Name: "confirmation",
Value: 1,
},
@ -483,7 +483,7 @@ func TestPRCreate_survey_defaults_monocommit(t *testing.T) {
}
func TestPRCreate_survey_autofill(t *testing.T) {
initBlankContext("OWNER/REPO", "feature")
initBlankContext("", "OWNER/REPO", "feature")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
http.StubResponse(200, bytes.NewBufferString(`
@ -541,7 +541,7 @@ func TestPRCreate_survey_autofill(t *testing.T) {
}
func TestPRCreate_defaults_error_autofill(t *testing.T) {
initBlankContext("OWNER/REPO", "feature")
initBlankContext("", "OWNER/REPO", "feature")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -559,7 +559,7 @@ func TestPRCreate_defaults_error_autofill(t *testing.T) {
}
func TestPRCreate_defaults_error_web(t *testing.T) {
initBlankContext("OWNER/REPO", "feature")
initBlankContext("", "OWNER/REPO", "feature")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -577,7 +577,7 @@ func TestPRCreate_defaults_error_web(t *testing.T) {
}
func TestPRCreate_defaults_error_interactive(t *testing.T) {
initBlankContext("OWNER/REPO", "feature")
initBlankContext("", "OWNER/REPO", "feature")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
http.StubResponse(200, bytes.NewBufferString(`
@ -605,17 +605,17 @@ func TestPRCreate_defaults_error_interactive(t *testing.T) {
defer surveyTeardown()
as.Stub([]*QuestionStub{
&QuestionStub{
{
Name: "title",
Default: true,
},
&QuestionStub{
{
Name: "body",
Value: "social distancing",
},
})
as.Stub([]*QuestionStub{
&QuestionStub{
{
Name: "confirmation",
Value: 0,
},

View file

@ -74,7 +74,7 @@ func RunCommand(cmd *cobra.Command, args string) (*cmdOut, error) {
}
func TestPRStatus(t *testing.T) {
initBlankContext("OWNER/REPO", "blueberries")
initBlankContext("", "OWNER/REPO", "blueberries")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -102,7 +102,7 @@ func TestPRStatus(t *testing.T) {
}
func TestPRStatus_fork(t *testing.T) {
initBlankContext("OWNER/REPO", "blueberries")
initBlankContext("", "OWNER/REPO", "blueberries")
http := initFakeHTTP()
http.StubForkedRepoResponse("OWNER/REPO", "PARENT/REPO")
@ -132,7 +132,7 @@ branch.blueberries.merge refs/heads/blueberries`)}
}
func TestPRStatus_reviewsAndChecks(t *testing.T) {
initBlankContext("OWNER/REPO", "blueberries")
initBlankContext("", "OWNER/REPO", "blueberries")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -159,7 +159,7 @@ func TestPRStatus_reviewsAndChecks(t *testing.T) {
}
func TestPRStatus_currentBranch_showTheMostRecentPR(t *testing.T) {
initBlankContext("OWNER/REPO", "blueberries")
initBlankContext("", "OWNER/REPO", "blueberries")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -191,7 +191,7 @@ func TestPRStatus_currentBranch_showTheMostRecentPR(t *testing.T) {
}
func TestPRStatus_currentBranch_Closed(t *testing.T) {
initBlankContext("OWNER/REPO", "blueberries")
initBlankContext("", "OWNER/REPO", "blueberries")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -212,7 +212,7 @@ func TestPRStatus_currentBranch_Closed(t *testing.T) {
}
func TestPRStatus_currentBranch_Merged(t *testing.T) {
initBlankContext("OWNER/REPO", "blueberries")
initBlankContext("", "OWNER/REPO", "blueberries")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -233,7 +233,7 @@ func TestPRStatus_currentBranch_Merged(t *testing.T) {
}
func TestPRStatus_blankSlate(t *testing.T) {
initBlankContext("OWNER/REPO", "blueberries")
initBlankContext("", "OWNER/REPO", "blueberries")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -265,7 +265,7 @@ Requesting a code review from you
}
func TestPRList(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -289,7 +289,7 @@ Showing 3 of 3 pull requests in OWNER/REPO
}
func TestPRList_filtering(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -321,7 +321,7 @@ No pull requests match your search in OWNER/REPO
}
func TestPRList_filteringRemoveDuplicate(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -341,7 +341,7 @@ func TestPRList_filteringRemoveDuplicate(t *testing.T) {
}
func TestPRList_filteringClosed(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -365,7 +365,7 @@ func TestPRList_filteringClosed(t *testing.T) {
}
func TestPRList_filteringAssignee(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -389,7 +389,7 @@ func TestPRList_filteringAssignee(t *testing.T) {
}
func TestPRList_filteringAssigneeLabels(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -531,7 +531,7 @@ func TestPRView_Preview(t *testing.T) {
for name, tc := range tests {
t.Run(name, func(t *testing.T) {
initBlankContext("OWNER/REPO", tc.ownerRepo)
initBlankContext("", "OWNER/REPO", tc.ownerRepo)
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -552,7 +552,7 @@ func TestPRView_Preview(t *testing.T) {
}
func TestPRView_web_currentBranch(t *testing.T) {
initBlankContext("OWNER/REPO", "blueberries")
initBlankContext("", "OWNER/REPO", "blueberries")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -590,7 +590,7 @@ func TestPRView_web_currentBranch(t *testing.T) {
}
func TestPRView_web_noResultsForBranch(t *testing.T) {
initBlankContext("OWNER/REPO", "blueberries")
initBlankContext("", "OWNER/REPO", "blueberries")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -621,7 +621,7 @@ func TestPRView_web_noResultsForBranch(t *testing.T) {
}
func TestPRView_web_numberArg(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -653,7 +653,7 @@ func TestPRView_web_numberArg(t *testing.T) {
}
func TestPRView_web_numberArgWithHash(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -685,7 +685,7 @@ func TestPRView_web_numberArgWithHash(t *testing.T) {
}
func TestPRView_web_urlArg(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubResponse(200, bytes.NewBufferString(`
@ -716,7 +716,7 @@ func TestPRView_web_urlArg(t *testing.T) {
}
func TestPRView_web_branchArg(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -750,7 +750,7 @@ func TestPRView_web_branchArg(t *testing.T) {
}
func TestPRView_web_branchWithOwnerArg(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")

View file

@ -77,7 +77,7 @@ func stubSince(d time.Duration) func() {
}
func TestRepoFork_in_parent(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
defer stubSince(2 * time.Second)()
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -134,7 +134,7 @@ func TestRepoFork_outside(t *testing.T) {
}
func TestRepoFork_in_parent_yes(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
defer stubSince(2 * time.Second)()
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -261,7 +261,7 @@ func TestRepoFork_outside_survey_no(t *testing.T) {
}
func TestRepoFork_in_parent_survey_yes(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
defer stubSince(2 * time.Second)()
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -303,7 +303,7 @@ func TestRepoFork_in_parent_survey_yes(t *testing.T) {
}
func TestRepoFork_in_parent_survey_no(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
defer stubSince(2 * time.Second)()
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
@ -678,7 +678,7 @@ func TestRepoCreate_orgWithTeam(t *testing.T) {
}
func TestRepoView_web(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
http.StubResponse(200, bytes.NewBufferString(`
@ -773,7 +773,7 @@ func TestRepoView_web_fullURL(t *testing.T) {
}
func TestRepoView(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
http.StubResponse(200, bytes.NewBufferString(`
@ -801,7 +801,7 @@ func TestRepoView(t *testing.T) {
}
func TestRepoView_nonmarkdown_readme(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
http.StubResponse(200, bytes.NewBufferString(`
@ -828,7 +828,7 @@ func TestRepoView_nonmarkdown_readme(t *testing.T) {
}
func TestRepoView_blanks(t *testing.T) {
initBlankContext("OWNER/REPO", "master")
initBlankContext("", "OWNER/REPO", "master")
http := initFakeHTTP()
http.StubRepoResponse("OWNER", "REPO")
http.StubResponse(200, bytes.NewBufferString("{}"))

View file

@ -10,6 +10,7 @@ import (
"github.com/cli/cli/api"
"github.com/cli/cli/context"
"github.com/cli/cli/internal/config"
"github.com/cli/cli/internal/ghrepo"
"github.com/cli/cli/utils"
@ -17,6 +18,9 @@ import (
"github.com/spf13/pflag"
)
// TODO these are sprinkled across command, context, config, and ghrepo
const defaultHostname = "github.com"
// Version is dynamically set by the toolchain or overridden by the Makefile.
var Version = "DEV"
@ -106,9 +110,21 @@ func BasicClient() (*api.Client, error) {
opts = append(opts, apiVerboseLog())
}
opts = append(opts, api.AddHeader("User-Agent", fmt.Sprintf("GitHub CLI %s", Version)))
if c, err := context.ParseDefaultConfig(); err == nil {
opts = append(opts, api.AddHeader("Authorization", fmt.Sprintf("token %s", c.Token)))
c, err := config.ParseDefaultConfig()
if err != nil {
return nil, err
}
token, err := c.Get(defaultHostname, "oauth_token")
if err != nil {
return nil, err
}
if token == "" {
return nil, fmt.Errorf("no oauth_token set in config")
}
opts = append(opts, api.AddHeader("Authorization", fmt.Sprintf("token %s", token)))
return api.NewClient(opts...), nil
}

View file

@ -10,8 +10,15 @@ import (
"github.com/cli/cli/api"
"github.com/cli/cli/context"
"github.com/cli/cli/internal/config"
)
const defaultTestConfig = `hosts:
github.com:
user: OWNER
oauth_token: 1234567890
`
type askStubber struct {
Asks [][]*survey.Question
Count int
@ -63,7 +70,7 @@ func (as *askStubber) Stub(stubbedQuestions []*QuestionStub) {
as.Stubs = append(as.Stubs, stubbedQuestions)
}
func initBlankContext(repo, branch string) {
func initBlankContext(cfg, repo, branch string) {
initContext = func() context.Context {
ctx := context.NewBlank()
ctx.SetBaseRepo(repo)
@ -71,6 +78,15 @@ func initBlankContext(repo, branch string) {
ctx.SetRemotes(map[string]string{
"origin": "OWNER/REPO",
})
if cfg == "" {
cfg = defaultTestConfig
}
// NOTE we are not restoring the original readConfig; we never want to touch the config file on
// disk during tests.
config.StubConfig(cfg)
return ctx
}
}