Merge branch 'master' into reviewers-in-pr-view
This commit is contained in:
commit
d2d0b47ecc
22 changed files with 416 additions and 136 deletions
|
|
@ -504,7 +504,11 @@ func issueProjectList(issue api.Issue) string {
|
|||
|
||||
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))
|
||||
colName := project.Column.Name
|
||||
if colName == "" {
|
||||
colName = "Awaiting triage"
|
||||
}
|
||||
projectNames = append(projectNames, fmt.Sprintf("%s (%s)", project.Project.Name, colName))
|
||||
}
|
||||
|
||||
list := strings.Join(projectNames, ", ")
|
||||
|
|
|
|||
|
|
@ -312,7 +312,7 @@ func TestIssueView_Preview(t *testing.T) {
|
|||
`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`,
|
||||
`Projects: Project 1 \(column A\), Project 2 \(column B\), Project 3 \(column C\), Project 4 \(Awaiting triage\)\n`,
|
||||
`Milestone: uluru\n`,
|
||||
`bold story`,
|
||||
`View this issue on GitHub: https://github.com/OWNER/REPO/issues/123`,
|
||||
|
|
|
|||
|
|
@ -531,7 +531,11 @@ func prProjectList(pr api.PullRequest) string {
|
|||
|
||||
projectNames := make([]string, 0, len(pr.ProjectCards.Nodes))
|
||||
for _, project := range pr.ProjectCards.Nodes {
|
||||
projectNames = append(projectNames, fmt.Sprintf("%s (%s)", project.Project.Name, project.Column.Name))
|
||||
colName := project.Column.Name
|
||||
if colName == "" {
|
||||
colName = "Awaiting triage"
|
||||
}
|
||||
projectNames = append(projectNames, fmt.Sprintf("%s (%s)", project.Project.Name, colName))
|
||||
}
|
||||
|
||||
list := strings.Join(projectNames, ", ")
|
||||
|
|
|
|||
|
|
@ -47,7 +47,7 @@ func prCheckout(cmd *cobra.Command, args []string) error {
|
|||
|
||||
baseRemote, _ := remotes.FindByRepo(baseRepo.RepoOwner(), baseRepo.RepoName())
|
||||
// baseRemoteSpec is a repository URL or a remote name to be used in git fetch
|
||||
baseURLOrName := fmt.Sprintf("https://github.com/%s.git", ghrepo.FullName(baseRepo))
|
||||
baseURLOrName := formatRemoteURL(cmd, ghrepo.FullName(baseRepo))
|
||||
if baseRemote != nil {
|
||||
baseURLOrName = baseRemote.Name
|
||||
}
|
||||
|
|
@ -97,7 +97,7 @@ func prCheckout(cmd *cobra.Command, args []string) error {
|
|||
remote := baseURLOrName
|
||||
mergeRef := ref
|
||||
if pr.MaintainerCanModify {
|
||||
remote = fmt.Sprintf("https://github.com/%s/%s.git", pr.HeadRepositoryOwner.Login, pr.HeadRepository.Name)
|
||||
remote = formatRemoteURL(cmd, fmt.Sprintf("%s/%s", pr.HeadRepositoryOwner.Login, pr.HeadRepository.Name))
|
||||
mergeRef = fmt.Sprintf("refs/heads/%s", pr.HeadRefName)
|
||||
}
|
||||
if mc, err := git.Config(fmt.Sprintf("branch.%s.merge", newBranchName)); err != nil || mc == "" {
|
||||
|
|
|
|||
|
|
@ -250,8 +250,8 @@ func prCreate(cmd *cobra.Command, _ []string) error {
|
|||
// In either case, we want to add the head repo as a new git remote so we
|
||||
// can push to it.
|
||||
if headRemote == nil {
|
||||
// TODO: support non-HTTPS git remote URLs
|
||||
headRepoURL := fmt.Sprintf("https://github.com/%s.git", ghrepo.FullName(headRepo))
|
||||
headRepoURL := formatRemoteURL(cmd, ghrepo.FullName(headRepo))
|
||||
|
||||
// TODO: prevent clashes with another remote of a same name
|
||||
gitRemote, err := git.AddRemote("fork", headRepoURL)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -430,7 +430,7 @@ func TestPRView_Preview(t *testing.T) {
|
|||
`Reviewers: 2 \(Approved\), 3 \(Commented\), 1 \(Requested\)\n`,
|
||||
`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`,
|
||||
`Projects: Project 1 \(column A\), Project 2 \(column B\), Project 3 \(column C\), Project 4 \(Awaiting triage\)\n`,
|
||||
`Milestone: uluru\n`,
|
||||
`blueberries taste good`,
|
||||
`View this pull request on GitHub: https://github.com/OWNER/REPO/pull/12\n`,
|
||||
|
|
|
|||
|
|
@ -127,7 +127,7 @@ func runClone(cloneURL string, args []string) (target string, err error) {
|
|||
func repoClone(cmd *cobra.Command, args []string) error {
|
||||
cloneURL := args[0]
|
||||
if !strings.Contains(cloneURL, ":") {
|
||||
cloneURL = fmt.Sprintf("https://github.com/%s.git", cloneURL)
|
||||
cloneURL = formatRemoteURL(cmd, cloneURL)
|
||||
}
|
||||
|
||||
var repo ghrepo.Interface
|
||||
|
|
@ -158,7 +158,7 @@ func repoClone(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
|
||||
if parentRepo != nil {
|
||||
err := addUpstreamRemote(parentRepo, cloneDir)
|
||||
err := addUpstreamRemote(cmd, parentRepo, cloneDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -167,9 +167,8 @@ func repoClone(cmd *cobra.Command, args []string) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
func addUpstreamRemote(parentRepo ghrepo.Interface, cloneDir string) error {
|
||||
// TODO: support SSH remote URLs
|
||||
upstreamURL := fmt.Sprintf("https://github.com/%s.git", ghrepo.FullName(parentRepo))
|
||||
func addUpstreamRemote(cmd *cobra.Command, parentRepo ghrepo.Interface, cloneDir string) error {
|
||||
upstreamURL := formatRemoteURL(cmd, ghrepo.FullName(parentRepo))
|
||||
|
||||
cloneCmd := git.GitCommand("-C", cloneDir, "remote", "add", "-f", "upstream", upstreamURL)
|
||||
cloneCmd.Stdout = os.Stdout
|
||||
|
|
@ -267,14 +266,10 @@ func repoCreate(cmd *cobra.Command, args []string) error {
|
|||
fmt.Fprintln(out, repo.URL)
|
||||
}
|
||||
|
||||
remoteURL := repo.URL + ".git"
|
||||
remoteURL := formatRemoteURL(cmd, ghrepo.FullName(repo))
|
||||
|
||||
if projectDirErr == nil {
|
||||
// TODO: use git.AddRemote
|
||||
remoteAdd := git.GitCommand("remote", "add", "origin", remoteURL)
|
||||
remoteAdd.Stdout = os.Stdout
|
||||
remoteAdd.Stderr = os.Stderr
|
||||
err = run.PrepareCmd(remoteAdd).Run()
|
||||
_, err = git.AddRemote("origin", remoteURL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -338,7 +333,7 @@ func repoFork(cmd *cobra.Command, args []string) error {
|
|||
return fmt.Errorf("unable to create client: %w", err)
|
||||
}
|
||||
|
||||
var toFork ghrepo.Interface
|
||||
var repoToFork ghrepo.Interface
|
||||
inParent := false // whether or not we're forking the repo we're currently "in"
|
||||
if len(args) == 0 {
|
||||
baseRepo, err := determineBaseRepo(cmd, ctx)
|
||||
|
|
@ -346,7 +341,7 @@ func repoFork(cmd *cobra.Command, args []string) error {
|
|||
return fmt.Errorf("unable to determine base repository: %w", err)
|
||||
}
|
||||
inParent = true
|
||||
toFork = baseRepo
|
||||
repoToFork = baseRepo
|
||||
} else {
|
||||
repoArg := args[0]
|
||||
|
||||
|
|
@ -356,14 +351,23 @@ func repoFork(cmd *cobra.Command, args []string) error {
|
|||
return fmt.Errorf("did not understand argument: %w", err)
|
||||
}
|
||||
|
||||
toFork, err = ghrepo.FromURL(parsedURL)
|
||||
repoToFork, err = ghrepo.FromURL(parsedURL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("did not understand argument: %w", err)
|
||||
}
|
||||
|
||||
} else if strings.HasPrefix(repoArg, "git@") {
|
||||
parsedURL, err := git.ParseURL(repoArg)
|
||||
if err != nil {
|
||||
return fmt.Errorf("did not understand argument: %w", err)
|
||||
}
|
||||
repoToFork, err = ghrepo.FromURL(parsedURL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("did not understand argument: %w", err)
|
||||
}
|
||||
} else {
|
||||
toFork = ghrepo.FromFullName(repoArg)
|
||||
if toFork.RepoName() == "" || toFork.RepoOwner() == "" {
|
||||
repoToFork = ghrepo.FromFullName(repoArg)
|
||||
if repoToFork.RepoName() == "" || repoToFork.RepoOwner() == "" {
|
||||
return fmt.Errorf("could not parse owner or repo name from %s", repoArg)
|
||||
}
|
||||
}
|
||||
|
|
@ -372,12 +376,12 @@ func repoFork(cmd *cobra.Command, args []string) error {
|
|||
greenCheck := utils.Green("✓")
|
||||
out := colorableOut(cmd)
|
||||
s := utils.Spinner(out)
|
||||
loading := utils.Gray("Forking ") + utils.Bold(utils.Gray(ghrepo.FullName(toFork))) + utils.Gray("...")
|
||||
loading := utils.Gray("Forking ") + utils.Bold(utils.Gray(ghrepo.FullName(repoToFork))) + utils.Gray("...")
|
||||
s.Suffix = " " + loading
|
||||
s.FinalMSG = utils.Gray(fmt.Sprintf("- %s\n", loading))
|
||||
s.Start()
|
||||
|
||||
forkedRepo, err := api.ForkRepo(apiClient, toFork)
|
||||
forkedRepo, err := api.ForkRepo(apiClient, repoToFork)
|
||||
if err != nil {
|
||||
s.Stop()
|
||||
return fmt.Errorf("failed to fork: %w", err)
|
||||
|
|
@ -437,7 +441,9 @@ func repoFork(cmd *cobra.Command, args []string) error {
|
|||
fmt.Fprintf(out, "%s Renamed %s remote to %s\n", greenCheck, utils.Bold(remoteName), utils.Bold(renameTarget))
|
||||
}
|
||||
|
||||
_, err = git.AddRemote(remoteName, forkedRepo.CloneURL)
|
||||
forkedRepoCloneURL := formatRemoteURL(cmd, ghrepo.FullName(forkedRepo))
|
||||
|
||||
_, err = git.AddRemote(remoteName, forkedRepoCloneURL)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to add remote: %w", err)
|
||||
}
|
||||
|
|
@ -453,12 +459,13 @@ func repoFork(cmd *cobra.Command, args []string) error {
|
|||
}
|
||||
}
|
||||
if cloneDesired {
|
||||
cloneDir, err := runClone(forkedRepo.CloneURL, []string{})
|
||||
forkedRepoCloneURL := formatRemoteURL(cmd, ghrepo.FullName(forkedRepo))
|
||||
cloneDir, err := runClone(forkedRepoCloneURL, []string{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to clone fork: %w", err)
|
||||
}
|
||||
|
||||
err = addUpstreamRemote(toFork, cloneDir)
|
||||
err = addUpstreamRemote(cmd, repoToFork, cloneDir)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -153,7 +153,7 @@ func TestRepoFork_in_parent_yes(t *testing.T) {
|
|||
|
||||
expectedCmds := []string{
|
||||
"git remote rename origin upstream",
|
||||
"git remote add -f origin https://github.com/someone/repo.git",
|
||||
"git remote add -f origin https://github.com/someone/REPO.git",
|
||||
}
|
||||
|
||||
for x, cmd := range seenCmds {
|
||||
|
|
@ -185,8 +185,8 @@ func TestRepoFork_outside_yes(t *testing.T) {
|
|||
|
||||
eq(t, output.Stderr(), "")
|
||||
|
||||
eq(t, strings.Join(cs.Calls[0].Args, " "), "git clone https://github.com/someone/repo.git")
|
||||
eq(t, strings.Join(cs.Calls[1].Args, " "), "git -C repo remote add -f upstream https://github.com/OWNER/REPO.git")
|
||||
eq(t, strings.Join(cs.Calls[0].Args, " "), "git clone https://github.com/someone/REPO.git")
|
||||
eq(t, strings.Join(cs.Calls[1].Args, " "), "git -C REPO remote add -f upstream https://github.com/OWNER/REPO.git")
|
||||
|
||||
test.ExpectLines(t, output.String(),
|
||||
"Created fork someone/REPO",
|
||||
|
|
@ -218,8 +218,8 @@ func TestRepoFork_outside_survey_yes(t *testing.T) {
|
|||
|
||||
eq(t, output.Stderr(), "")
|
||||
|
||||
eq(t, strings.Join(cs.Calls[0].Args, " "), "git clone https://github.com/someone/repo.git")
|
||||
eq(t, strings.Join(cs.Calls[1].Args, " "), "git -C repo remote add -f upstream https://github.com/OWNER/REPO.git")
|
||||
eq(t, strings.Join(cs.Calls[0].Args, " "), "git clone https://github.com/someone/REPO.git")
|
||||
eq(t, strings.Join(cs.Calls[1].Args, " "), "git -C REPO remote add -f upstream https://github.com/OWNER/REPO.git")
|
||||
|
||||
test.ExpectLines(t, output.String(),
|
||||
"Created fork someone/REPO",
|
||||
|
|
@ -287,7 +287,7 @@ func TestRepoFork_in_parent_survey_yes(t *testing.T) {
|
|||
|
||||
expectedCmds := []string{
|
||||
"git remote rename origin upstream",
|
||||
"git remote add -f origin https://github.com/someone/repo.git",
|
||||
"git remote add -f origin https://github.com/someone/REPO.git",
|
||||
}
|
||||
|
||||
for x, cmd := range seenCmds {
|
||||
|
|
@ -499,7 +499,11 @@ func TestRepoCreate(t *testing.T) {
|
|||
{ "data": { "createRepository": {
|
||||
"repository": {
|
||||
"id": "REPOID",
|
||||
"url": "https://github.com/OWNER/REPO"
|
||||
"url": "https://github.com/OWNER/REPO",
|
||||
"name": "REPO",
|
||||
"owner": {
|
||||
"login": "OWNER"
|
||||
}
|
||||
}
|
||||
} } }
|
||||
`))
|
||||
|
|
@ -522,7 +526,7 @@ func TestRepoCreate(t *testing.T) {
|
|||
if seenCmd == nil {
|
||||
t.Fatal("expected a command to run")
|
||||
}
|
||||
eq(t, strings.Join(seenCmd.Args, " "), "git remote add origin https://github.com/OWNER/REPO.git")
|
||||
eq(t, strings.Join(seenCmd.Args, " "), "git remote add -f origin https://github.com/OWNER/REPO.git")
|
||||
|
||||
var reqBody struct {
|
||||
Query string
|
||||
|
|
@ -564,7 +568,11 @@ func TestRepoCreate_org(t *testing.T) {
|
|||
{ "data": { "createRepository": {
|
||||
"repository": {
|
||||
"id": "REPOID",
|
||||
"url": "https://github.com/ORG/REPO"
|
||||
"url": "https://github.com/ORG/REPO",
|
||||
"name": "REPO",
|
||||
"owner": {
|
||||
"login": "ORG"
|
||||
}
|
||||
}
|
||||
} } }
|
||||
`))
|
||||
|
|
@ -587,7 +595,7 @@ func TestRepoCreate_org(t *testing.T) {
|
|||
if seenCmd == nil {
|
||||
t.Fatal("expected a command to run")
|
||||
}
|
||||
eq(t, strings.Join(seenCmd.Args, " "), "git remote add origin https://github.com/ORG/REPO.git")
|
||||
eq(t, strings.Join(seenCmd.Args, " "), "git remote add -f origin https://github.com/ORG/REPO.git")
|
||||
|
||||
var reqBody struct {
|
||||
Query string
|
||||
|
|
@ -629,7 +637,11 @@ func TestRepoCreate_orgWithTeam(t *testing.T) {
|
|||
{ "data": { "createRepository": {
|
||||
"repository": {
|
||||
"id": "REPOID",
|
||||
"url": "https://github.com/ORG/REPO"
|
||||
"url": "https://github.com/ORG/REPO",
|
||||
"name": "REPO",
|
||||
"owner": {
|
||||
"login": "ORG"
|
||||
}
|
||||
}
|
||||
} } }
|
||||
`))
|
||||
|
|
@ -652,7 +664,7 @@ func TestRepoCreate_orgWithTeam(t *testing.T) {
|
|||
if seenCmd == nil {
|
||||
t.Fatal("expected a command to run")
|
||||
}
|
||||
eq(t, strings.Join(seenCmd.Args, " "), "git remote add origin https://github.com/ORG/REPO.git")
|
||||
eq(t, strings.Join(seenCmd.Args, " "), "git remote add -f origin https://github.com/ORG/REPO.git")
|
||||
|
||||
var reqBody struct {
|
||||
Query string
|
||||
|
|
|
|||
147
command/root.go
147
command/root.go
|
|
@ -51,6 +51,8 @@ func init() {
|
|||
// TODO:
|
||||
// RootCmd.PersistentFlags().BoolP("verbose", "V", false, "enable verbose output")
|
||||
|
||||
RootCmd.SetHelpFunc(rootHelpFunc)
|
||||
|
||||
RootCmd.SetFlagErrorFunc(func(cmd *cobra.Command, err error) error {
|
||||
if err == pflag.ErrHelp {
|
||||
return err
|
||||
|
|
@ -74,12 +76,9 @@ func (fe FlagError) Unwrap() error {
|
|||
|
||||
// RootCmd is the entry point of command-line execution
|
||||
var RootCmd = &cobra.Command{
|
||||
Use: "gh",
|
||||
Use: "gh <command> <subcommand> [flags]",
|
||||
Short: "GitHub CLI",
|
||||
Long: `Work seamlessly with GitHub from the command line.
|
||||
|
||||
GitHub CLI is in early stages of development, and we'd love to hear your
|
||||
feedback at <https://forms.gle/umxd3h31c7aMQFKG7>`,
|
||||
Long: `Work seamlessly with GitHub from the command line.`,
|
||||
|
||||
SilenceErrors: true,
|
||||
SilenceUsage: true,
|
||||
|
|
@ -111,20 +110,11 @@ func BasicClient() (*api.Client, error) {
|
|||
}
|
||||
opts = append(opts, api.AddHeader("User-Agent", fmt.Sprintf("GitHub CLI %s", Version)))
|
||||
|
||||
c, err := config.ParseDefaultConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if c, err := config.ParseDefaultConfig(); err == nil {
|
||||
if token, _ := c.Get(defaultHostname, "oauth_token"); token != "" {
|
||||
opts = append(opts, api.AddHeader("Authorization", fmt.Sprintf("token %s", token)))
|
||||
}
|
||||
}
|
||||
|
||||
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
|
||||
}
|
||||
|
||||
|
|
@ -142,12 +132,47 @@ var apiClientForContext = func(ctx context.Context) (*api.Client, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var opts []api.ClientOption
|
||||
if verbose := os.Getenv("DEBUG"); verbose != "" {
|
||||
opts = append(opts, apiVerboseLog())
|
||||
}
|
||||
|
||||
getAuthValue := func() string {
|
||||
return fmt.Sprintf("token %s", token)
|
||||
}
|
||||
|
||||
checkScopesFunc := func(appID string) error {
|
||||
if config.IsGitHubApp(appID) && utils.IsTerminal(os.Stdin) && utils.IsTerminal(os.Stderr) {
|
||||
newToken, loginHandle, err := config.AuthFlow("Notice: additional authorization required")
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
cfg, err := ctx.Config()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
_ = cfg.Set(defaultHostname, "oauth_token", newToken)
|
||||
_ = cfg.Set(defaultHostname, "user", loginHandle)
|
||||
// update config file on disk
|
||||
err = cfg.Write()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
// update configuration in memory
|
||||
token = newToken
|
||||
config.AuthFlowComplete()
|
||||
} else {
|
||||
fmt.Fprintln(os.Stderr, "Warning: gh now requires the `read:org` OAuth scope.")
|
||||
fmt.Fprintln(os.Stderr, "Visit https://github.com/settings/tokens and edit your token to enable `read:org`")
|
||||
fmt.Fprintln(os.Stderr, "or generate a new token and paste it via `gh config set -h github.com oauth_token MYTOKEN`")
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
opts = append(opts,
|
||||
api.AddHeader("Authorization", fmt.Sprintf("token %s", token)),
|
||||
api.CheckScopes("read:org", checkScopesFunc),
|
||||
api.AddHeaderFunc("Authorization", getAuthValue),
|
||||
api.AddHeader("User-Agent", fmt.Sprintf("GitHub CLI %s", Version)),
|
||||
// antiope-preview: Checks
|
||||
api.AddHeader("Accept", "application/vnd.github.antiope-preview+json"),
|
||||
|
|
@ -222,3 +247,87 @@ func determineBaseRepo(cmd *cobra.Command, ctx context.Context) (ghrepo.Interfac
|
|||
|
||||
return baseRepo, nil
|
||||
}
|
||||
|
||||
func rootHelpFunc(command *cobra.Command, s []string) {
|
||||
type helpEntry struct {
|
||||
Title string
|
||||
Body string
|
||||
}
|
||||
|
||||
coreCommandNames := []string{"issue", "pr", "repo"}
|
||||
var coreCommands []string
|
||||
var additionalCommands []string
|
||||
for _, c := range command.Commands() {
|
||||
if c.Short == "" {
|
||||
continue
|
||||
}
|
||||
s := " " + rpad(c.Name()+":", c.NamePadding()) + c.Short
|
||||
if includes(coreCommandNames, c.Name()) {
|
||||
coreCommands = append(coreCommands, s)
|
||||
} else {
|
||||
additionalCommands = append(additionalCommands, s)
|
||||
}
|
||||
}
|
||||
|
||||
helpEntries := []helpEntry{
|
||||
{
|
||||
"",
|
||||
command.Long},
|
||||
{"USAGE", command.Use},
|
||||
{"CORE COMMANDS", strings.Join(coreCommands, "\n")},
|
||||
{"ADDITIONAL COMMANDS", strings.Join(additionalCommands, "\n")},
|
||||
{"FLAGS", strings.TrimRight(command.LocalFlags().FlagUsages(), "\n")},
|
||||
{"EXAMPLES", `
|
||||
$ gh issue create
|
||||
$ gh repo clone
|
||||
$ gh pr checkout 321`},
|
||||
{"LEARN MORE", `
|
||||
Use "gh <command> <subcommand> --help" for more information about a command.
|
||||
Read the manual at <http://cli.github.com/manual>`},
|
||||
{"FEEDBACK", `
|
||||
Fill out our feedback form <https://forms.gle/umxd3h31c7aMQFKG7>
|
||||
Open an issue using “gh issue create -R cli/cli”`},
|
||||
}
|
||||
|
||||
out := colorableOut(command)
|
||||
for _, e := range helpEntries {
|
||||
if e.Title != "" {
|
||||
fmt.Fprintln(out, utils.Bold(e.Title))
|
||||
}
|
||||
fmt.Fprintln(out, strings.TrimLeft(e.Body, "\n")+"\n")
|
||||
}
|
||||
}
|
||||
|
||||
// rpad adds padding to the right of a string.
|
||||
func rpad(s string, padding int) string {
|
||||
template := fmt.Sprintf("%%-%ds ", padding)
|
||||
return fmt.Sprintf(template, s)
|
||||
}
|
||||
|
||||
func includes(a []string, s string) bool {
|
||||
for _, x := range a {
|
||||
if x == s {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func formatRemoteURL(cmd *cobra.Command, fullRepoName string) string {
|
||||
ctx := contextForCommand(cmd)
|
||||
|
||||
protocol := "https"
|
||||
cfg, err := ctx.Config()
|
||||
if err != nil {
|
||||
fmt.Fprintf(colorableErr(cmd), "%s failed to load config: %s. using defaults\n", utils.Yellow("!"), err)
|
||||
} else {
|
||||
cfgProtocol, _ := cfg.Get(defaultHostname, "git_protocol")
|
||||
protocol = cfgProtocol
|
||||
}
|
||||
|
||||
if protocol == "ssh" {
|
||||
return fmt.Sprintf("git@%s:%s.git", defaultHostname, fullRepoName)
|
||||
}
|
||||
|
||||
return fmt.Sprintf("https://%s/%s.git", defaultHostname, fullRepoName)
|
||||
}
|
||||
|
|
|
|||
|
|
@ -40,3 +40,22 @@ func TestChangelogURL(t *testing.T) {
|
|||
t.Errorf("expected %s to create url %s but got %s", tag, url, result)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemoteURLFormatting_no_config(t *testing.T) {
|
||||
initBlankContext("", "OWNER/REPO", "master")
|
||||
result := formatRemoteURL(repoForkCmd, "OWNER/REPO")
|
||||
eq(t, result, "https://github.com/OWNER/REPO.git")
|
||||
}
|
||||
|
||||
func TestRemoteURLFormatting_ssh_config(t *testing.T) {
|
||||
cfg := `---
|
||||
hosts:
|
||||
github.com:
|
||||
user: OWNER
|
||||
oauth_token: MUSTBEHIGHCUZIMATOKEN
|
||||
git_protocol: ssh
|
||||
`
|
||||
initBlankContext(cfg, "OWNER/REPO", "master")
|
||||
result := formatRemoteURL(repoForkCmd, "OWNER/REPO")
|
||||
eq(t, result, "git@github.com:OWNER/REPO.git")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,6 +2,7 @@ package command
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"os"
|
||||
|
||||
"github.com/AlecAivazis/survey/v2"
|
||||
"github.com/cli/cli/pkg/githubtemplate"
|
||||
|
|
@ -82,6 +83,16 @@ func selectTemplate(templatePaths []string) (string, error) {
|
|||
}
|
||||
|
||||
func titleBodySurvey(cmd *cobra.Command, providedTitle, providedBody string, defs defaults, templatePaths []string) (*titleBody, error) {
|
||||
editorCommand := os.Getenv("GH_EDITOR")
|
||||
if editorCommand == "" {
|
||||
ctx := contextForCommand(cmd)
|
||||
cfg, err := ctx.Config()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not read config: %w", err)
|
||||
}
|
||||
editorCommand, _ = cfg.Get(defaultHostname, "editor")
|
||||
}
|
||||
|
||||
var inProgress titleBody
|
||||
inProgress.Title = defs.Title
|
||||
templateContents := ""
|
||||
|
|
@ -109,6 +120,7 @@ func titleBodySurvey(cmd *cobra.Command, providedTitle, providedBody string, def
|
|||
bodyQuestion := &survey.Question{
|
||||
Name: "body",
|
||||
Prompt: &surveyext.GhEditor{
|
||||
EditorCommand: editorCommand,
|
||||
Editor: &survey.Editor{
|
||||
Message: "Body",
|
||||
FileName: "*.md",
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue