mirror of
https://gitea.com/jolheiser/sip
synced 2024-11-22 19:51:58 +01:00
Refactor (#29)
Clean up docs Signed-off-by: jolheiser <john.olheiser@gmail.com> Add generated docs Signed-off-by: jolheiser <john.olheiser@gmail.com> Update go.sum Signed-off-by: jolheiser <john.olheiser@gmail.com> Fix remote parsing Signed-off-by: jolheiser <john.olheiser@gmail.com> Refactor and clean up Signed-off-by: jolheiser <john.olheiser@gmail.com> Co-authored-by: jolheiser <john.olheiser@gmail.com> Reviewed-on: https://gitea.com/jolheiser/sip/pulls/29
This commit is contained in:
parent
a51305f816
commit
894a641ef8
7
LICENSE
Normal file
7
LICENSE
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
Copyright 2020 John Olheiser
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
4
Makefile
4
Makefile
@ -32,6 +32,10 @@ fmt:
|
|||||||
test:
|
test:
|
||||||
$(GO) test -race ./...
|
$(GO) test -race ./...
|
||||||
|
|
||||||
|
.PHONY: docs
|
||||||
|
docs:
|
||||||
|
$(GO) run docs.go
|
||||||
|
|
||||||
.PHONY: release
|
.PHONY: release
|
||||||
release: release-dirs check-xgo release-windows release-linux release-darwin release-copy release-compress release-check
|
release: release-dirs check-xgo release-windows release-linux release-darwin release-copy release-compress release-check
|
||||||
|
|
||||||
|
16
README.md
16
README.md
@ -1,12 +1,14 @@
|
|||||||
# Sip (alternative)
|
# Sip
|
||||||
CLI for interacting with Gitea
|
CLI for interacting with Gitea
|
||||||
|
|
||||||
[![Build Status](https://drone.gitea.com/api/badges/jolheiser/sip/status.svg)](https://drone.gitea.com/jolheiser/sip)
|
[![Build Status](https://drone.gitea.com/api/badges/jolheiser/sip/status.svg)](https://drone.gitea.com/jolheiser/sip)
|
||||||
|
|
||||||
|
[Docs](docs.md)
|
||||||
|
|
||||||
### Features
|
### Features
|
||||||
|
|
||||||
Understands the concepts of an origin vs remote repository.
|
Understands the concepts of an origin vs remote repository.
|
||||||
By default uses remotes `origin` and `upstream`.
|
By default, uses remotes `origin` and `upstream`.
|
||||||
If no `upstream` repository is found, `upstream` becomes synonymous with `origin` for the sake of defaults.
|
If no `upstream` repository is found, `upstream` becomes synonymous with `origin` for the sake of defaults.
|
||||||
|
|
||||||
* Configuration `sip config`
|
* Configuration `sip config`
|
||||||
@ -28,6 +30,12 @@ If no `upstream` repository is found, `upstream` becomes synonymous with `origin
|
|||||||
* Create a new pull request `sip pulls create`
|
* Create a new pull request `sip pulls create`
|
||||||
* Check pull request status (default based on current branch) `sip pulls status`
|
* Check pull request status (default based on current branch) `sip pulls status`
|
||||||
* Checkout a pull request to test locally `sip pulls checkout`
|
* Checkout a pull request to test locally `sip pulls checkout`
|
||||||
|
* Release search `sip release`
|
||||||
|
* Create a new release `sip release create`
|
||||||
|
* Attach files to an existing release `sip release attach`
|
||||||
|
* Open item in a web browser
|
||||||
|
* Repository `sip open` or `sip open owner/repo`
|
||||||
|
* Issue or PR `sip open 1234` or `sip open owner/repo/1234`
|
||||||
|
|
||||||
### Search filters
|
### Search filters
|
||||||
Sip supports certain search filters for issues/PRs.
|
Sip supports certain search filters for issues/PRs.
|
||||||
@ -39,3 +47,7 @@ Anything in the query that doesn't match one of the below filters will be sent a
|
|||||||
* Milestone `mileston:v1.0.0` - only the last milestone in the query will be applied
|
* Milestone `mileston:v1.0.0` - only the last milestone in the query will be applied
|
||||||
|
|
||||||
e.g. `test is:open query author:jolheiser milestone:0.2.0` will search for issues/PRs with keywords `test query` that are `open`, authored by `jolheiser`, and in the `0.2.0` milestone.
|
e.g. `test is:open query author:jolheiser milestone:0.2.0` will search for issues/PRs with keywords `test query` that are `open`, authored by `jolheiser`, and in the `0.2.0` milestone.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
[MIT](LICENSE)
|
108
cmd/cmd.go
108
cmd/cmd.go
@ -3,10 +3,9 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"sync"
|
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/modules/config"
|
"gitea.com/jolheiser/sip/config"
|
||||||
"gitea.com/jolheiser/sip/modules/git"
|
"gitea.com/jolheiser/sip/flag"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
@ -14,47 +13,25 @@ import (
|
|||||||
"go.jolheiser.com/beaver/color"
|
"go.jolheiser.com/beaver/color"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
func NewApp(version string) *cli.App {
|
||||||
Flags = []cli.Flag{
|
app := cli.NewApp()
|
||||||
&cli.StringFlag{
|
app.Name = "Sip"
|
||||||
Name: "origin",
|
app.Usage = "Command line tool to interact with Gitea"
|
||||||
Usage: "The origin remote",
|
app.Version = version
|
||||||
Value: config.Origin,
|
app.Commands = []*cli.Command{
|
||||||
},
|
&Config,
|
||||||
&cli.StringFlag{
|
&Tokens,
|
||||||
Name: "upstream",
|
&Repo,
|
||||||
Usage: "The upstream remote",
|
&Issues,
|
||||||
Value: config.Upstream,
|
&Pulls,
|
||||||
},
|
&Release,
|
||||||
&cli.StringFlag{
|
&Open,
|
||||||
Name: "url",
|
|
||||||
Aliases: []string{"u"},
|
|
||||||
Usage: "The base URL to the Gitea instance",
|
|
||||||
Value: getUpstreamRepo()[0],
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "owner",
|
|
||||||
Aliases: []string{"o"},
|
|
||||||
Usage: "The owner to target",
|
|
||||||
Value: getUpstreamRepo()[1],
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "repo",
|
|
||||||
Aliases: []string{"r"},
|
|
||||||
Usage: "The repo to target",
|
|
||||||
Value: getUpstreamRepo()[2],
|
|
||||||
},
|
|
||||||
&cli.StringFlag{
|
|
||||||
Name: "token",
|
|
||||||
Aliases: []string{"t"},
|
|
||||||
Usage: "The access token to use (by name)",
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
originOnce sync.Once
|
app.Before = flag.Before
|
||||||
originRepo []string
|
app.Flags = flag.Flags
|
||||||
upstreamOnce sync.Once
|
app.EnableBashCompletion = true
|
||||||
upstreamRepo []string
|
return app
|
||||||
)
|
}
|
||||||
|
|
||||||
func getToken(name string) string {
|
func getToken(name string) string {
|
||||||
for _, token := range config.Tokens {
|
for _, token := range config.Tokens {
|
||||||
@ -65,9 +42,9 @@ func getToken(name string) string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
func getClient(ctx *cli.Context, requireToken bool) (*gitea.Client, error) {
|
func getClient(requireToken bool) (*gitea.Client, error) {
|
||||||
if ctx.IsSet("token") {
|
if flag.Token != "" {
|
||||||
return gitea.NewClient(ctx.String("url"), gitea.SetToken(getToken(ctx.String("token"))))
|
return gitea.NewClient(flag.URL, gitea.SetToken(getToken(flag.Token)))
|
||||||
}
|
}
|
||||||
|
|
||||||
var token string
|
var token string
|
||||||
@ -93,42 +70,5 @@ func getClient(ctx *cli.Context, requireToken bool) (*gitea.Client, error) {
|
|||||||
token = tokenMap[answer].Token
|
token = tokenMap[answer].Token
|
||||||
}
|
}
|
||||||
|
|
||||||
return gitea.NewClient(ctx.String("url"), gitea.SetToken(token))
|
return gitea.NewClient(flag.URL, gitea.SetToken(token))
|
||||||
}
|
|
||||||
|
|
||||||
func defRemote(remote, def string) string {
|
|
||||||
if remote == "" {
|
|
||||||
return def
|
|
||||||
}
|
|
||||||
return remote
|
|
||||||
}
|
|
||||||
|
|
||||||
func getUpstreamRepo() []string {
|
|
||||||
upstreamOnce.Do(func() {
|
|
||||||
var err error
|
|
||||||
upstreamRepo, err = git.GetRepo(defRemote(config.Upstream, "upstream"))
|
|
||||||
if err != nil {
|
|
||||||
upstreamRepo = getOriginRepo()
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return upstreamRepo
|
|
||||||
}
|
|
||||||
|
|
||||||
func getOriginRepo() []string {
|
|
||||||
originOnce.Do(func() {
|
|
||||||
var err error
|
|
||||||
originRepo, err = git.GetRepo(defRemote(config.Origin, "origin"))
|
|
||||||
if err != nil {
|
|
||||||
originRepo = []string{"https://gitea.com", "jolheiser", "sip"}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
return originRepo
|
|
||||||
}
|
|
||||||
|
|
||||||
func fullRepoURL(ctx *cli.Context) string {
|
|
||||||
return ctx.String("url") + "/" + fullName(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
func fullName(ctx *cli.Context) string {
|
|
||||||
return ctx.String("owner") + "/" + ctx.String("repo")
|
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gitea.com/jolheiser/sip/modules/config"
|
"gitea.com/jolheiser/sip/config"
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
@ -34,7 +34,7 @@ func doConfig(ctx *cli.Context) error {
|
|||||||
return doConfigUpstream(ctx)
|
return doConfigUpstream(ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
func doConfigOrigin(ctx *cli.Context) error {
|
func doConfigOrigin(_ *cli.Context) error {
|
||||||
question := &survey.Input{
|
question := &survey.Input{
|
||||||
Message: "Default origin name",
|
Message: "Default origin name",
|
||||||
Default: "origin",
|
Default: "origin",
|
||||||
@ -53,7 +53,7 @@ func doConfigOrigin(ctx *cli.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func doConfigUpstream(ctx *cli.Context) error {
|
func doConfigUpstream(_ *cli.Context) error {
|
||||||
question := &survey.Input{
|
question := &survey.Input{
|
||||||
Message: "Default upstream name",
|
Message: "Default upstream name",
|
||||||
Default: "upstream",
|
Default: "upstream",
|
||||||
|
@ -7,9 +7,10 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/modules/csv"
|
"gitea.com/jolheiser/sip/csv"
|
||||||
"gitea.com/jolheiser/sip/modules/markdown"
|
"gitea.com/jolheiser/sip/flag"
|
||||||
"gitea.com/jolheiser/sip/modules/sdk"
|
"gitea.com/jolheiser/sip/markdown"
|
||||||
|
"gitea.com/jolheiser/sip/sdk"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
@ -29,7 +30,7 @@ var Issues = cli.Command{
|
|||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "csv",
|
Name: "csv",
|
||||||
Usage: "Output results to a CSV file",
|
Usage: "Output results to a CSV file at `PATH`",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -42,7 +43,7 @@ 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)
|
client, err := getClient(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -51,7 +52,7 @@ func issuesSearch(ctx *cli.Context, pulls bool) (*gitea.Issue, error) {
|
|||||||
if pulls {
|
if pulls {
|
||||||
typ = "pulls"
|
typ = "pulls"
|
||||||
}
|
}
|
||||||
issues, err := queryIssues(ctx, client, pulls)
|
issues, err := queryIssues(client, pulls)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -113,8 +114,8 @@ func issuesSearch(ctx *cli.Context, pulls bool) (*gitea.Issue, error) {
|
|||||||
return issueMap[selection], nil
|
return issueMap[selection], nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func queryIssues(ctx *cli.Context, client *gitea.Client, pulls bool) ([]*gitea.Issue, error) {
|
func queryIssues(client *gitea.Client, pulls bool) ([]*gitea.Issue, error) {
|
||||||
owner, repo, err := askOwnerRepo(ctx)
|
owner, repo, err := askOwnerRepo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@ -150,11 +151,15 @@ 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) {
|
func askOwnerRepo() (string, string, error) {
|
||||||
|
// If --owner or --repo was set, assume the user knows where they are searching
|
||||||
|
if flag.OwnerRepoCtxSet {
|
||||||
|
return flag.Owner, flag.Repo, nil
|
||||||
|
}
|
||||||
question := []*survey.Question{
|
question := []*survey.Question{
|
||||||
{
|
{
|
||||||
Name: "repo",
|
Name: "repo",
|
||||||
Prompt: &survey.Input{Message: "Full repository name", Default: fullName(ctx)},
|
Prompt: &survey.Input{Message: "Full repository name", Default: flag.FullName()},
|
||||||
Validate: validateFullName,
|
Validate: validateFullName,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,8 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/modules/markdown"
|
"gitea.com/jolheiser/sip/flag"
|
||||||
|
"gitea.com/jolheiser/sip/markdown"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
@ -18,12 +19,12 @@ var IssuesCreate = cli.Command{
|
|||||||
Action: doIssueCreate,
|
Action: doIssueCreate,
|
||||||
}
|
}
|
||||||
|
|
||||||
func doIssueCreate(ctx *cli.Context) error {
|
func doIssueCreate(_ *cli.Context) error {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
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(flag.FullURL())
|
||||||
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)
|
||||||
|
|
||||||
client, err := getClient(ctx, true)
|
client, err := getClient(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -67,7 +68,7 @@ func doIssueCreate(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
issue, _, err := client.CreateIssue(ctx.String("owner"), ctx.String("repo"), gitea.CreateIssueOption{Title: title, Body: body})
|
issue, _, err := client.CreateIssue(flag.Owner, flag.Repo, gitea.CreateIssueOption{Title: title, Body: body})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -75,6 +76,6 @@ func doIssueCreate(ctx *cli.Context) error {
|
|||||||
info := color.Info
|
info := color.Info
|
||||||
cyan := color.New(color.FgCyan)
|
cyan := color.New(color.FgCyan)
|
||||||
fmt.Println(info.Format("Issue"), cyan.Format(fmt.Sprintf("#%d", issue.Index)), info.Format("created!"))
|
fmt.Println(info.Format("Issue"), cyan.Format(fmt.Sprintf("#%d", issue.Index)), info.Format("created!"))
|
||||||
fmt.Println(cyan.Format(fmt.Sprintf("%s/%s/%s/issues/%d", ctx.String("url"), ctx.String("owner"), ctx.String("repo"), issue.Index)))
|
fmt.Println(cyan.Format(fmt.Sprintf("%s/issues/%d", flag.FullURL(), issue.Index)))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
11
cmd/open.go
11
cmd/open.go
@ -6,6 +6,8 @@ import (
|
|||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"gitea.com/jolheiser/sip/flag"
|
||||||
|
|
||||||
"github.com/skratchdot/open-golang/open"
|
"github.com/skratchdot/open-golang/open"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
)
|
)
|
||||||
@ -18,9 +20,8 @@ var Open = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func doOpen(ctx *cli.Context) error {
|
func doOpen(ctx *cli.Context) error {
|
||||||
repo := fullRepoURL(ctx)
|
|
||||||
if ctx.NArg() == 0 {
|
if ctx.NArg() == 0 {
|
||||||
return open.Run(repo)
|
return open.Run(flag.FullURL())
|
||||||
}
|
}
|
||||||
|
|
||||||
arg := ctx.Args().First()
|
arg := ctx.Args().First()
|
||||||
@ -28,18 +29,18 @@ func doOpen(ctx *cli.Context) error {
|
|||||||
// Check if issue or PR
|
// Check if issue or PR
|
||||||
issue, err := strconv.ParseInt(arg, 10, 64)
|
issue, err := strconv.ParseInt(arg, 10, 64)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
return open.Run(fmt.Sprintf("%s/issues/%d", repo, issue))
|
return open.Run(fmt.Sprintf("%s/issues/%d", flag.FullURL(), issue))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if overriding repository (jolheiser/sip)
|
// Check if overriding repository (jolheiser/sip)
|
||||||
ownerRepoIssue := strings.Split(arg, "/")
|
ownerRepoIssue := strings.Split(arg, "/")
|
||||||
if len(ownerRepoIssue) == 2 {
|
if len(ownerRepoIssue) == 2 {
|
||||||
return open.Run(fmt.Sprintf("%s/%s", ctx.String("url"), arg))
|
return open.Run(fmt.Sprintf("%s/%s", flag.FullURL(), arg))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check if both? (jolheiser/sip/1234)
|
// Check if both? (jolheiser/sip/1234)
|
||||||
if len(ownerRepoIssue) == 3 {
|
if len(ownerRepoIssue) == 3 {
|
||||||
return open.Run(fmt.Sprintf("%s/%s/%s/issues/%s", ctx.String("url"), ownerRepoIssue[0], ownerRepoIssue[1], ownerRepoIssue[2]))
|
return open.Run(fmt.Sprintf("%s/%s/%s/issues/%s", flag.URL, ownerRepoIssue[0], ownerRepoIssue[1], ownerRepoIssue[2]))
|
||||||
}
|
}
|
||||||
|
|
||||||
return errors.New("unknown argument: leave blank to open current repo, pass issue/PR as #1234, or override repo as owner/repo")
|
return errors.New("unknown argument: leave blank to open current repo, pass issue/PR as #1234, or override repo as owner/repo")
|
||||||
|
@ -17,7 +17,7 @@ var Pulls = cli.Command{
|
|||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "csv",
|
Name: "csv",
|
||||||
Usage: "Output results to a CSV file",
|
Usage: "Output results to a CSV file at `PATH`",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,8 @@ import (
|
|||||||
"os/exec"
|
"os/exec"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/modules/config"
|
"gitea.com/jolheiser/sip/config"
|
||||||
|
"gitea.com/jolheiser/sip/flag"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
@ -23,7 +24,7 @@ var PullsCheckout = cli.Command{
|
|||||||
}
|
}
|
||||||
|
|
||||||
func doPullCheckout(ctx *cli.Context) error {
|
func doPullCheckout(ctx *cli.Context) error {
|
||||||
client, err := getClient(ctx, true)
|
client, err := getClient(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -57,7 +58,7 @@ func doPullCheckout(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
iss, _, err := client.GetIssue(upstreamRepo[1], upstreamRepo[2], prNum.Index)
|
iss, _, err := client.GetIssue(flag.Upstream.Owner, flag.Upstream.Repo, prNum.Index)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -2,9 +2,11 @@ package cmd
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"strings"
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/modules/git"
|
"gitea.com/jolheiser/sip/flag"
|
||||||
"gitea.com/jolheiser/sip/modules/markdown"
|
"gitea.com/jolheiser/sip/git"
|
||||||
|
"gitea.com/jolheiser/sip/markdown"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
@ -19,30 +21,32 @@ var PullsCreate = cli.Command{
|
|||||||
Action: doPullCreate,
|
Action: doPullCreate,
|
||||||
}
|
}
|
||||||
|
|
||||||
func doPullCreate(ctx *cli.Context) error {
|
func doPullCreate(_ *cli.Context) error {
|
||||||
fmt.Println()
|
fmt.Println()
|
||||||
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(flag.FullURL())
|
||||||
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)
|
||||||
|
|
||||||
client, err := getClient(ctx, true)
|
client, err := getClient(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
upstreams, _, err := client.ListRepoBranches(getUpstreamRepo()[1], getUpstreamRepo()[2], gitea.ListRepoBranchesOptions{})
|
repo, _, err := client.GetRepo(flag.Upstream.Owner, flag.Upstream.Repo)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
|
||||||
|
upstreams, _, err := client.ListRepoBranches(flag.Upstream.Owner, flag.Upstream.Repo, gitea.ListRepoBranchesOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
bases := make([]string, len(upstreams))
|
bases := make([]string, len(upstreams))
|
||||||
defUpstream := upstreams[0].Name
|
defUpstream := repo.DefaultBranch
|
||||||
for idx, upstream := range upstreams {
|
for idx, upstream := range upstreams {
|
||||||
if upstream.Name == "master" {
|
|
||||||
defUpstream = upstream.Name
|
|
||||||
}
|
|
||||||
bases[idx] = upstream.Name
|
bases[idx] = upstream.Name
|
||||||
}
|
}
|
||||||
|
|
||||||
origins, _, err := client.ListRepoBranches(getOriginRepo()[1], getOriginRepo()[2], gitea.ListRepoBranchesOptions{})
|
origins, _, err := client.ListRepoBranches(flag.Origin.Owner, flag.Origin.Repo, gitea.ListRepoBranchesOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -50,10 +54,10 @@ func doPullCreate(ctx *cli.Context) error {
|
|||||||
defOrigin := origins[0].Name
|
defOrigin := origins[0].Name
|
||||||
for idx, origin := range origins {
|
for idx, origin := range origins {
|
||||||
originName := origin.Name
|
originName := origin.Name
|
||||||
if ctx.String("owner") != getOriginRepo()[1] {
|
if flag.Owner != flag.Origin.Owner {
|
||||||
originName = getOriginRepo()[1] + ":" + originName
|
originName = flag.Origin.Owner + ":" + originName
|
||||||
}
|
}
|
||||||
if origin.Name == git.Branch() {
|
if strings.EqualFold(origin.Name, git.Branch()) {
|
||||||
defOrigin = originName
|
defOrigin = originName
|
||||||
}
|
}
|
||||||
heads[idx] = originName
|
heads[idx] = originName
|
||||||
@ -114,10 +118,10 @@ func doPullCreate(ctx *cli.Context) error {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pull, _, err := client.CreatePullRequest(ctx.String("owner"), ctx.String("repo"), gitea.CreatePullRequestOption{Title: title, Body: body, Base: base, Head: head})
|
pull, _, err := client.CreatePullRequest(flag.Owner, flag.Repo, gitea.CreatePullRequestOption{Title: title, Body: body, Base: base, Head: head})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if fmt.Sprint(err) == "409 Conflict" { // Hard-coded in the SDK
|
if fmt.Sprint(err) == "409 Conflict" { // Hard-coded in the SDK
|
||||||
return existingPR(client, getUpstreamRepo()[1], getUpstreamRepo()[2], head, err)
|
return existingPR(client, flag.Upstream.Owner, flag.Upstream.Repo, head, err)
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -125,7 +129,7 @@ func doPullCreate(ctx *cli.Context) error {
|
|||||||
info := color.Info
|
info := color.Info
|
||||||
cyan := color.New(color.FgCyan)
|
cyan := color.New(color.FgCyan)
|
||||||
fmt.Println(info.Format("PR"), cyan.Format(fmt.Sprintf("#%d", pull.Index)), info.Format("created!"))
|
fmt.Println(info.Format("PR"), cyan.Format(fmt.Sprintf("#%d", pull.Index)), info.Format("created!"))
|
||||||
fmt.Println(cyan.Format(fmt.Sprintf("%s/%s/%s/pulls/%d", ctx.String("url"), ctx.String("owner"), ctx.String("repo"), pull.Index)))
|
fmt.Println(cyan.Format(fmt.Sprintf("%s/pulls/%d", flag.FullURL(), pull.Index)))
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,8 +4,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/modules/git"
|
"gitea.com/jolheiser/sip/flag"
|
||||||
"gitea.com/jolheiser/sip/modules/sdk"
|
"gitea.com/jolheiser/sip/git"
|
||||||
|
"gitea.com/jolheiser/sip/sdk"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
@ -18,15 +19,15 @@ var PullsStatus = cli.Command{
|
|||||||
Action: doPullStatus,
|
Action: doPullStatus,
|
||||||
}
|
}
|
||||||
|
|
||||||
func doPullStatus(ctx *cli.Context) error {
|
func doPullStatus(_ *cli.Context) error {
|
||||||
client, err := getClient(ctx, false)
|
client, err := getClient(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
head := fmt.Sprintf("%s:%s", getOriginRepo()[1], git.Branch())
|
head := fmt.Sprintf("%s:%s", flag.Origin.Owner, git.Branch())
|
||||||
|
|
||||||
pulls, err := sdk.GetPulls(client, getUpstreamRepo()[1], getUpstreamRepo()[2], gitea.ListPullRequestsOptions{State: "all"})
|
pulls, err := sdk.GetPulls(client, flag.Upstream.Owner, flag.Upstream.Repo, gitea.ListPullRequestsOptions{State: "all"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -4,9 +4,9 @@ import (
|
|||||||
"fmt"
|
"fmt"
|
||||||
"os"
|
"os"
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/modules/csv"
|
"gitea.com/jolheiser/sip/csv"
|
||||||
"gitea.com/jolheiser/sip/modules/markdown"
|
"gitea.com/jolheiser/sip/markdown"
|
||||||
"gitea.com/jolheiser/sip/modules/sdk"
|
"gitea.com/jolheiser/sip/sdk"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
@ -26,18 +26,18 @@ var Release = cli.Command{
|
|||||||
Flags: []cli.Flag{
|
Flags: []cli.Flag{
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "csv",
|
Name: "csv",
|
||||||
Usage: "Output results to a CSV file",
|
Usage: "Output results to a CSV file at `PATH`",
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func doRelease(ctx *cli.Context) error {
|
func doRelease(ctx *cli.Context) error {
|
||||||
client, err := getClient(ctx, false)
|
client, err := getClient(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
owner, repo, err := askOwnerRepo(ctx)
|
owner, repo, err := askOwnerRepo()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,8 @@ import (
|
|||||||
"path/filepath"
|
"path/filepath"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/modules/sdk"
|
"gitea.com/jolheiser/sip/flag"
|
||||||
|
"gitea.com/jolheiser/sip/sdk"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
@ -21,13 +22,13 @@ var ReleaseAttach = cli.Command{
|
|||||||
Action: doReleaseAttach,
|
Action: doReleaseAttach,
|
||||||
}
|
}
|
||||||
|
|
||||||
func doReleaseAttach(ctx *cli.Context) error {
|
func doReleaseAttach(_ *cli.Context) error {
|
||||||
client, err := getClient(ctx, true)
|
client, err := getClient(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
releases, err := sdk.GetReleases(client, ctx.String("owner"), ctx.String("repo"), gitea.ListReleasesOptions{})
|
releases, err := sdk.GetReleases(client, flag.Owner, flag.Repo, gitea.ListReleasesOptions{})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -64,15 +65,14 @@ func doReleaseAttach(ctx *cli.Context) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := attachFiles(ctx, client, release.ID, files); err != nil {
|
if err := attachFiles(client, release.ID, files); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
info := color.Info
|
info := color.Info
|
||||||
cyan := color.New(color.FgCyan)
|
cyan := color.New(color.FgCyan)
|
||||||
fmt.Println(info.Format("Release"), cyan.Format(release.TagName), info.Format("updated!"))
|
fmt.Println(info.Format("Release"), cyan.Format(release.TagName), info.Format("updated!"))
|
||||||
fmt.Println(cyan.Format(fmt.Sprintf("%s/%s/%s/releases/tag/%s",
|
fmt.Println(cyan.Format(fmt.Sprintf("%s/releases/tag/%s", flag.FullURL(), release.TagName)))
|
||||||
ctx.String("url"), ctx.String("owner"), ctx.String("repo"), release.TagName)))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +89,7 @@ func fileGlobs(globList string) ([]string, error) {
|
|||||||
return files, nil
|
return files, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func attachFiles(ctx *cli.Context, client *gitea.Client, releaseID int64, files []string) error {
|
func attachFiles(client *gitea.Client, releaseID int64, files []string) error {
|
||||||
beaver.Infof("Attachments:\n\t%s", strings.Join(files, "\n\t"))
|
beaver.Infof("Attachments:\n\t%s", strings.Join(files, "\n\t"))
|
||||||
|
|
||||||
var confirm bool
|
var confirm bool
|
||||||
@ -104,7 +104,7 @@ func attachFiles(ctx *cli.Context, client *gitea.Client, releaseID int64, files
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, _, err := client.CreateReleaseAttachment(ctx.String("owner"), ctx.String("repo"), releaseID, fi, fi.Name()); err != nil {
|
if _, _, err := client.CreateReleaseAttachment(flag.Owner, flag.Repo, releaseID, fi, fi.Name()); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,8 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/modules/git"
|
"gitea.com/jolheiser/sip/flag"
|
||||||
|
"gitea.com/jolheiser/sip/git"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
@ -18,8 +19,8 @@ var ReleaseCreate = cli.Command{
|
|||||||
Action: doReleaseCreate,
|
Action: doReleaseCreate,
|
||||||
}
|
}
|
||||||
|
|
||||||
func doReleaseCreate(ctx *cli.Context) error {
|
func doReleaseCreate(_ *cli.Context) error {
|
||||||
client, err := getClient(ctx, true)
|
client, err := getClient(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
@ -73,7 +74,7 @@ func doReleaseCreate(ctx *cli.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
release, _, err := client.CreateRelease(ctx.String("owner"), ctx.String("repo"), gitea.CreateReleaseOption{
|
release, _, err := client.CreateRelease(flag.Owner, flag.Repo, gitea.CreateReleaseOption{
|
||||||
TagName: answers.Tag,
|
TagName: answers.Tag,
|
||||||
Target: answers.Target,
|
Target: answers.Target,
|
||||||
Title: answers.Title,
|
Title: answers.Title,
|
||||||
@ -90,7 +91,7 @@ func doReleaseCreate(ctx *cli.Context) error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
if err := attachFiles(ctx, client, release.ID, files); err != nil {
|
if err := attachFiles(client, release.ID, files); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -98,7 +99,6 @@ func doReleaseCreate(ctx *cli.Context) error {
|
|||||||
info := color.Info
|
info := color.Info
|
||||||
cyan := color.New(color.FgCyan)
|
cyan := color.New(color.FgCyan)
|
||||||
fmt.Println(info.Format("Release"), cyan.Format(release.TagName), info.Format("created!"))
|
fmt.Println(info.Format("Release"), cyan.Format(release.TagName), info.Format("created!"))
|
||||||
fmt.Println(cyan.Format(fmt.Sprintf("%s/%s/%s/releases/tag/%s",
|
fmt.Println(cyan.Format(fmt.Sprintf("%s/releases/tag/%s", flag.FullURL(), release.TagName)))
|
||||||
ctx.String("url"), ctx.String("owner"), ctx.String("repo"), release.TagName)))
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
11
cmd/repo.go
11
cmd/repo.go
@ -3,7 +3,8 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/modules/sdk"
|
"gitea.com/jolheiser/sip/flag"
|
||||||
|
"gitea.com/jolheiser/sip/sdk"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
@ -20,18 +21,18 @@ var Repo = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func doRepo(ctx *cli.Context) error {
|
func doRepo(_ *cli.Context) error {
|
||||||
client, err := getClient(ctx, false)
|
client, err := getClient(false)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
repo, _, err := client.GetRepo(ctx.String("owner"), ctx.String("repo"))
|
repo, _, err := client.GetRepo(flag.Owner, flag.Repo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
issues, err := sdk.GetIssues(client, ctx.String("owner"), ctx.String("repo"), gitea.ListIssueOption{State: "open"})
|
issues, err := sdk.GetIssues(client, flag.Owner, flag.Repo, gitea.ListIssueOption{State: "open"})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -16,8 +16,8 @@ var RepoCreate = cli.Command{
|
|||||||
Action: doRepoCreate,
|
Action: doRepoCreate,
|
||||||
}
|
}
|
||||||
|
|
||||||
func doRepoCreate(ctx *cli.Context) error {
|
func doRepoCreate(_ *cli.Context) error {
|
||||||
client, err := getClient(ctx, true)
|
client, err := getClient(true)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package cmd
|
package cmd
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"gitea.com/jolheiser/sip/modules/config"
|
"gitea.com/jolheiser/sip/config"
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
"go.jolheiser.com/beaver"
|
"go.jolheiser.com/beaver"
|
||||||
@ -19,7 +19,7 @@ var Tokens = cli.Command{
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
func doTokenList(ctx *cli.Context) error {
|
func doTokenList(_ *cli.Context) error {
|
||||||
if len(config.Tokens) == 0 {
|
if len(config.Tokens) == 0 {
|
||||||
beaver.Errorf("No tokens found! Add one with %s", color.FgMagenta.Format("sip token create"))
|
beaver.Errorf("No tokens found! Add one with %s", color.FgMagenta.Format("sip token create"))
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,8 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/modules/config"
|
"gitea.com/jolheiser/sip/config"
|
||||||
|
"gitea.com/jolheiser/sip/flag"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
@ -28,7 +29,7 @@ func doTokenAdd(ctx *cli.Context) error {
|
|||||||
},
|
},
|
||||||
{
|
{
|
||||||
Name: "url",
|
Name: "url",
|
||||||
Prompt: &survey.Input{Message: "URL for the Gitea instance", Default: ctx.String("url")},
|
Prompt: &survey.Input{Message: "URL for the Gitea instance", Default: flag.URL},
|
||||||
Validate: survey.Required,
|
Validate: survey.Required,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/modules/config"
|
"gitea.com/jolheiser/sip/config"
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"github.com/urfave/cli/v2"
|
"github.com/urfave/cli/v2"
|
||||||
@ -17,7 +17,7 @@ var TokensRemove = cli.Command{
|
|||||||
Action: doTokenRemove,
|
Action: doTokenRemove,
|
||||||
}
|
}
|
||||||
|
|
||||||
func doTokenRemove(ctx *cli.Context) error {
|
func doTokenRemove(_ *cli.Context) error {
|
||||||
opts := make([]string, len(config.Tokens))
|
opts := make([]string, len(config.Tokens))
|
||||||
for idx, token := range config.Tokens {
|
for idx, token := range config.Tokens {
|
||||||
opts[idx] = fmt.Sprintf("%s (%s)", token.Name, token.URL)
|
opts[idx] = fmt.Sprintf("%s (%s)", token.Name, token.URL)
|
||||||
|
@ -7,15 +7,12 @@ import (
|
|||||||
|
|
||||||
"github.com/BurntSushi/toml"
|
"github.com/BurntSushi/toml"
|
||||||
"github.com/mitchellh/go-homedir"
|
"github.com/mitchellh/go-homedir"
|
||||||
"go.jolheiser.com/beaver"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
configPath string
|
configPath string
|
||||||
cfg *config
|
|
||||||
|
|
||||||
// Config items
|
// Config items
|
||||||
|
|
||||||
Origin string
|
Origin string
|
||||||
Upstream string
|
Upstream string
|
||||||
Tokens []Token
|
Tokens []Token
|
||||||
@ -34,46 +31,49 @@ type Token struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Load on init so that CLI contexts are correctly populated
|
// Load on init so that CLI contexts are correctly populated
|
||||||
func init() {
|
func Init() error {
|
||||||
home, err := homedir.Dir()
|
home, err := homedir.Dir()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
beaver.Fatalf("could not locate home directory: %v", err)
|
return err
|
||||||
}
|
}
|
||||||
configPath = fmt.Sprintf("%s/.sip/config.toml", home)
|
configPath = fmt.Sprintf("%s/.sip/config.toml", home)
|
||||||
|
|
||||||
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
if _, err := os.Stat(configPath); os.IsNotExist(err) {
|
||||||
if err := os.MkdirAll(path.Dir(configPath), os.ModePerm); err != nil {
|
if err := os.MkdirAll(path.Dir(configPath), os.ModePerm); err != nil {
|
||||||
beaver.Fatalf("could not create Sip home: %v", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := os.Create(configPath); err != nil {
|
if _, err := os.Create(configPath); err != nil {
|
||||||
beaver.Fatalf("could not create Sip config: %v", err)
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var cfg config
|
||||||
if _, err := toml.DecodeFile(configPath, &cfg); err != nil {
|
if _, err := toml.DecodeFile(configPath, &cfg); err != nil {
|
||||||
beaver.Fatalf("could not decode Sip config: %v", err)
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
Origin = cfg.Origin
|
Origin = cfg.Origin
|
||||||
Upstream = cfg.Upstream
|
Upstream = cfg.Upstream
|
||||||
Tokens = cfg.Tokens
|
Tokens = cfg.Tokens
|
||||||
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func Save() error {
|
func Save() error {
|
||||||
cfg.Origin = Origin
|
cfg := config{
|
||||||
cfg.Upstream = Upstream
|
Origin: Origin,
|
||||||
cfg.Tokens = Tokens
|
Upstream: Upstream,
|
||||||
|
Tokens: Tokens,
|
||||||
|
}
|
||||||
|
|
||||||
fi, err := os.Create(configPath)
|
fi, err := os.Create(configPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
defer fi.Close()
|
|
||||||
|
|
||||||
if err := toml.NewEncoder(fi).Encode(cfg); err != nil {
|
if err := toml.NewEncoder(fi).Encode(cfg); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return fi.Close()
|
||||||
}
|
}
|
35
docs.go
Normal file
35
docs.go
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// +build docs
|
||||||
|
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"os"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"gitea.com/jolheiser/sip/cmd"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
app := cmd.NewApp("docs")
|
||||||
|
|
||||||
|
fi, err := os.Create("docs.md")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
md, err := app.ToMarkdown()
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Clean up the header
|
||||||
|
md = md[strings.Index(md, "#"):]
|
||||||
|
|
||||||
|
if _, err := fi.WriteString(md); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := fi.Close(); err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
}
|
117
docs.md
Normal file
117
docs.md
Normal file
@ -0,0 +1,117 @@
|
|||||||
|
# NAME
|
||||||
|
|
||||||
|
Sip - Command line tool to interact with Gitea
|
||||||
|
|
||||||
|
# SYNOPSIS
|
||||||
|
|
||||||
|
Sip
|
||||||
|
|
||||||
|
```
|
||||||
|
[--origin]=[value]
|
||||||
|
[--owner|-o]=[value]
|
||||||
|
[--repo|-r]=[value]
|
||||||
|
[--token|-t]=[value]
|
||||||
|
[--upstream]=[value]
|
||||||
|
[--url|-u]=[value]
|
||||||
|
```
|
||||||
|
|
||||||
|
**Usage**:
|
||||||
|
|
||||||
|
```
|
||||||
|
Sip [GLOBAL OPTIONS] command [COMMAND OPTIONS] [ARGUMENTS...]
|
||||||
|
```
|
||||||
|
|
||||||
|
# GLOBAL OPTIONS
|
||||||
|
|
||||||
|
**--origin**="": The origin remote
|
||||||
|
|
||||||
|
**--owner, -o**="": The owner to target (default: jolheiser)
|
||||||
|
|
||||||
|
**--repo, -r**="": The repo to target (default: sip)
|
||||||
|
|
||||||
|
**--token, -t**="": The access token to use (by name)
|
||||||
|
|
||||||
|
**--upstream**="": The upstream remote
|
||||||
|
|
||||||
|
**--url, -u**="": The base URL to the Gitea instance (default: https://gitea.com)
|
||||||
|
|
||||||
|
|
||||||
|
# COMMANDS
|
||||||
|
|
||||||
|
## config, cfg
|
||||||
|
|
||||||
|
Modify Sip config
|
||||||
|
|
||||||
|
### origin
|
||||||
|
|
||||||
|
Specify default origin name
|
||||||
|
|
||||||
|
### upstream
|
||||||
|
|
||||||
|
Specify default upstream name
|
||||||
|
|
||||||
|
## tokens, token
|
||||||
|
|
||||||
|
Manage access tokens
|
||||||
|
|
||||||
|
### add, create
|
||||||
|
|
||||||
|
Add a new access token
|
||||||
|
|
||||||
|
### remove, delete
|
||||||
|
|
||||||
|
Remove access tokens
|
||||||
|
|
||||||
|
## repo
|
||||||
|
|
||||||
|
Commands for interacting with a Gitea repository
|
||||||
|
|
||||||
|
### create
|
||||||
|
|
||||||
|
Create a new repository
|
||||||
|
|
||||||
|
## issues, issue
|
||||||
|
|
||||||
|
Commands for interacting with issues
|
||||||
|
|
||||||
|
**--csv**="": Output results to a CSV file at `PATH`
|
||||||
|
|
||||||
|
### create, new
|
||||||
|
|
||||||
|
Create a new issue
|
||||||
|
|
||||||
|
## pulls, pull, pr
|
||||||
|
|
||||||
|
Commands for interacting with pull requests
|
||||||
|
|
||||||
|
**--csv**="": Output results to a CSV file at `PATH`
|
||||||
|
|
||||||
|
### create, new
|
||||||
|
|
||||||
|
Create a new pull request
|
||||||
|
|
||||||
|
### status
|
||||||
|
|
||||||
|
View the status of a pull request
|
||||||
|
|
||||||
|
### checkout
|
||||||
|
|
||||||
|
Checkout a pull request for testing
|
||||||
|
|
||||||
|
## releases, release
|
||||||
|
|
||||||
|
Commands for interacting with releases
|
||||||
|
|
||||||
|
**--csv**="": Output results to a CSV file at `PATH`
|
||||||
|
|
||||||
|
### create, new
|
||||||
|
|
||||||
|
Create a new release
|
||||||
|
|
||||||
|
### attach
|
||||||
|
|
||||||
|
Attach files to a release
|
||||||
|
|
||||||
|
## open, o
|
||||||
|
|
||||||
|
Open a repository or issue/pull request
|
121
flag/flag.go
Normal file
121
flag/flag.go
Normal file
@ -0,0 +1,121 @@
|
|||||||
|
package flag
|
||||||
|
|
||||||
|
import (
|
||||||
|
"fmt"
|
||||||
|
"sync"
|
||||||
|
|
||||||
|
"gitea.com/jolheiser/sip/config"
|
||||||
|
"gitea.com/jolheiser/sip/git"
|
||||||
|
|
||||||
|
"github.com/urfave/cli/v2"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Remote struct {
|
||||||
|
Name string
|
||||||
|
URL string
|
||||||
|
Owner string
|
||||||
|
Repo string
|
||||||
|
}
|
||||||
|
|
||||||
|
var (
|
||||||
|
// Set via config
|
||||||
|
Origin Remote
|
||||||
|
Upstream Remote
|
||||||
|
|
||||||
|
// Set via flags
|
||||||
|
URL string
|
||||||
|
Owner string
|
||||||
|
Repo string
|
||||||
|
Token string
|
||||||
|
|
||||||
|
// Set via Before
|
||||||
|
OwnerRepoCtxSet bool
|
||||||
|
|
||||||
|
Flags = []cli.Flag{
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "origin",
|
||||||
|
Usage: "The origin remote",
|
||||||
|
Value: config.Origin,
|
||||||
|
Destination: &Origin.Name,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "upstream",
|
||||||
|
Usage: "The upstream remote",
|
||||||
|
Value: config.Upstream,
|
||||||
|
Destination: &Upstream.Name,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "url",
|
||||||
|
Aliases: []string{"u"},
|
||||||
|
Usage: "The base URL to the Gitea instance",
|
||||||
|
Value: getUpstream().URL,
|
||||||
|
Destination: &URL,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "owner",
|
||||||
|
Aliases: []string{"o"},
|
||||||
|
Usage: "The owner to target",
|
||||||
|
Value: getUpstream().Owner,
|
||||||
|
Destination: &Owner,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "repo",
|
||||||
|
Aliases: []string{"r"},
|
||||||
|
Usage: "The repo to target",
|
||||||
|
Value: getUpstream().Repo,
|
||||||
|
Destination: &Repo,
|
||||||
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "token",
|
||||||
|
Aliases: []string{"t"},
|
||||||
|
Usage: "The access token to use (by name)",
|
||||||
|
Destination: &Token,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
originOnce sync.Once
|
||||||
|
upstreamOnce sync.Once
|
||||||
|
)
|
||||||
|
|
||||||
|
func FullName() string {
|
||||||
|
return fmt.Sprintf("%s/%s", Owner, Repo)
|
||||||
|
}
|
||||||
|
|
||||||
|
func FullURL() string {
|
||||||
|
return fmt.Sprintf("%s/%s", URL, FullName())
|
||||||
|
}
|
||||||
|
|
||||||
|
func Before(ctx *cli.Context) error {
|
||||||
|
OwnerRepoCtxSet = ctx.IsSet("owner") || ctx.IsSet("repo")
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func defRemote(remote, def string) string {
|
||||||
|
if remote == "" {
|
||||||
|
return def
|
||||||
|
}
|
||||||
|
return remote
|
||||||
|
}
|
||||||
|
|
||||||
|
func getUpstream() Remote {
|
||||||
|
upstreamOnce.Do(func() {
|
||||||
|
Upstream.URL, Upstream.Owner, Upstream.Repo = getOrigin().URL, getOrigin().Owner, getOrigin().Name
|
||||||
|
upstream, err := git.GetRepo(defRemote(config.Upstream, "upstream"))
|
||||||
|
if err == nil {
|
||||||
|
Upstream.URL, Upstream.Owner, Upstream.Repo = upstream[0], upstream[1], upstream[2]
|
||||||
|
}
|
||||||
|
|
||||||
|
})
|
||||||
|
return Upstream
|
||||||
|
}
|
||||||
|
|
||||||
|
func getOrigin() Remote {
|
||||||
|
originOnce.Do(func() {
|
||||||
|
Origin.URL, Origin.Owner, Origin.Name = "https://gitea.com", "jolheiser", "sip"
|
||||||
|
origin, err := git.GetRepo(defRemote(config.Origin, "origin"))
|
||||||
|
if err == nil {
|
||||||
|
Origin.URL, Origin.Owner, Origin.Repo = origin[0], origin[1], origin[2]
|
||||||
|
}
|
||||||
|
})
|
||||||
|
return Origin
|
||||||
|
}
|
2
go.sum
2
go.sum
@ -1,5 +1,3 @@
|
|||||||
code.gitea.io/sdk/gitea v0.12.2 h1:NQI8b/CT9AEQjsxbVIZ6gsPUXv38moT5y1ocN7n1YcQ=
|
|
||||||
code.gitea.io/sdk/gitea v0.12.2/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY=
|
|
||||||
code.gitea.io/sdk/gitea v0.13.0 h1:iHognp8ZMhMFLooUUNZFpm8IHaC9qoHJDvAE5vTm5aw=
|
code.gitea.io/sdk/gitea v0.13.0 h1:iHognp8ZMhMFLooUUNZFpm8IHaC9qoHJDvAE5vTm5aw=
|
||||||
code.gitea.io/sdk/gitea v0.13.0/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY=
|
code.gitea.io/sdk/gitea v0.13.0/go.mod h1:z3uwDV/b9Ls47NGukYM9XhnHtqPh/J+t40lsUrR6JDY=
|
||||||
github.com/AlecAivazis/survey/v2 v2.1.1 h1:LEMbHE0pLj75faaVEKClEX1TM4AJmmnOh9eimREzLWI=
|
github.com/AlecAivazis/survey/v2 v2.1.1 h1:LEMbHE0pLj75faaVEKClEX1TM4AJmmnOh9eimREzLWI=
|
||||||
|
24
main.go
24
main.go
@ -4,34 +4,22 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/cmd"
|
"gitea.com/jolheiser/sip/cmd"
|
||||||
|
"gitea.com/jolheiser/sip/config"
|
||||||
|
|
||||||
"github.com/urfave/cli/v2"
|
|
||||||
"go.jolheiser.com/beaver"
|
"go.jolheiser.com/beaver"
|
||||||
)
|
)
|
||||||
|
|
||||||
var Version = "develop"
|
var Version = "develop"
|
||||||
|
|
||||||
func main() {
|
func main() {
|
||||||
|
app := cmd.NewApp(Version)
|
||||||
|
|
||||||
// config loads on init
|
if err := config.Init(); err != nil {
|
||||||
|
beaver.Fatal(err)
|
||||||
app := cli.NewApp()
|
|
||||||
app.Name = "Sip"
|
|
||||||
app.Usage = "Command line tool to interact with Gitea"
|
|
||||||
app.Version = Version
|
|
||||||
app.Commands = []*cli.Command{
|
|
||||||
&cmd.Config,
|
|
||||||
&cmd.Tokens,
|
|
||||||
&cmd.Repo,
|
|
||||||
&cmd.Issues,
|
|
||||||
&cmd.Pulls,
|
|
||||||
&cmd.Release,
|
|
||||||
&cmd.Open,
|
|
||||||
}
|
}
|
||||||
app.Flags = cmd.Flags
|
|
||||||
app.EnableBashCompletion = true
|
|
||||||
err := app.Run(os.Args)
|
err := app.Run(os.Args)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
beaver.Error(err)
|
beaver.Fatal(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,7 @@ package sdk
|
|||||||
import (
|
import (
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"gitea.com/jolheiser/sip/modules/qualify"
|
"gitea.com/jolheiser/sip/qualify"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
)
|
)
|
Loading…
Reference in New Issue
Block a user