-
Notifications
You must be signed in to change notification settings - Fork 5
/
checkout-new.go
140 lines (116 loc) · 3.34 KB
/
checkout-new.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
package cmd
import (
"context"
"fmt"
"strings"
"github.com/AlecAivazis/survey/v2"
"github.com/MakeNowJust/heredoc"
"github.com/caarlos0/log"
"github.com/pkg/errors"
"github.com/samber/lo"
"github.com/spf13/cobra"
"github.com/ilaif/gh-prx/pkg/branch"
"github.com/ilaif/gh-prx/pkg/config"
"github.com/ilaif/gh-prx/pkg/models"
"github.com/ilaif/gh-prx/pkg/providers"
"github.com/ilaif/gh-prx/pkg/utils"
)
func NewCheckoutNewCmd() *cobra.Command {
cmd := &cobra.Command{
Use: "checkout-new [issue-id]",
Short: "Create a new branch based on an issue and checkout to it.",
Args: cobra.MaximumNArgs(1),
Long: heredoc.Docf(`
Create a new branch based on an issue and checkout to it.
If the issue type ({{.Type}}) can't be resolved from the labels automatically,
the user will be prompted to choose a type.
`, "`"),
Example: heredoc.Doc(`
// Create a new branch based on a list of available issues and checkout to it:
$ gh prx checkout-new
// Create a new branch based on issue 1234 and checkout to it:
$ gh prx checkout-new 1234
`),
Aliases: []string{"switch-create", "sc", "cob"},
RunE: func(cmd *cobra.Command, args []string) error {
ctx := cmd.Context()
issueID := ""
if len(args) > 0 {
issueID = args[0]
}
return checkoutNew(ctx, issueID)
},
}
return cmd
}
func checkoutNew(ctx context.Context, id string) error {
setupCfg, err := config.LoadSetupConfig()
if err != nil {
return err
}
cfg, err := config.LoadRepositoryConfig(setupCfg.RepositoryConfig)
if err != nil {
return err
}
provider, err := providers.NewIssueProvider(cfg, setupCfg)
if err != nil {
return err
}
if id == "" {
id, err = chooseIssue(ctx, provider)
if err != nil {
return errors.Wrap(err, "Failed to choose issue")
}
}
s := utils.StartSpinner("Fetching issue from provider...", "Fetched issue from provider")
issue, err := provider.Get(ctx, id)
s.Stop()
if err != nil {
return errors.Wrap(err, "Failed to get issue")
}
branchName := issue.SuggestedBranchName
if branchName == "" {
branchName, err = branch.TemplateBranchName(cfg, issue)
if err != nil {
return err
}
}
log.Debugf("Creating branch '%s' and checking out to it", branchName)
out, err := utils.Exec("git", "checkout", "-b", branchName)
if err != nil {
return errors.Wrap(err, "Failed to create branch")
}
log.Info(strings.Trim(out, "\n"))
return nil
}
func chooseIssue(ctx context.Context, provider providers.IssueProvider) (string, error) {
s := utils.StartSpinner(
fmt.Sprintf("Fetching issues from %s...", provider.Name()),
fmt.Sprintf("Fetched issues from %s", provider.Name()),
)
issues, err := provider.List(ctx)
s.Stop()
if err != nil {
return "", errors.Wrap(err, "Failed to list issues")
}
if len(issues) == 0 {
return "", errors.New("No issues found. Please make sure that you have issues that match the configured filter")
}
var i int
if err := survey.Ask([]*survey.Question{{
Name: "issue",
Prompt: &survey.Select{
Message: "Select an issue:",
Options: lo.Map(issues, func(i *models.Issue, _ int) string {
issueType := ""
if i.Type != "" {
issueType = fmt.Sprintf("(%s) ", i.Type)
}
return fmt.Sprintf("%s%s - %s", issueType, i.Key, i.Title)
}),
},
}}, &i); err != nil {
return "", errors.Wrap(err, "Failed to prompt for issue")
}
return issues[i].Key, nil
}