fix InitCommand() #285

Merged
6543 merged 7 commits from noerw/tea:issue-200-initcommand into master 2020-12-11 09:07:30 +00:00
17 changed files with 184 additions and 177 deletions
Showing only changes of commit f379b34993 - Show all commits

View File

@ -20,7 +20,17 @@ var CmdReleaseDelete = cli.Command{
Description: `Delete a release`,
ArgsUsage: "<release tag>",
Action: runReleaseDelete,
Flags: flags.AllDefaultFlags,
Flags: append([]cli.Flag{
&cli.BoolFlag{
Name: "confirm",
Aliases: []string{"y"},
Usage: "Confirm deletion (required)",
},
&cli.BoolFlag{
Name: "delete-tag",
Usage: "Also delete the git tag for this release",
},
}, flags.AllDefaultFlags...),
}
func runReleaseDelete(ctx *cli.Context) error {
@ -33,6 +43,11 @@ func runReleaseDelete(ctx *cli.Context) error {
return nil
}
if !ctx.Bool("confirm") {
fmt.Println("Are you sure? Please confirm with -y or --confirm.")
return nil
}
release, err := getReleaseByTag(owner, repo, tag, client)
if err != nil {
return err
@ -42,5 +57,14 @@ func runReleaseDelete(ctx *cli.Context) error {
}
_, err = client.DeleteRelease(owner, repo, release.ID)
return err
if err != nil {
return err
}
if ctx.Bool("delete-tag") {
_, err = client.DeleteReleaseTag(owner, repo, tag)
return err
}
return nil
}

2
go.mod
View File

@ -4,7 +4,7 @@ go 1.13
require (
code.gitea.io/gitea-vet v0.2.1
code.gitea.io/sdk/gitea v0.13.1-0.20201129150736-6ea6e887f2fc
code.gitea.io/sdk/gitea v0.13.1-0.20201209180822-68eec69f472e
github.com/AlecAivazis/survey/v2 v2.2.2
github.com/Microsoft/go-winio v0.4.15 // indirect
github.com/adrg/xdg v0.2.2

4
go.sum
View File

@ -1,7 +1,7 @@
code.gitea.io/gitea-vet v0.2.1 h1:b30by7+3SkmiftK0RjuXqFvZg2q4p68uoPGuxhzBN0s=
code.gitea.io/gitea-vet v0.2.1/go.mod h1:zcNbT/aJEmivCAhfmkHOlT645KNOf9W2KnkLgFjGGfE=
code.gitea.io/sdk/gitea v0.13.1-0.20201129150736-6ea6e887f2fc h1:Jy4PoO7T7tST6iYe7nvUwD2zkqbqVB34hLZsrG0EmLo=
code.gitea.io/sdk/gitea v0.13.1-0.20201129150736-6ea6e887f2fc/go.mod h1:89WiyOX1KEcvjP66sRHdu0RafojGo60bT9UqW17VbWs=
code.gitea.io/sdk/gitea v0.13.1-0.20201209180822-68eec69f472e h1:oJOoT5TGbSYRNGUhEiiEz3MqFjU6wELN0/liCZ3RmVg=
code.gitea.io/sdk/gitea v0.13.1-0.20201209180822-68eec69f472e/go.mod h1:89WiyOX1KEcvjP66sRHdu0RafojGo60bT9UqW17VbWs=
github.com/AlecAivazis/survey/v2 v2.2.2 h1:1I4qBrNsHQE+91tQCqVlfrKe9DEL65949d1oKZWVELY=
github.com/AlecAivazis/survey/v2 v2.2.2/go.mod h1:9FJRdMdDm8rnT+zHVbvQT2RTSTLq0Ttd6q3Vl2fahjk=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=

View File

@ -26,20 +26,14 @@ func IssueDetails(issue *gitea.Issue) {
// IssuesList prints a listing of issues
func IssuesList(issues []*gitea.Issue, output string) {
var values [][]string
headers := []string{
t := tableWithHeader(
"Index",
"Title",
"State",
"Author",
"Milestone",
"Updated",
}
if len(issues) == 0 {
outputList(output, headers, values)
return
}
)
for _, issue := range issues {
author := issue.Poster.FullName
@ -50,38 +44,29 @@ func IssuesList(issues []*gitea.Issue, output string) {
if issue.Milestone != nil {
mile = issue.Milestone.Title
}
values = append(
values,
[]string{
strconv.FormatInt(issue.Index, 10),
issue.Title,
string(issue.State),
author,
mile,
FormatTime(issue.Updated),
},
t.addRow(
strconv.FormatInt(issue.Index, 10),
issue.Title,
string(issue.State),
author,
mile,
FormatTime(issue.Updated),
)
}
outputList(output, headers, values)
t.print(output)
}
// IssuesPullsList prints a listing of issues & pulls
// TODO combine with IssuesList
func IssuesPullsList(issues []*gitea.Issue, output string) {
var values [][]string
headers := []string{
t := tableWithHeader(
"Index",
"State",
"Kind",
"Author",
"Updated",
"Title",
}
if len(issues) == 0 {
outputList(output, headers, values)
return
}
)
for _, issue := range issues {
name := issue.Poster.FullName
@ -92,18 +77,15 @@ func IssuesPullsList(issues []*gitea.Issue, output string) {
if issue.PullRequest != nil {
kind = "Pull"
}
values = append(
values,
[]string{
strconv.FormatInt(issue.Index, 10),
string(issue.State),
kind,
name,
FormatTime(issue.Updated),
issue.Title,
},
t.addRow(
strconv.FormatInt(issue.Index, 10),
string(issue.State),
kind,
name,
FormatTime(issue.Updated),
issue.Title,
)
}
outputList(output, headers, values)
t.print(output)
}

View File

@ -14,33 +14,24 @@ import (
// LabelsList prints a listing of labels
func LabelsList(labels []*gitea.Label, output string) {
var values [][]string
headers := []string{
t := tableWithHeader(
"Index",
"Color",
"Name",
"Description",
}
if len(labels) == 0 {
outputList(output, headers, values)
return
}
)
p := termenv.ColorProfile()
for _, label := range labels {
color := termenv.String(label.Color)
values = append(
values,
[]string{
strconv.FormatInt(label.ID, 10),
fmt.Sprint(color.Background(p.Color("#" + label.Color))),
label.Name,
label.Description,
},
t.addRow(
strconv.FormatInt(label.ID, 10),
fmt.Sprint(color.Background(p.Color("#"+label.Color))),
label.Name,
label.Description,
)
}
outputList(output, headers, values)
t.print(output)
}

View File

@ -33,24 +33,23 @@ func LoginDetails(login *config.Login, output string) {
// LoginsList prints a listing of logins
func LoginsList(logins []config.Login, output string) {
var values [][]string
headers := []string{
t := tableWithHeader(
"Name",
"URL",
"SSHHost",
"User",
"Default",
}
)
for _, l := range logins {
values = append(values, []string{
t.addRow(
l.Name,
l.URL,
l.GetSSHHost(),
l.User,
fmt.Sprint(l.Default),
})
)
}
outputList(output, headers, values)
t.print(output)
}

View File

@ -25,7 +25,6 @@ func MilestoneDetails(milestone *gitea.Milestone) {
// MilestonesList prints a listing of milestones
func MilestonesList(miles []*gitea.Milestone, output string, state gitea.StateType) {
headers := []string{
"Title",
}
@ -37,7 +36,7 @@ func MilestonesList(miles []*gitea.Milestone, output string, state gitea.StateTy
"DueDate",
)
var values [][]string
t := table{headers: headers}
for _, m := range miles {
var deadline = ""
@ -56,8 +55,9 @@ func MilestonesList(miles []*gitea.Milestone, output string, state gitea.StateTy
fmt.Sprintf("%d/%d", m.OpenIssues, m.ClosedIssues),
deadline,
)
values = append(values, item)
t.addRowSlice(item)
}
outputList(output, headers, values)
t.sort(0, true)
t.print(output)
}

View File

@ -12,7 +12,6 @@ import (
// NotificationsList prints a listing of notification threads
func NotificationsList(news []*gitea.NotificationThread, output string, showRepository bool) {
var values [][]string
headers := []string{
"Type",
"Index",
@ -22,6 +21,8 @@ func NotificationsList(news []*gitea.NotificationThread, output string, showRepo
headers = append(headers, "Repository")
}
t := table{headers: headers}
for _, n := range news {
if n.Subject == nil {
continue
@ -41,11 +42,10 @@ func NotificationsList(news []*gitea.NotificationThread, output string, showRepo
if showRepository {
item = append(item, n.Repository.FullName)
}
values = append(values, item)
t.addRowSlice(item)
}
if len(values) != 0 {
outputList(output, headers, values)
if t.Len() != 0 {
t.print(output)
}
return
}

View File

@ -17,28 +17,23 @@ func OrganizationsList(organizations []*gitea.Organization, output string) {
return
}
headers := []string{
t := tableWithHeader(
"Name",
"FullName",
"Website",
"Location",
"Description",
}
var values [][]string
)
for _, org := range organizations {
values = append(
values,
[]string{
org.UserName,
org.FullName,
org.Website,
org.Location,
org.Description,
},
t.addRow(
org.UserName,
org.FullName,
org.Website,
org.Location,
org.Description,
)
}
outputList(output, headers, values)
t.print(output)
}

View File

@ -60,20 +60,14 @@ func PullDetails(pr *gitea.PullRequest, reviews []*gitea.PullReview) {
// PullsList prints a listing of pulls
func PullsList(prs []*gitea.PullRequest, output string) {
var values [][]string
headers := []string{
t := tableWithHeader(
"Index",
"Title",
"State",
"Author",
"Milestone",
"Updated",
}
if len(prs) == 0 {
outputList(output, headers, values)
return
}
)
for _, pr := range prs {
if pr == nil {
@ -87,18 +81,15 @@ func PullsList(prs []*gitea.PullRequest, output string) {
if pr.Milestone != nil {
mile = pr.Milestone.Title
}
values = append(
values,
[]string{
strconv.FormatInt(pr.Index, 10),
pr.Title,
string(pr.State),
author,
mile,
FormatTime(*pr.Updated),
},
t.addRow(
strconv.FormatInt(pr.Index, 10),
pr.Title,
string(pr.State),
author,
mile,
FormatTime(*pr.Updated),
)
}
outputList(output, headers, values)
t.print(output)
}

View File

@ -10,19 +10,13 @@ import (
// ReleasesList prints a listing of releases
func ReleasesList(releases []*gitea.Release, output string) {
var values [][]string
headers := []string{
t := tableWithHeader(
"Tag-Name",
"Title",
"Published At",
"Status",
"Tar URL",
}
if len(releases) == 0 {
outputList(output, headers, values)
return
}
)
for _, release := range releases {
status := "released"
@ -31,17 +25,14 @@ func ReleasesList(releases []*gitea.Release, output string) {
} else if release.IsPrerelease {
status = "prerelease"
}
values = append(
values,
[]string{
release.TagName,
release.Title,
FormatTime(release.PublishedAt),
status,
release.TarURL,
},
t.addRow(
release.TagName,
release.Title,
FormatTime(release.PublishedAt),
status,
release.TarURL,
)
}
outputList(output, headers, values)
t.print(output)
}

View File

@ -90,7 +90,8 @@ func ReposList(repos []*gitea.Repository, output string, fields []string) {
}
}
outputList(output, fields, values)
t := table{headers: fields, values: values}
t.print(output)
}
// RepoDetails print an repo formatted to stdout

View File

@ -1,4 +1,4 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// 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.
@ -7,19 +7,67 @@ package print
import (
"fmt"
"os"
"sort"
"strconv"
"strings"
"github.com/olekukonko/tablewriter"
)
var (
showLog bool
)
// table provides infrastructure to easily print (sorted) lists in different formats
type table struct {
headers []string
values [][]string
sortDesc bool // used internally by sortable interface
sortColumn uint // ↑
}
// errorf printf content as an error information
func errorf(format string, a ...interface{}) {
fmt.Printf(format, a...)
func tableWithHeader(header ...string) table {
return table{headers: header}
}
// it's the callers responsibility to ensure row length is equal to header length!
func (t *table) addRow(row ...string) {
t.addRowSlice(row)
}
// it's the callers responsibility to ensure row length is equal to header length!
func (t *table) addRowSlice(row []string) {
t.values = append(t.values, row)
}
func (t *table) sort(column uint, desc bool) {
t.sortColumn = column
t.sortDesc = desc
sort.Stable(t) // stable to allow multiple calls to sort
}
// sortable interface
func (t table) Len() int { return len(t.values) }
func (t table) Swap(i, j int) { t.values[i], t.values[j] = t.values[j], t.values[i] }
func (t table) Less(i, j int) bool {
const column = 0
if t.sortDesc {
i, j = j, i
}
return t.values[i][t.sortColumn] < t.values[j][t.sortColumn]
}
func (t *table) print(output string) {
switch {
case output == "" || output == "table":
outputtable(t.headers, t.values)
case output == "csv":
outputdsv(t.headers, t.values, ",")
case output == "simple":
outputsimple(t.headers, t.values)
case output == "tsv":
outputdsv(t.headers, t.values, "\t")
case output == "yaml":
outputyaml(t.headers, t.values)
default:
fmt.Printf("unknown output type '" + output + "', available types are:\n- csv: comma-separated values\n- simple: space-separated values\n- table: auto-aligned table format (default)\n- tsv: tab-separated values\n- yaml: YAML format\n")
}
}
// outputtable prints structured data as table
@ -71,22 +119,3 @@ func outputyaml(headers []string, values [][]string) {
}
}
}
// outputList provides general function to convert given list of items
// into several outputs (table, csv, simple, tsv, yaml)
func outputList(output string, headers []string, values [][]string) {
switch {
case output == "" || output == "table":
outputtable(headers, values)
case output == "csv":
outputdsv(headers, values, ",")
case output == "simple":
outputsimple(headers, values)
case output == "tsv":
outputdsv(headers, values, "\t")
case output == "yaml":
outputyaml(headers, values)
default:
errorf("unknown output type '" + output + "', available types are:\n- csv: comma-separated values\n- simple: space-separated values\n- table: auto-aligned table format (default)\n- tsv: tab-separated values\n- yaml: YAML format\n")
}
}

View File

@ -23,7 +23,12 @@ func formatDuration(seconds int64, outputType string) string {
// TrackedTimesList print list of tracked times to stdout
func TrackedTimesList(times []*gitea.TrackedTime, outputType string, from, until time.Time, printTotal bool) {
var outputValues [][]string
tab := tableWithHeader(
"Created",
"Issue",
"User",
"Duration",
)
var totalDuration int64
for _, t := range times {
@ -35,29 +40,16 @@ func TrackedTimesList(times []*gitea.TrackedTime, outputType string, from, until
}
totalDuration += t.Time
outputValues = append(
outputValues,
[]string{
FormatTime(t.Created),
"#" + strconv.FormatInt(t.Issue.Index, 10),
t.UserName,
formatDuration(t.Time, outputType),
},
tab.addRow(
FormatTime(t.Created),
"#"+strconv.FormatInt(t.Issue.Index, 10),
t.UserName,
formatDuration(t.Time, outputType),
)
}
if printTotal {
outputValues = append(outputValues, []string{
"TOTAL", "", "", formatDuration(totalDuration, outputType),
})
tab.addRow("TOTAL", "", "", formatDuration(totalDuration, outputType))
}
headers := []string{
"Created",
"Issue",
"User",
"Duration",
}
outputList(outputType, headers, outputValues)
tab.print(outputType)
}

View File

@ -124,7 +124,7 @@ func (c *Client) EditRelease(user, repo string, id int64, form EditReleaseOption
return r, resp, err
}
// DeleteRelease delete a release from a repository
// DeleteRelease delete a release from a repository, keeping its tag
func (c *Client) DeleteRelease(user, repo string, id int64) (*Response, error) {
_, resp, err := c.getResponse("DELETE",
fmt.Sprintf("/repos/%s/%s/releases/%d", user, repo, id),
@ -132,6 +132,17 @@ func (c *Client) DeleteRelease(user, repo string, id int64) (*Response, error) {
return resp, err
}
// DeleteReleaseTag deletes a tag from a repository, if no release refers to it.
func (c *Client) DeleteReleaseTag(user, repo string, tag string) (*Response, error) {
if err := c.checkServerVersionGreaterThanOrEqual(version1_14_0); err != nil {
return nil, err
}
_, resp, err := c.getResponse("DELETE",
fmt.Sprintf("/repos/%s/%s/releases/tags/%s", user, repo, tag),
nil, nil)
return resp, err
}
// fallbackGetReleaseByTag is fallback for old gitea installations ( < 1.13.0 )
func (c *Client) fallbackGetReleaseByTag(user, repo string, tag string) (*Release, *Response, error) {
for i := 1; ; i++ {

View File

@ -41,6 +41,7 @@ var (
version1_11_0, _ = version.NewVersion("1.11.0")
version1_12_0, _ = version.NewVersion("1.12.0")
version1_13_0, _ = version.NewVersion("1.13.0")
version1_14_0, _ = version.NewVersion("1.14.0")
)
// checkServerVersionGreaterThanOrEqual is internally used to speed up things and ignore issues with prerelease

2
vendor/modules.txt vendored
View File

@ -1,7 +1,7 @@
# code.gitea.io/gitea-vet v0.2.1
code.gitea.io/gitea-vet
code.gitea.io/gitea-vet/checks
# code.gitea.io/sdk/gitea v0.13.1-0.20201129150736-6ea6e887f2fc
# code.gitea.io/sdk/gitea v0.13.1-0.20201209180822-68eec69f472e
code.gitea.io/sdk/gitea
# github.com/AlecAivazis/survey/v2 v2.2.2
github.com/AlecAivazis/survey/v2