mirror of
https://gitea.com/jolheiser/sip
synced 2024-11-22 19:51:58 +01:00
Add release support and CSV output (#16)
Add CSV output Refactor requireToken and add release creation Start releases Signed-off-by: jolheiser <john.olheiser@gmail.com> Co-authored-by: jolheiser <john.olheiser@gmail.com> Reviewed-on: https://gitea.com/jolheiser/sip/pulls/16
This commit is contained in:
parent
5ea204fb61
commit
0a6162ad05
@ -27,6 +27,7 @@ steps:
|
|||||||
GOPROXY: https://goproxy.cn
|
GOPROXY: https://goproxy.cn
|
||||||
commands:
|
commands:
|
||||||
- make lint
|
- make lint
|
||||||
|
- make vet
|
||||||
|
|
||||||
---
|
---
|
||||||
kind: pipeline
|
kind: pipeline
|
||||||
|
4
Makefile
4
Makefile
@ -28,6 +28,10 @@ lint:
|
|||||||
fi
|
fi
|
||||||
golangci-lint run --timeout 5m
|
golangci-lint run --timeout 5m
|
||||||
|
|
||||||
|
.PHONY: vet
|
||||||
|
vet:
|
||||||
|
$(GO) vet ./...
|
||||||
|
|
||||||
.PHONY: fmt
|
.PHONY: fmt
|
||||||
fmt:
|
fmt:
|
||||||
$(GO) fmt ./...
|
$(GO) fmt ./...
|
||||||
|
56
cmd/cmd.go
56
cmd/cmd.go
@ -54,31 +54,6 @@ var (
|
|||||||
upstreamRepo []string
|
upstreamRepo []string
|
||||||
)
|
)
|
||||||
|
|
||||||
func requireToken(ctx *cli.Context) (string, error) {
|
|
||||||
if ctx.IsSet("token") {
|
|
||||||
return getToken(ctx.String("token")), nil
|
|
||||||
}
|
|
||||||
if len(config.Tokens) == 0 {
|
|
||||||
return "", errors.New(color.Error.Wrap("No tokens found! Add one with #{sip token create}", color.New(color.FgMagenta)))
|
|
||||||
}
|
|
||||||
tokenMap := make(map[string]config.Token)
|
|
||||||
opts := make([]string, len(config.Tokens))
|
|
||||||
for idx, token := range config.Tokens {
|
|
||||||
key := fmt.Sprintf("%s (%s)", token.Name, token.URL)
|
|
||||||
tokenMap[key] = token
|
|
||||||
opts[idx] = key
|
|
||||||
}
|
|
||||||
|
|
||||||
question := &survey.Select{Message: "This action requires an access token", Options: opts}
|
|
||||||
var answer string
|
|
||||||
|
|
||||||
if err := survey.AskOne(question, &answer); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
|
|
||||||
return tokenMap[answer].Token, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func getToken(name string) string {
|
func getToken(name string) string {
|
||||||
for _, token := range config.Tokens {
|
for _, token := range config.Tokens {
|
||||||
if name == token.Name {
|
if name == token.Name {
|
||||||
@ -88,8 +63,35 @@ func getToken(name string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func getClient(ctx *cli.Context) *gitea.Client {
|
func getClient(ctx *cli.Context, requireToken bool) (*gitea.Client, error) {
|
||||||
return gitea.NewClient(ctx.String("url"), getToken(ctx.String("token")))
|
if ctx.IsSet("token") {
|
||||||
|
return gitea.NewClient(ctx.String("url"), getToken(ctx.String("token"))), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
var token string
|
||||||
|
if requireToken {
|
||||||
|
if len(config.Tokens) == 0 {
|
||||||
|
return nil, errors.New(color.Error.Wrap("No tokens found! Add one with #{sip token create}", color.New(color.FgMagenta)))
|
||||||
|
}
|
||||||
|
tokenMap := make(map[string]config.Token)
|
||||||
|
opts := make([]string, len(config.Tokens))
|
||||||
|
for idx, token := range config.Tokens {
|
||||||
|
key := fmt.Sprintf("%s (%s)", token.Name, token.URL)
|
||||||
|
tokenMap[key] = token
|
||||||
|
opts[idx] = key
|
||||||
|
}
|
||||||
|
|
||||||
|
question := &survey.Select{Message: "This action requires an access token", Options: opts}
|
||||||
|
var answer string
|
||||||
|
|
||||||
|
if err := survey.AskOne(question, &answer); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
token = tokenMap[answer].Token
|
||||||
|
}
|
||||||
|
|
||||||
|
return gitea.NewClient(ctx.String("url"), token), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func defRemote(remote, def string) string {
|
func defRemote(remote, def string) string {
|
||||||
|
@ -4,12 +4,14 @@ import (
|
|||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"gitea.com/jolheiser/sip/modules/csv"
|
||||||
"gitea.com/jolheiser/sip/modules/markdown"
|
"gitea.com/jolheiser/sip/modules/markdown"
|
||||||
"gitea.com/jolheiser/sip/modules/sdk"
|
"gitea.com/jolheiser/sip/modules/sdk"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"go.jolheiser.com/beaver"
|
"go.jolheiser.com/beaver"
|
||||||
"go.jolheiser.com/beaver/color"
|
"go.jolheiser.com/beaver/color"
|
||||||
|
"os"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
@ -22,6 +24,12 @@ var Issues = cli.Command{
|
|||||||
Subcommands: []*cli.Command{
|
Subcommands: []*cli.Command{
|
||||||
&IssuesCreate,
|
&IssuesCreate,
|
||||||
},
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "csv",
|
||||||
|
Usage: "Output results to a CSV file",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func doIssuesSearch(ctx *cli.Context) error {
|
func doIssuesSearch(ctx *cli.Context) error {
|
||||||
@ -32,11 +40,16 @@ func doIssuesSearch(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func issuesSearch(ctx *cli.Context, pulls bool) (*gitea.Issue, error) {
|
func issuesSearch(ctx *cli.Context, pulls bool) (*gitea.Issue, error) {
|
||||||
|
client, err := getClient(ctx, false)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
typ := "issues"
|
typ := "issues"
|
||||||
if pulls {
|
if pulls {
|
||||||
typ = "pulls"
|
typ = "pulls"
|
||||||
}
|
}
|
||||||
issues, err := queryIssues(ctx, getClient(ctx), pulls)
|
issues, err := queryIssues(ctx, client, pulls)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -46,6 +59,18 @@ func issuesSearch(ctx *cli.Context, pulls bool) (*gitea.Issue, error) {
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ctx.String("csv") != "" {
|
||||||
|
fi, err := os.Create(ctx.String("csv"))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if _, err := fi.WriteString(csv.Issues(issues)); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
fmt.Println(color.FgCyan.Formatf("Matching %s were exported to", typ), color.Info.Format(ctx.String("csv")))
|
||||||
|
return nil, fi.Close()
|
||||||
|
}
|
||||||
|
|
||||||
issueMap := make(map[string]*gitea.Issue)
|
issueMap := make(map[string]*gitea.Issue)
|
||||||
for _, issue := range issues {
|
for _, issue := range issues {
|
||||||
index := color.New(color.FgCyan).Format("#" + strconv.Itoa(int(issue.Index)))
|
index := color.New(color.FgCyan).Format("#" + strconv.Itoa(int(issue.Index)))
|
||||||
@ -87,29 +112,20 @@ func issuesSearch(ctx *cli.Context, pulls bool) (*gitea.Issue, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func queryIssues(ctx *cli.Context, client *gitea.Client, pulls bool) ([]*gitea.Issue, error) {
|
func queryIssues(ctx *cli.Context, client *gitea.Client, pulls bool) ([]*gitea.Issue, error) {
|
||||||
questions := []*survey.Question{
|
owner, repo, err := askOwnerRepo(ctx)
|
||||||
{
|
if err != nil {
|
||||||
Name: "repo",
|
|
||||||
Prompt: &survey.Input{Message: "Full repository name", Default: fullName(ctx)},
|
|
||||||
Validate: validateFullName,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
Name: "query",
|
|
||||||
Prompt: &survey.Input{Message: "Search query"},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
answers := struct {
|
|
||||||
Repo string
|
|
||||||
Query string
|
|
||||||
}{}
|
|
||||||
|
|
||||||
if err := survey.Ask(questions, &answers); err != nil {
|
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
filter := sdk.NewIssueFilter(answers.Query)
|
|
||||||
ownerRepo := strings.Split(answers.Repo, "/")
|
question := &survey.Input{Message: "Search query"}
|
||||||
|
var answer string
|
||||||
|
if err := survey.AskOne(question, &answer); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
filter := sdk.NewIssueFilter(answer)
|
||||||
opts := gitea.ListIssueOption{KeyWord: filter.Query, State: "all"}
|
opts := gitea.ListIssueOption{KeyWord: filter.Query, State: "all"}
|
||||||
issues, err := sdk.GetIssues(client, ownerRepo[0], ownerRepo[1], opts)
|
issues, err := sdk.GetIssues(client, owner, repo, opts)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -132,6 +148,26 @@ func queryIssues(ctx *cli.Context, client *gitea.Client, pulls bool) ([]*gitea.I
|
|||||||
return filtered, nil
|
return filtered, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func askOwnerRepo(ctx *cli.Context) (string, string, error) {
|
||||||
|
question := []*survey.Question{
|
||||||
|
{
|
||||||
|
Name: "repo",
|
||||||
|
Prompt: &survey.Input{Message: "Full repository name", Default: fullName(ctx)},
|
||||||
|
Validate: validateFullName,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
answer := struct {
|
||||||
|
Repo string
|
||||||
|
}{}
|
||||||
|
|
||||||
|
if err := survey.Ask(question, &answer); err != nil {
|
||||||
|
return "", "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
ownerRepo := strings.Split(answer.Repo, "/")
|
||||||
|
return ownerRepo[0], ownerRepo[1], nil
|
||||||
|
}
|
||||||
|
|
||||||
func validateFullName(ans interface{}) error {
|
func validateFullName(ans interface{}) error {
|
||||||
fullName := ans.(string)
|
fullName := ans.(string)
|
||||||
ownerRepo := strings.Split(fullName, "/")
|
ownerRepo := strings.Split(fullName, "/")
|
||||||
|
@ -21,7 +21,7 @@ func doIssueCreate(ctx *cli.Context) error {
|
|||||||
url := color.New(color.FgYellow).Format(fmt.Sprintf("%s/%s/%s", ctx.String("url"), ctx.String("owner"), ctx.String("repo")))
|
url := color.New(color.FgYellow).Format(fmt.Sprintf("%s/%s/%s", ctx.String("url"), ctx.String("owner"), ctx.String("repo")))
|
||||||
fmt.Println(color.New(color.FgCyan).Format("Creating a new issue for"), url)
|
fmt.Println(color.New(color.FgCyan).Format("Creating a new issue for"), url)
|
||||||
|
|
||||||
token, err := requireToken(ctx)
|
client, err := getClient(ctx, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -65,8 +65,6 @@ func doIssueCreate(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
client := gitea.NewClient(ctx.String("url"), token)
|
|
||||||
|
|
||||||
issue, err := client.CreateIssue(ctx.String("owner"), ctx.String("repo"), gitea.CreateIssueOption{Title: title, Body: body})
|
issue, err := client.CreateIssue(ctx.String("owner"), ctx.String("repo"), gitea.CreateIssueOption{Title: title, Body: body})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -14,6 +14,12 @@ var Pulls = cli.Command{
|
|||||||
&PullsStatus,
|
&PullsStatus,
|
||||||
&PullsCheckout,
|
&PullsCheckout,
|
||||||
},
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "csv",
|
||||||
|
Usage: "Output results to a CSV file",
|
||||||
|
},
|
||||||
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func doPullsSearch(ctx *cli.Context) error {
|
func doPullsSearch(ctx *cli.Context) error {
|
||||||
|
@ -21,6 +21,11 @@ var PullsCheckout = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func doPullCheckout(ctx *cli.Context) error {
|
func doPullCheckout(ctx *cli.Context) error {
|
||||||
|
client, err := getClient(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
var issue *gitea.Issue
|
var issue *gitea.Issue
|
||||||
questions := []*survey.Question{
|
questions := []*survey.Question{
|
||||||
{
|
{
|
||||||
@ -50,7 +55,7 @@ func doPullCheckout(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
iss, err := getClient(ctx).GetIssue(upstreamRepo[1], upstreamRepo[2], prNum.Index)
|
iss, err := client.GetIssue(upstreamRepo[1], upstreamRepo[2], prNum.Index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -22,13 +22,11 @@ func doPullCreate(ctx *cli.Context) error {
|
|||||||
url := color.New(color.FgYellow).Format(fmt.Sprintf("%s/%s/%s", ctx.String("url"), ctx.String("owner"), ctx.String("repo")))
|
url := color.New(color.FgYellow).Format(fmt.Sprintf("%s/%s/%s", ctx.String("url"), ctx.String("owner"), ctx.String("repo")))
|
||||||
fmt.Println(color.New(color.FgCyan).Format("Creating a new pull request for"), url)
|
fmt.Println(color.New(color.FgCyan).Format("Creating a new pull request for"), url)
|
||||||
|
|
||||||
token, err := requireToken(ctx)
|
client, err := getClient(ctx, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
client := gitea.NewClient(ctx.String("url"), token)
|
|
||||||
|
|
||||||
upstreams, err := client.ListRepoBranches(getUpstreamRepo()[1], getUpstreamRepo()[2])
|
upstreams, err := client.ListRepoBranches(getUpstreamRepo()[1], getUpstreamRepo()[2])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -17,7 +17,11 @@ var PullsStatus = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func doPullStatus(ctx *cli.Context) error {
|
func doPullStatus(ctx *cli.Context) error {
|
||||||
client := getClient(ctx)
|
client, err := getClient(ctx, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
head := fmt.Sprintf("%s:%s", getOriginRepo()[1], git.Branch())
|
head := fmt.Sprintf("%s:%s", getOriginRepo()[1], git.Branch())
|
||||||
|
|
||||||
pulls, err := sdk.GetPulls(client, getUpstreamRepo()[1], getUpstreamRepo()[2], gitea.ListPullRequestsOptions{State: "all"})
|
pulls, err := sdk.GetPulls(client, getUpstreamRepo()[1], getUpstreamRepo()[2], gitea.ListPullRequestsOptions{State: "all"})
|
||||||
|
80
cmd/release.go
Normal file
80
cmd/release.go
Normal file
@ -0,0 +1,80 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.gitea.io/sdk/gitea"
|
||||||
|
"fmt"
|
||||||
|
"gitea.com/jolheiser/sip/modules/csv"
|
||||||
|
"gitea.com/jolheiser/sip/modules/markdown"
|
||||||
|
"github.com/AlecAivazis/survey/v2"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
"go.jolheiser.com/beaver/color"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var Release = cli.Command{
|
||||||
|
Name: "releases",
|
||||||
|
Aliases: []string{"release"},
|
||||||
|
Usage: "Commands for interacting with releases",
|
||||||
|
Action: doRelease,
|
||||||
|
Subcommands: []*cli.Command{
|
||||||
|
&ReleaseCreate,
|
||||||
|
},
|
||||||
|
Flags: []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "csv",
|
||||||
|
Usage: "Output results to a CSV file",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
func doRelease(ctx *cli.Context) error {
|
||||||
|
client, err := getClient(ctx, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
owner, repo, err := askOwnerRepo(ctx)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
releases, err := client.ListReleases(owner, repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
if ctx.String("csv") != "" {
|
||||||
|
fi, err := os.Create(ctx.String("csv"))
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if _, err := fi.WriteString(csv.Releases(releases)); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
fmt.Println(color.FgCyan.Format("Releases were exported to"), color.Info.Format(ctx.String("csv")))
|
||||||
|
return fi.Close()
|
||||||
|
}
|
||||||
|
|
||||||
|
releaseMap := make(map[string]*gitea.Release)
|
||||||
|
releaseList := make([]string, len(releases))
|
||||||
|
for idx, release := range releases {
|
||||||
|
key := fmt.Sprintf("%s (%s)", release.Title, release.TagName)
|
||||||
|
releaseMap[key] = release
|
||||||
|
releaseList[idx] = key
|
||||||
|
}
|
||||||
|
|
||||||
|
sel := &survey.Select{Options: releaseList, Message: "Releases"}
|
||||||
|
var selection string
|
||||||
|
if err := survey.AskOne(sel, &selection); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
note, err := markdown.Render(releaseMap[selection].Note)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println(note)
|
||||||
|
fmt.Printf("Release Date: %s\n", releaseMap[selection].PublishedAt.Format(csv.TimeFormat))
|
||||||
|
return nil
|
||||||
|
}
|
87
cmd/release_create.go
Normal file
87
cmd/release_create.go
Normal file
@ -0,0 +1,87 @@
|
|||||||
|
package cmd
|
||||||
|
|
||||||
|
import (
|
||||||
|
"code.gitea.io/sdk/gitea"
|
||||||
|
"fmt"
|
||||||
|
"gitea.com/jolheiser/sip/modules/git"
|
||||||
|
"github.com/AlecAivazis/survey/v2"
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
"go.jolheiser.com/beaver/color"
|
||||||
|
)
|
||||||
|
|
||||||
|
var ReleaseCreate = cli.Command{
|
||||||
|
Name: "create",
|
||||||
|
Aliases: []string{"new"},
|
||||||
|
Usage: "Create a new release",
|
||||||
|
Action: doReleaseCreate,
|
||||||
|
}
|
||||||
|
|
||||||
|
func doReleaseCreate(ctx *cli.Context) error {
|
||||||
|
client, err := getClient(ctx, true)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
questions := []*survey.Question{
|
||||||
|
{
|
||||||
|
Name: "tag",
|
||||||
|
Prompt: &survey.Input{Message: "Tag Name"},
|
||||||
|
Validate: survey.Required,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "target",
|
||||||
|
Prompt: &survey.Input{Message: "Target", Default: git.Branch(), Help: "Target ref, branch name or commit SHA"},
|
||||||
|
Validate: survey.Required,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "title",
|
||||||
|
Prompt: &survey.Input{Message: "Title"},
|
||||||
|
Validate: survey.Required,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "note",
|
||||||
|
Prompt: &survey.Multiline{Message: "Notes"},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "draft",
|
||||||
|
Prompt: &survey.Confirm{Message: "Draft", Default: false},
|
||||||
|
Validate: survey.Required,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
Name: "pre",
|
||||||
|
Prompt: &survey.Confirm{Message: "Pre-Release", Default: false},
|
||||||
|
Validate: survey.Required,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
answers := struct {
|
||||||
|
Tag string
|
||||||
|
Target string
|
||||||
|
Title string
|
||||||
|
Note string
|
||||||
|
Draft bool
|
||||||
|
Pre bool
|
||||||
|
}{}
|
||||||
|
|
||||||
|
if err := survey.Ask(questions, &answers); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
release, err := client.CreateRelease(ctx.String("owner"), ctx.String("repo"), gitea.CreateReleaseOption{
|
||||||
|
TagName: answers.Tag,
|
||||||
|
Target: answers.Target,
|
||||||
|
Title: answers.Title,
|
||||||
|
Note: answers.Note,
|
||||||
|
IsDraft: answers.Draft,
|
||||||
|
IsPrerelease: answers.Pre,
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
info := color.Info
|
||||||
|
cyan := color.New(color.FgCyan)
|
||||||
|
fmt.Println(info.Format("Release"), cyan.Format(release.TagName), info.Format("created!"))
|
||||||
|
// TODO Change to specific release page once supported
|
||||||
|
fmt.Println(cyan.Format(fmt.Sprintf("%s/%s/%s/releases/", ctx.String("url"), ctx.String("owner"), ctx.String("repo"))))
|
||||||
|
return nil
|
||||||
|
}
|
@ -19,7 +19,10 @@ var Repo = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func doRepo(ctx *cli.Context) error {
|
func doRepo(ctx *cli.Context) error {
|
||||||
client := getClient(ctx)
|
client, err := getClient(ctx, false)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
issues, err := sdk.GetIssues(client, ctx.String("owner"), ctx.String("repo"), gitea.ListIssueOption{State: "open"})
|
issues, err := sdk.GetIssues(client, ctx.String("owner"), ctx.String("repo"), gitea.ListIssueOption{State: "open"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -16,13 +16,11 @@ var RepoCreate = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func doRepoCreate(ctx *cli.Context) error {
|
func doRepoCreate(ctx *cli.Context) error {
|
||||||
token, err := requireToken(ctx)
|
client, err := getClient(ctx, true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
client := gitea.NewClient(ctx.String("url"), token)
|
|
||||||
|
|
||||||
questions := []*survey.Question{
|
questions := []*survey.Question{
|
||||||
{
|
{
|
||||||
Name: "name",
|
Name: "name",
|
||||||
|
2
go.mod
2
go.mod
@ -3,7 +3,7 @@ module gitea.com/jolheiser/sip
|
|||||||
go 1.13
|
go 1.13
|
||||||
|
|
||||||
require (
|
require (
|
||||||
code.gitea.io/sdk/gitea v0.11.0
|
code.gitea.io/sdk/gitea v0.11.2
|
||||||
github.com/AlecAivazis/survey/v2 v2.0.5
|
github.com/AlecAivazis/survey/v2 v2.0.5
|
||||||
github.com/BurntSushi/toml v0.3.1
|
github.com/BurntSushi/toml v0.3.1
|
||||||
github.com/charmbracelet/glamour v0.1.0
|
github.com/charmbracelet/glamour v0.1.0
|
||||||
|
8
go.sum
8
go.sum
@ -1,7 +1,5 @@
|
|||||||
code.gitea.io/sdk/gitea v0.11.0 h1:XgZtmImZsjMC+Z1WBfO6bYTCOJiGp+7w0HKmfhTwytw=
|
code.gitea.io/sdk/gitea v0.11.2 h1:D0xIRlHv3IckzdYOWzHK1bPvlkXdA4LD909UYyBdi1o=
|
||||||
code.gitea.io/sdk/gitea v0.11.0/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY=
|
code.gitea.io/sdk/gitea v0.11.2/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY=
|
||||||
go.jolheiser.com/beaver v1.0.0 h1:IfNMhp7+DUaM0kaNwho4RWfuebCsa8A/kxtZBngFjHk=
|
|
||||||
go.jolheiser.com/beaver v1.0.0/go.mod h1:2mUGl6ZGKY/Y9u36iR4bqOPrHhr4C22cxkR8ei2G06I=
|
|
||||||
github.com/AlecAivazis/survey/v2 v2.0.5 h1:xpZp+Q55wi5C7Iaze+40onHnEkex1jSc34CltJjOoPM=
|
github.com/AlecAivazis/survey/v2 v2.0.5 h1:xpZp+Q55wi5C7Iaze+40onHnEkex1jSc34CltJjOoPM=
|
||||||
github.com/AlecAivazis/survey/v2 v2.0.5/go.mod h1:WYBhg6f0y/fNYUuesWQc0PKbJcEliGcYHB9sNT3Bg74=
|
github.com/AlecAivazis/survey/v2 v2.0.5/go.mod h1:WYBhg6f0y/fNYUuesWQc0PKbJcEliGcYHB9sNT3Bg74=
|
||||||
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
|
||||||
@ -127,8 +125,6 @@ golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5h
|
|||||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190530182044-ad28b68e88f1/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20190813064441-fde4db37ae7a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 h1:sfkvUWPNGwSV+8/fNqctR5lS2AqCSqYwXdrjCxp/dXo=
|
|
||||||
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae h1:/WDfKMnPU+m5M4xB+6x4kaepxRw6jWvR5iDRdvjHgy8=
|
||||||
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
|
||||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||||
|
1
main.go
1
main.go
@ -23,6 +23,7 @@ func main() {
|
|||||||
&cmd.Repo,
|
&cmd.Repo,
|
||||||
&cmd.Issues,
|
&cmd.Issues,
|
||||||
&cmd.Pulls,
|
&cmd.Pulls,
|
||||||
|
&cmd.Release,
|
||||||
}
|
}
|
||||||
app.Flags = cmd.Flags
|
app.Flags = cmd.Flags
|
||||||
app.EnableBashCompletion = true
|
app.EnableBashCompletion = true
|
||||||
|
93
modules/csv/csv.go
Normal file
93
modules/csv/csv.go
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
package csv
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"code.gitea.io/sdk/gitea"
|
||||||
|
)
|
||||||
|
|
||||||
|
const TimeFormat = "Jan 2, 2006 at 03:04 PM"
|
||||||
|
|
||||||
|
func Issues(issues []*gitea.Issue) string {
|
||||||
|
headers := "ID,Index,Author,Title,Body,Labels,Milestone,Assignee,State,Created,Updated,Closed\r\n"
|
||||||
|
|
||||||
|
// Sort the issues coming in
|
||||||
|
sort.Slice(issues, func(i, j int) bool {
|
||||||
|
return issues[i].ID < issues[j].ID
|
||||||
|
})
|
||||||
|
|
||||||
|
rows := make([]string, 0)
|
||||||
|
for _, issue := range issues {
|
||||||
|
cols := make([]string, 12)
|
||||||
|
cols[0] = fmt.Sprintf("%d", issue.ID)
|
||||||
|
cols[1] = fmt.Sprintf("%d", issue.Index)
|
||||||
|
if issue.Poster != nil {
|
||||||
|
cols[2] = issue.Poster.UserName
|
||||||
|
}
|
||||||
|
cols[3] = issue.Title
|
||||||
|
cols[4] = issue.Body
|
||||||
|
labels := make([]string, 0)
|
||||||
|
for _, lbl := range issue.Labels {
|
||||||
|
labels = append(labels, lbl.Name)
|
||||||
|
}
|
||||||
|
cols[5] = strings.Join(labels, ",")
|
||||||
|
if issue.Milestone != nil {
|
||||||
|
cols[6] = issue.Milestone.Title
|
||||||
|
}
|
||||||
|
if issue.Assignee != nil {
|
||||||
|
cols[7] = issue.Assignee.UserName
|
||||||
|
}
|
||||||
|
state := string(issue.State)
|
||||||
|
if issue.PullRequest != nil && issue.PullRequest.HasMerged {
|
||||||
|
state = "merged"
|
||||||
|
}
|
||||||
|
cols[8] = state
|
||||||
|
cols[9] = issue.Created.Format(TimeFormat)
|
||||||
|
cols[10] = issue.Updated.Format(TimeFormat)
|
||||||
|
if issue.Closed != nil {
|
||||||
|
cols[11] = issue.Closed.Format(TimeFormat)
|
||||||
|
}
|
||||||
|
for idx, col := range cols {
|
||||||
|
cols[idx] = escape(col)
|
||||||
|
}
|
||||||
|
rows = append(rows, strings.Join(cols, ","))
|
||||||
|
}
|
||||||
|
return headers + strings.Join(rows, "\r\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func Releases(releases []*gitea.Release) string {
|
||||||
|
headers := "ID,Tag Name,Target,Title,Body,Draft,Pre-Release,Created,Published,Publisher\r\n"
|
||||||
|
|
||||||
|
// Sort the releases coming in
|
||||||
|
sort.Slice(releases, func(i, j int) bool {
|
||||||
|
return releases[i].ID < releases[j].ID
|
||||||
|
})
|
||||||
|
|
||||||
|
rows := make([]string, 0)
|
||||||
|
for _, release := range releases {
|
||||||
|
cols := make([]string, 10)
|
||||||
|
cols[0] = fmt.Sprintf("%d", release.ID)
|
||||||
|
cols[1] = release.TagName
|
||||||
|
cols[2] = release.Target
|
||||||
|
cols[3] = release.Title
|
||||||
|
cols[4] = release.Note
|
||||||
|
cols[5] = fmt.Sprintf("%t", release.IsDraft)
|
||||||
|
cols[6] = fmt.Sprintf("%t", release.IsPrerelease)
|
||||||
|
cols[7] = release.CreatedAt.Format(TimeFormat)
|
||||||
|
cols[8] = release.PublishedAt.Format(TimeFormat)
|
||||||
|
if release.Publisher != nil {
|
||||||
|
cols[9] = release.Publisher.UserName
|
||||||
|
}
|
||||||
|
for idx, col := range cols {
|
||||||
|
cols[idx] = escape(col)
|
||||||
|
}
|
||||||
|
rows = append(rows, strings.Join(cols, ","))
|
||||||
|
}
|
||||||
|
return headers + strings.Join(rows, "\r\n")
|
||||||
|
}
|
||||||
|
|
||||||
|
func escape(input string) string {
|
||||||
|
return fmt.Sprintf(`"%s"`, strings.ReplaceAll(input, `"`, `""`))
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user