From b9f5ba0702befa976ba9a446173a977acd45fd86 Mon Sep 17 00:00:00 2001 From: Martin Reboredo Date: Tue, 15 Dec 2020 04:05:31 +0800 Subject: [PATCH] Add interactive mode for `tea issue create` (#302) Implement interactive issue creation Comment PromptRepoSlug Move PromptRepoSlug to the right place Hide promptRepoSlug Signed-off-by: Martin Reboredo Co-authored-by: Martin Reboredo Reviewed-on: https://gitea.com/gitea/tea/pulls/302 Reviewed-by: Norwin Reviewed-by: khmarbaise Reviewed-by: 6543 <6543@obermui.de> Co-Authored-By: Martin Reboredo Co-Committed-By: Martin Reboredo --- cmd/issues/create.go | 33 ++++++++--------------- modules/interact/issue_create.go | 43 ++++++++++++++++++++++++++++++ modules/interact/prompts.go | 43 ++++++++++++++++++++++++++++++ modules/interact/pull_create.go | 42 ----------------------------- modules/task/issue_create.go | 45 ++++++++++++++++++++++++++++++++ 5 files changed, 142 insertions(+), 64 deletions(-) create mode 100644 modules/interact/issue_create.go create mode 100644 modules/task/issue_create.go diff --git a/cmd/issues/create.go b/cmd/issues/create.go index f4fa875..12eb0fd 100644 --- a/cmd/issues/create.go +++ b/cmd/issues/create.go @@ -5,14 +5,11 @@ package issues import ( - "fmt" - "log" - "code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/modules/config" - "code.gitea.io/tea/modules/print" + "code.gitea.io/tea/modules/interact" + "code.gitea.io/tea/modules/task" - "code.gitea.io/sdk/gitea" "github.com/urfave/cli/v2" ) @@ -39,23 +36,15 @@ var CmdIssuesCreate = cli.Command{ func runIssuesCreate(ctx *cli.Context) error { login, owner, repo := config.InitCommand(flags.GlobalRepoValue, flags.GlobalLoginValue, flags.GlobalRemoteValue) - issue, _, err := login.Client().CreateIssue(owner, repo, gitea.CreateIssueOption{ - Title: ctx.String("title"), - Body: ctx.String("body"), - // TODO: - //Assignee string `json:"assignee"` - //Assignees []string `json:"assignees"` - //Deadline *time.Time `json:"due_date"` - //Milestone int64 `json:"milestone"` - //Labels []int64 `json:"labels"` - //Closed bool `json:"closed"` - }) - - if err != nil { - log.Fatal(err) + if ctx.NumFlags() == 0 { + return interact.CreateIssue(login, owner, repo) } - print.IssueDetails(issue) - fmt.Println(issue.HTMLURL) - return nil + return task.CreateIssue( + login, + owner, + repo, + ctx.String("title"), + ctx.String("body"), + ) } diff --git a/modules/interact/issue_create.go b/modules/interact/issue_create.go new file mode 100644 index 0000000..6eca95b --- /dev/null +++ b/modules/interact/issue_create.go @@ -0,0 +1,43 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package interact + +import ( + "code.gitea.io/tea/modules/config" + "code.gitea.io/tea/modules/task" + + "github.com/AlecAivazis/survey/v2" +) + +// CreateIssue interactively creates a PR +func CreateIssue(login *config.Login, owner, repo string) error { + var title, description string + + // owner, repo + owner, repo, err := promptRepoSlug(owner, repo) + if err != nil { + return err + } + + // title + promptOpts := survey.WithValidator(survey.Required) + promptI := &survey.Input{Message: "Issue title:"} + if err := survey.AskOne(promptI, &title, promptOpts); err != nil { + return err + } + + // description + promptM := &survey.Multiline{Message: "Issue description:"} + if err := survey.AskOne(promptM, &description); err != nil { + return err + } + + return task.CreateIssue( + login, + owner, + repo, + title, + description) +} diff --git a/modules/interact/prompts.go b/modules/interact/prompts.go index bd94207..89c22b6 100644 --- a/modules/interact/prompts.go +++ b/modules/interact/prompts.go @@ -5,6 +5,9 @@ package interact import ( + "fmt" + "strings" + "github.com/AlecAivazis/survey/v2" ) @@ -14,3 +17,43 @@ func PromptPassword(name string) (pass string, err error) { err = survey.AskOne(promptPW, &pass, survey.WithValidator(survey.Required)) return } + +// promptRepoSlug interactively prompts for a Gitea repository or returns the current one +func promptRepoSlug(defaultOwner, defaultRepo string) (owner, repo string, err error) { + prompt := "Target repo:" + required := true + if len(defaultOwner) != 0 && len(defaultRepo) != 0 { + prompt = fmt.Sprintf("Target repo [%s/%s]:", defaultOwner, defaultRepo) + required = false + } + var repoSlug string + + owner = defaultOwner + repo = defaultRepo + + err = survey.AskOne( + &survey.Input{Message: prompt}, + &repoSlug, + survey.WithValidator(func(input interface{}) error { + if str, ok := input.(string); ok { + if !required && len(str) == 0 { + return nil + } + split := strings.Split(str, "/") + if len(split) != 2 || len(split[0]) == 0 || len(split[1]) == 0 { + return fmt.Errorf("must follow the / syntax") + } + } else { + return fmt.Errorf("invalid result type") + } + return nil + }), + ) + + if err == nil && len(repoSlug) != 0 { + repoSlugSplit := strings.Split(repoSlug, "/") + owner = repoSlugSplit[0] + repo = repoSlugSplit[1] + } + return +} diff --git a/modules/interact/pull_create.go b/modules/interact/pull_create.go index a1ec947..ff14e99 100644 --- a/modules/interact/pull_create.go +++ b/modules/interact/pull_create.go @@ -5,9 +5,6 @@ package interact import ( - "fmt" - "strings" - "code.gitea.io/tea/modules/config" "code.gitea.io/tea/modules/git" "code.gitea.io/tea/modules/task" @@ -92,42 +89,3 @@ func CreatePull(login *config.Login, owner, repo string) error { title, description) } - -func promptRepoSlug(defaultOwner, defaultRepo string) (owner, repo string, err error) { - prompt := "Target repo:" - required := true - if len(defaultOwner) != 0 && len(defaultRepo) != 0 { - prompt = fmt.Sprintf("Target repo [%s/%s]:", defaultOwner, defaultRepo) - required = false - } - var repoSlug string - - owner = defaultOwner - repo = defaultRepo - - err = survey.AskOne( - &survey.Input{Message: prompt}, - &repoSlug, - survey.WithValidator(func(input interface{}) error { - if str, ok := input.(string); ok { - if !required && len(str) == 0 { - return nil - } - split := strings.Split(str, "/") - if len(split) != 2 || len(split[0]) == 0 || len(split[1]) == 0 { - return fmt.Errorf("must follow the / syntax") - } - } else { - return fmt.Errorf("invalid result type") - } - return nil - }), - ) - - if err == nil && len(repoSlug) != 0 { - repoSlugSplit := strings.Split(repoSlug, "/") - owner = repoSlugSplit[0] - repo = repoSlugSplit[1] - } - return -} diff --git a/modules/task/issue_create.go b/modules/task/issue_create.go new file mode 100644 index 0000000..3808a9f --- /dev/null +++ b/modules/task/issue_create.go @@ -0,0 +1,45 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// Use of this source code is governed by a MIT-style +// license that can be found in the LICENSE file. + +package task + +import ( + "fmt" + "log" + + "code.gitea.io/sdk/gitea" + "code.gitea.io/tea/modules/config" + "code.gitea.io/tea/modules/print" +) + +// CreateIssue creates a PR in the given repo and prints the result +func CreateIssue(login *config.Login, repoOwner, repoName, title, description string) error { + + // title is required + if len(title) == 0 { + return fmt.Errorf("Title is required") + } + + issue, _, err := login.Client().CreateIssue(repoOwner, repoName, gitea.CreateIssueOption{ + Title: title, + Body: description, + // TODO: + //Assignee string `json:"assignee"` + //Assignees []string `json:"assignees"` + //Deadline *time.Time `json:"due_date"` + //Milestone int64 `json:"milestone"` + //Labels []int64 `json:"labels"` + //Closed bool `json:"closed"` + }) + + if err != nil { + log.Fatalf("could not create issue: %s", err) + } + + print.IssueDetails(issue) + + fmt.Println(issue.HTMLURL) + + return err +}