add more issue / pr creation params #331
|
@ -12,17 +12,20 @@ import (
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"code.gitea.io/tea/modules/config"
|
"code.gitea.io/tea/modules/config"
|
||||||
"code.gitea.io/tea/modules/task"
|
"code.gitea.io/tea/modules/task"
|
||||||
|
"code.gitea.io/tea/modules/utils"
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/araddon/dateparse"
|
"github.com/araddon/dateparse"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const nilVal = "[none]"
|
||||||
|
const customVal = "[other]"
|
||||||
|
|
||||||
// CreateIssue interactively creates an issue
|
// CreateIssue interactively creates an issue
|
||||||
func CreateIssue(login *config.Login, owner, repo string) error {
|
func CreateIssue(login *config.Login, owner, repo string) error {
|
||||||
var title, description, dueDate, assignees, milestone, labels string
|
var title, description, dueDate, milestone string
|
||||||
|
var assignees, labels []string
|
||||||
var deadline *time.Time
|
var deadline *time.Time
|
||||||
var msID int64
|
|
||||||
var labelIDs []int64
|
|
||||||
|
|
||||||
// owner, repo
|
// owner, repo
|
||||||
owner, repo, err := promptRepoSlug(owner, repo)
|
owner, repo, err := promptRepoSlug(owner, repo)
|
||||||
|
@ -30,6 +33,9 @@ func CreateIssue(login *config.Login, owner, repo string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
selectableChan := make(chan (issueSelectables), 1)
|
||||||
|
go fetchIssueSelectables(login, owner, repo, selectableChan)
|
||||||
|
|
||||||
// title
|
// title
|
||||||
promptOpts := survey.WithValidator(survey.Required)
|
promptOpts := survey.WithValidator(survey.Required)
|
||||||
promptI := &survey.Input{Message: "Issue title:"}
|
promptI := &survey.Input{Message: "Issue title:"}
|
||||||
|
@ -43,23 +49,43 @@ func CreateIssue(login *config.Login, owner, repo string) error {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// assignees // TODO: add suggestions
|
// wait until selectables are fetched
|
||||||
promptA := &survey.Input{Message: "Assignees:"}
|
selectables := <-selectableChan
|
||||||
|
if selectables.Err != nil {
|
||||||
|
return selectables.Err
|
||||||
|
}
|
||||||
|
|
||||||
|
// assignees
|
||||||
|
promptA := &survey.MultiSelect{Message: "Assignees:", Options: selectables.Collaborators, VimMode: true}
|
||||||
if err := survey.AskOne(promptA, &assignees); err != nil {
|
if err := survey.AskOne(promptA, &assignees); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
// check for custom value & prompt again with text input
|
||||||
|
// HACK until https://github.com/AlecAivazis/survey/issues/339 is implemented
|
||||||
|
if utils.Contains(assignees, customVal) {
|
||||||
|
var customAssignees string
|
||||||
|
promptA := &survey.Input{Message: "Assignees:", Help: "comma separated usernames"}
|
||||||
|
if err := survey.AskOne(promptA, &customAssignees); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
assignees = append(assignees, strings.Split(customAssignees, ",")...)
|
||||||
|
}
|
||||||
|
|
||||||
// milestone // TODO: add suggestions
|
// milestone
|
||||||
promptM := &survey.Input{Message: "Milestone:"}
|
promptM := &survey.Select{Message: "Milestone:", Options: selectables.MilestoneList, VimMode: true, Default: nilVal}
|
||||||
if err := survey.AskOne(promptM, &milestone); err != nil {
|
if err := survey.AskOne(promptM, &milestone); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
// labels // TODO: add suggestions
|
// labels
|
||||||
promptL := &survey.Input{Message: "Labels:"}
|
promptL := &survey.MultiSelect{Message: "Labels:", Options: selectables.LabelList, VimMode: true}
|
||||||
if err := survey.AskOne(promptL, &labels); err != nil {
|
if err := survey.AskOne(promptL, &labels); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
labelIDs := make([]int64, len(labels))
|
||||||
|
for i, l := range labels {
|
||||||
|
labelIDs[i] = selectables.LabelMap[l]
|
||||||
|
}
|
||||||
|
|
||||||
// deadline
|
// deadline
|
||||||
promptI = &survey.Input{Message: "Due date [no due date]:"}
|
promptI = &survey.Input{Message: "Due date [no due date]:"}
|
||||||
|
@ -83,22 +109,6 @@ func CreateIssue(login *config.Login, owner, repo string) error {
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
|
||||||
// resolve IDs
|
|
||||||
client := login.Client()
|
|
||||||
if len(milestone) != 0 {
|
|
||||||
ms, _, err := client.GetMilestoneByName(owner, repo, milestone)
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("Milestone '%s' not found", milestone)
|
|
||||||
}
|
|
||||||
msID = ms.ID
|
|
||||||
}
|
|
||||||
if len(labels) != 0 {
|
|
||||||
labelIDs, err = task.ResolveLabelNames(client, owner, repo, strings.Split(labels, ","))
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return task.CreateIssue(
|
return task.CreateIssue(
|
||||||
login,
|
login,
|
||||||
owner,
|
owner,
|
||||||
|
@ -107,9 +117,68 @@ func CreateIssue(login *config.Login, owner, repo string) error {
|
||||||
Title: title,
|
Title: title,
|
||||||
Body: description,
|
Body: description,
|
||||||
Deadline: deadline,
|
Deadline: deadline,
|
||||||
Assignees: strings.Split(assignees, ","),
|
Assignees: assignees,
|
||||||
Milestone: msID,
|
Milestone: selectables.MilestoneMap[milestone],
|
||||||
Labels: labelIDs,
|
Labels: labelIDs,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type issueSelectables struct {
|
||||||
|
Collaborators []string
|
||||||
|
MilestoneList []string
|
||||||
|
MilestoneMap map[string]int64
|
||||||
|
LabelList []string
|
||||||
|
LabelMap map[string]int64
|
||||||
|
Err error
|
||||||
|
}
|
||||||
|
|
||||||
|
func fetchIssueSelectables(login *config.Login, owner, repo string, done chan issueSelectables) {
|
||||||
|
// TODO PERF make these calls concurrent
|
||||||
|
r := issueSelectables{}
|
||||||
|
c := login.Client()
|
||||||
|
|
||||||
|
// FIXME: this should ideally be ListAssignees(), https://github.com/go-gitea/gitea/issues/14856
|
||||||
|
colabs, _, err := c.ListCollaborators(owner, repo, gitea.ListCollaboratorsOptions{})
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
done <- r
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.Collaborators = make([]string, len(colabs)+2)
|
||||||
|
r.Collaborators[0] = login.User
|
||||||
|
r.Collaborators[1] = customVal
|
||||||
|
for i, u := range colabs {
|
||||||
|
r.Collaborators[i+2] = u.UserName
|
||||||
|
}
|
||||||
|
|
||||||
|
milestones, _, err := c.ListRepoMilestones(owner, repo, gitea.ListMilestoneOption{})
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
done <- r
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.MilestoneMap = make(map[string]int64)
|
||||||
|
r.MilestoneList = make([]string, len(milestones)+1)
|
||||||
|
r.MilestoneList[0] = nilVal
|
||||||
|
r.MilestoneMap[nilVal] = 0
|
||||||
|
for i, m := range milestones {
|
||||||
|
r.MilestoneMap[m.Title] = m.ID
|
||||||
|
r.MilestoneList[i+1] = m.Title
|
||||||
|
}
|
||||||
|
|
||||||
|
labels, _, err := c.ListRepoLabels(owner, repo, gitea.ListLabelsOptions{})
|
||||||
|
if err != nil {
|
||||||
|
r.Err = err
|
||||||
|
done <- r
|
||||||
|
return
|
||||||
|
}
|
||||||
|
r.LabelMap = make(map[string]int64)
|
||||||
|
r.LabelList = make([]string, len(labels))
|
||||||
|
for i, l := range labels {
|
||||||
|
r.LabelMap[l.Name] = l.ID
|
||||||
|
r.LabelList[i] = l.Name
|
||||||
|
}
|
||||||
|
|
||||||
|
done <- r
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user