Merge branch 'main' into fix-524
This commit is contained in:
commit
404439f8fd
@ -71,9 +71,8 @@ builds:
|
|||||||
no_unique_dist_dir: true
|
no_unique_dist_dir: true
|
||||||
hooks:
|
hooks:
|
||||||
post:
|
post:
|
||||||
- cmd: tar -cJf {{ .Path }}.xz {{ .Path }}
|
- cmd: xz -k -9 {{ .Path }}
|
||||||
env:
|
dir: ./dist/
|
||||||
- XZ_OPT=-9
|
|
||||||
- cmd: sh .goreleaser.checksum.sh {{ .Path }}
|
- cmd: sh .goreleaser.checksum.sh {{ .Path }}
|
||||||
- cmd: sh .goreleaser.checksum.sh {{ .Path }}.xz
|
- cmd: sh .goreleaser.checksum.sh {{ .Path }}.xz
|
||||||
|
|
||||||
@ -118,5 +117,10 @@ gitea_urls:
|
|||||||
api: https://gitea.com/api/v1
|
api: https://gitea.com/api/v1
|
||||||
download: https://gitea.com
|
download: https://gitea.com
|
||||||
|
|
||||||
|
release:
|
||||||
|
extra_files:
|
||||||
|
- glob: ./**.xz
|
||||||
|
- glob: ./**.xz.sha256
|
||||||
|
|
||||||
# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json
|
# yaml-language-server: $schema=https://goreleaser.com/static/schema-pro.json
|
||||||
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
|
# vim: set ts=2 sw=2 tw=0 fo=cnqoj
|
@ -105,6 +105,11 @@ Make sure you have a current go version installed (1.13 or newer).
|
|||||||
make
|
make
|
||||||
```
|
```
|
||||||
Note that GNU Make (gmake on OpenBSD) is required.
|
Note that GNU Make (gmake on OpenBSD) is required.
|
||||||
|
If you want to install the compiled program you have to execute the following command:
|
||||||
|
```sh
|
||||||
|
make install
|
||||||
|
```
|
||||||
|
This installs the binary into the "bin" folder inside of your GOPATH folder (`go env GOPATH`). It is possible that this folder isn't in your PATH Environment Variable.
|
||||||
|
|
||||||
- For a quick installation without `git` & `make`, set $version and exec:
|
- For a quick installation without `git` & `make`, set $version and exec:
|
||||||
```sh
|
```sh
|
||||||
|
@ -71,6 +71,10 @@ var IssueListingFlags = append([]cli.Flag{
|
|||||||
Name: "mentions",
|
Name: "mentions",
|
||||||
Aliases: []string{"M"},
|
Aliases: []string{"M"},
|
||||||
},
|
},
|
||||||
|
&cli.StringFlag{
|
||||||
|
Name: "owner",
|
||||||
|
Aliases: []string{"org"},
|
||||||
|
},
|
||||||
&cli.StringFlag{
|
&cli.StringFlag{
|
||||||
Name: "from",
|
Name: "from",
|
||||||
Aliases: []string{"F"},
|
Aliases: []string{"F"},
|
||||||
|
@ -18,7 +18,7 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
var issueFieldsFlag = flags.FieldsFlag(print.IssueFields, []string{
|
var issueFieldsFlag = flags.FieldsFlag(print.IssueFields, []string{
|
||||||
"index", "title", "state", "author", "milestone", "labels",
|
"index", "title", "state", "author", "milestone", "labels", "owner", "repo",
|
||||||
})
|
})
|
||||||
|
|
||||||
// CmdIssuesList represents a sub command of issues to list issues
|
// CmdIssuesList represents a sub command of issues to list issues
|
||||||
@ -35,7 +35,6 @@ var CmdIssuesList = cli.Command{
|
|||||||
// RunIssuesList list issues
|
// RunIssuesList list issues
|
||||||
func RunIssuesList(cmd *cli.Context) error {
|
func RunIssuesList(cmd *cli.Context) error {
|
||||||
ctx := context.InitCommand(cmd)
|
ctx := context.InitCommand(cmd)
|
||||||
ctx.Ensure(context.CtxRequirement{RemoteRepo: true})
|
|
||||||
|
|
||||||
state := gitea.StateOpen
|
state := gitea.StateOpen
|
||||||
switch ctx.String("state") {
|
switch ctx.String("state") {
|
||||||
@ -75,27 +74,52 @@ func RunIssuesList(cmd *cli.Context) error {
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
owner := ctx.Owner
|
||||||
|
if ctx.IsSet("owner") {
|
||||||
|
owner = ctx.String("owner")
|
||||||
|
}
|
||||||
|
|
||||||
// ignore error, as we don't do any input validation on these flags
|
// ignore error, as we don't do any input validation on these flags
|
||||||
labels, _ := flags.LabelFilterFlag.GetValues(cmd)
|
labels, _ := flags.LabelFilterFlag.GetValues(cmd)
|
||||||
milestones, _ := flags.MilestoneFilterFlag.GetValues(cmd)
|
milestones, _ := flags.MilestoneFilterFlag.GetValues(cmd)
|
||||||
|
var issues []*gitea.Issue
|
||||||
|
if ctx.Repo != "" {
|
||||||
|
issues, _, err = ctx.Login.Client().ListRepoIssues(owner, ctx.Repo, gitea.ListIssueOption{
|
||||||
|
ListOptions: ctx.GetListOptions(),
|
||||||
|
State: state,
|
||||||
|
Type: kind,
|
||||||
|
KeyWord: ctx.String("keyword"),
|
||||||
|
CreatedBy: ctx.String("author"),
|
||||||
|
AssignedBy: ctx.String("assigned-to"),
|
||||||
|
MentionedBy: ctx.String("mentions"),
|
||||||
|
Labels: labels,
|
||||||
|
Milestones: milestones,
|
||||||
|
Since: from,
|
||||||
|
Before: until,
|
||||||
|
})
|
||||||
|
|
||||||
issues, _, err := ctx.Login.Client().ListRepoIssues(ctx.Owner, ctx.Repo, gitea.ListIssueOption{
|
if err != nil {
|
||||||
ListOptions: ctx.GetListOptions(),
|
return err
|
||||||
State: state,
|
}
|
||||||
Type: kind,
|
} else {
|
||||||
KeyWord: ctx.String("keyword"),
|
issues, _, err = ctx.Login.Client().ListIssues(gitea.ListIssueOption{
|
||||||
CreatedBy: ctx.String("author"),
|
ListOptions: ctx.GetListOptions(),
|
||||||
AssignedBy: ctx.String("assigned-to"),
|
State: state,
|
||||||
MentionedBy: ctx.String("mentions"),
|
Type: kind,
|
||||||
Labels: labels,
|
KeyWord: ctx.String("keyword"),
|
||||||
Milestones: milestones,
|
CreatedBy: ctx.String("author"),
|
||||||
Since: from,
|
AssignedBy: ctx.String("assigned-to"),
|
||||||
Before: until,
|
MentionedBy: ctx.String("mentions"),
|
||||||
})
|
Labels: labels,
|
||||||
|
Milestones: milestones,
|
||||||
|
Since: from,
|
||||||
|
Before: until,
|
||||||
|
Owner: owner,
|
||||||
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fields, err := issueFieldsFlag.GetValues(cmd)
|
fields, err := issueFieldsFlag.GetValues(cmd)
|
||||||
|
2
go.mod
2
go.mod
@ -18,6 +18,7 @@ require (
|
|||||||
github.com/stretchr/testify v1.7.0
|
github.com/stretchr/testify v1.7.0
|
||||||
github.com/urfave/cli/v2 v2.16.3
|
github.com/urfave/cli/v2 v2.16.3
|
||||||
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be
|
golang.org/x/crypto v0.0.0-20220926161630-eccd6366d1be
|
||||||
|
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035
|
||||||
gopkg.in/yaml.v2 v2.4.0
|
gopkg.in/yaml.v2 v2.4.0
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -60,7 +61,6 @@ require (
|
|||||||
github.com/yuin/goldmark-emoji v1.0.1 // indirect
|
github.com/yuin/goldmark-emoji v1.0.1 // indirect
|
||||||
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect
|
golang.org/x/net v0.0.0-20220909164309-bea034e7d591 // indirect
|
||||||
golang.org/x/sys v0.0.0-20220926163933-8cfa568d3c25 // indirect
|
golang.org/x/sys v0.0.0-20220926163933-8cfa568d3c25 // indirect
|
||||||
golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect
|
|
||||||
golang.org/x/text v0.3.7 // indirect
|
golang.org/x/text v0.3.7 // indirect
|
||||||
golang.org/x/tools v0.1.12 // indirect
|
golang.org/x/tools v0.1.12 // indirect
|
||||||
gopkg.in/warnings.v0 v0.1.2 // indirect
|
gopkg.in/warnings.v0 v0.1.2 // indirect
|
||||||
|
@ -74,7 +74,7 @@ func GetConfigPath() string {
|
|||||||
|
|
||||||
// GetPreferences returns preferences based on the config file
|
// GetPreferences returns preferences based on the config file
|
||||||
func GetPreferences() Preferences {
|
func GetPreferences() Preferences {
|
||||||
loadConfig()
|
_ = loadConfig()
|
||||||
return config.Prefs
|
return config.Prefs
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,5 +105,5 @@ func saveConfig() error {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return ioutil.WriteFile(ymlPath, bs, 0660)
|
return ioutil.WriteFile(ymlPath, bs, 0o660)
|
||||||
}
|
}
|
||||||
|
@ -228,5 +228,5 @@ func (l *Login) GetSSHHost() string {
|
|||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
return u.Hostname()
|
return u.Host
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,10 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var protocolRe = regexp.MustCompile("^[a-zA-Z_+-]+://")
|
||||||
protocolRe = regexp.MustCompile("^[a-zA-Z_+-]+://")
|
|
||||||
)
|
|
||||||
|
|
||||||
// URLParser represents a git URL parser
|
// URLParser represents a git URL parser
|
||||||
type URLParser struct {
|
type URLParser struct{}
|
||||||
}
|
|
||||||
|
|
||||||
// Parse parses the git URL
|
// Parse parses the git URL
|
||||||
func (p *URLParser) Parse(rawURL string) (u *url.URL, err error) {
|
func (p *URLParser) Parse(rawURL string) (u *url.URL, err error) {
|
||||||
@ -50,9 +47,7 @@ func (p *URLParser) Parse(rawURL string) (u *url.URL, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// .git suffix is optional and breaks normalization
|
// .git suffix is optional and breaks normalization
|
||||||
if strings.HasSuffix(u.Path, ".git") {
|
u.Path = strings.TrimSuffix(u.Path, ".git")
|
||||||
u.Path = strings.TrimSuffix(u.Path, ".git")
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ import (
|
|||||||
"code.gitea.io/tea/modules/print"
|
"code.gitea.io/tea/modules/print"
|
||||||
|
|
||||||
"github.com/AlecAivazis/survey/v2"
|
"github.com/AlecAivazis/survey/v2"
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ShowCommentsMaybeInteractive fetches & prints comments, depending on the --comments flag.
|
// ShowCommentsMaybeInteractive fetches & prints comments, depending on the --comments flag.
|
||||||
@ -72,5 +72,5 @@ func ShowCommentsPaginated(ctx *context.TeaContext, idx int64, totalComments int
|
|||||||
|
|
||||||
// IsStdinPiped checks if stdin is piped
|
// IsStdinPiped checks if stdin is piped
|
||||||
func IsStdinPiped() bool {
|
func IsStdinPiped() bool {
|
||||||
return !terminal.IsTerminal(int(os.Stdin.Fd()))
|
return !term.IsTerminal(int(os.Stdin.Fd()))
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ func CreateLogin() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
switch loginMethod {
|
switch loginMethod {
|
||||||
case "token":
|
default: // token
|
||||||
var hasToken bool
|
var hasToken bool
|
||||||
promptYN := &survey.Confirm{
|
promptYN := &survey.Confirm{
|
||||||
Message: "Do you have an access token?",
|
Message: "Do you have an access token?",
|
||||||
|
@ -18,12 +18,12 @@ func Comments(comments []*gitea.Comment) {
|
|||||||
baseURL = getRepoURL(comments[0].HTMLURL)
|
baseURL = getRepoURL(comments[0].HTMLURL)
|
||||||
}
|
}
|
||||||
|
|
||||||
var out = make([]string, len(comments))
|
out := make([]string, len(comments))
|
||||||
for i, c := range comments {
|
for i, c := range comments {
|
||||||
out[i] = formatComment(c)
|
out[i] = formatComment(c)
|
||||||
}
|
}
|
||||||
|
|
||||||
outputMarkdown(fmt.Sprintf(
|
_ = outputMarkdown(fmt.Sprintf(
|
||||||
// this will become a heading by means of the first --- from a comment
|
// this will become a heading by means of the first --- from a comment
|
||||||
"Comments\n%s",
|
"Comments\n%s",
|
||||||
strings.Join(out, "\n"),
|
strings.Join(out, "\n"),
|
||||||
@ -32,7 +32,7 @@ func Comments(comments []*gitea.Comment) {
|
|||||||
|
|
||||||
// Comment renders a comment to stdout
|
// Comment renders a comment to stdout
|
||||||
func Comment(c *gitea.Comment) {
|
func Comment(c *gitea.Comment) {
|
||||||
outputMarkdown(formatComment(c), getRepoURL(c.HTMLURL))
|
_ = outputMarkdown(formatComment(c), getRepoURL(c.HTMLURL))
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatComment(c *gitea.Comment) string {
|
func formatComment(c *gitea.Comment) string {
|
||||||
|
@ -12,12 +12,12 @@ import (
|
|||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
"github.com/muesli/termenv"
|
"github.com/muesli/termenv"
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
// IsInteractive checks if the output is piped, but NOT if the session is run interactively..
|
// IsInteractive checks if the output is piped, but NOT if the session is run interactively..
|
||||||
func IsInteractive() bool {
|
func IsInteractive() bool {
|
||||||
return terminal.IsTerminal(int(os.Stdout.Fd()))
|
return term.IsTerminal(int(os.Stdout.Fd()))
|
||||||
}
|
}
|
||||||
|
|
||||||
// captures the repo URL part <host>/<owner>/<repo> of an url
|
// captures the repo URL part <host>/<owner>/<repo> of an url
|
||||||
|
@ -28,7 +28,7 @@ func IssueDetails(issue *gitea.Issue, reactions []*gitea.Reaction) {
|
|||||||
out += fmt.Sprintf("\n---\n\n%s\n", formatReactions(reactions))
|
out += fmt.Sprintf("\n---\n\n%s\n", formatReactions(reactions))
|
||||||
}
|
}
|
||||||
|
|
||||||
outputMarkdown(out, getRepoURL(issue.HTMLURL))
|
_ = outputMarkdown(out, getRepoURL(issue.HTMLURL))
|
||||||
}
|
}
|
||||||
|
|
||||||
func formatReactions(reactions []*gitea.Reaction) string {
|
func formatReactions(reactions []*gitea.Reaction) string {
|
||||||
@ -70,11 +70,13 @@ var IssueFields = []string{
|
|||||||
"milestone",
|
"milestone",
|
||||||
"labels",
|
"labels",
|
||||||
"comments",
|
"comments",
|
||||||
|
"owner",
|
||||||
|
"repo",
|
||||||
}
|
}
|
||||||
|
|
||||||
func printIssues(issues []*gitea.Issue, output string, fields []string) {
|
func printIssues(issues []*gitea.Issue, output string, fields []string) {
|
||||||
labelMap := map[int64]string{}
|
labelMap := map[int64]string{}
|
||||||
var printables = make([]printable, len(issues))
|
printables := make([]printable, len(issues))
|
||||||
machineReadable := isMachineReadable(output)
|
machineReadable := isMachineReadable(output)
|
||||||
|
|
||||||
for i, x := range issues {
|
for i, x := range issues {
|
||||||
@ -133,19 +135,23 @@ func (x printableIssue) FormatField(field string, machineReadable bool) string {
|
|||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
case "labels":
|
case "labels":
|
||||||
var labels = make([]string, len(x.Labels))
|
labels := make([]string, len(x.Labels))
|
||||||
for i, l := range x.Labels {
|
for i, l := range x.Labels {
|
||||||
labels[i] = (*x.formattedLabels)[l.ID]
|
labels[i] = (*x.formattedLabels)[l.ID]
|
||||||
}
|
}
|
||||||
return strings.Join(labels, " ")
|
return strings.Join(labels, " ")
|
||||||
case "assignees":
|
case "assignees":
|
||||||
var assignees = make([]string, len(x.Assignees))
|
assignees := make([]string, len(x.Assignees))
|
||||||
for i, a := range x.Assignees {
|
for i, a := range x.Assignees {
|
||||||
assignees[i] = formatUserName(a)
|
assignees[i] = formatUserName(a)
|
||||||
}
|
}
|
||||||
return strings.Join(assignees, " ")
|
return strings.Join(assignees, " ")
|
||||||
case "comments":
|
case "comments":
|
||||||
return fmt.Sprintf("%d", x.Comments)
|
return fmt.Sprintf("%d", x.Comments)
|
||||||
|
case "owner":
|
||||||
|
return x.Repository.Owner
|
||||||
|
case "repo":
|
||||||
|
return x.Repository.Name
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ func LoginDetails(login *config.Login) {
|
|||||||
}
|
}
|
||||||
in += fmt.Sprintf("\nCreated: %s", time.Unix(login.Created, 0).Format(time.RFC822))
|
in += fmt.Sprintf("\nCreated: %s", time.Unix(login.Created, 0).Format(time.RFC822))
|
||||||
|
|
||||||
outputMarkdown(in, "")
|
_ = outputMarkdown(in, "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoginsList prints a listing of logins
|
// LoginsList prints a listing of logins
|
||||||
|
@ -9,7 +9,7 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/charmbracelet/glamour"
|
"github.com/charmbracelet/glamour"
|
||||||
"golang.org/x/crypto/ssh/terminal"
|
"golang.org/x/term"
|
||||||
)
|
)
|
||||||
|
|
||||||
// outputMarkdown prints markdown to stdout, formatted for terminals.
|
// outputMarkdown prints markdown to stdout, formatted for terminals.
|
||||||
@ -47,8 +47,8 @@ func outputMarkdown(markdown string, baseURL string) error {
|
|||||||
func getWordWrap() int {
|
func getWordWrap() int {
|
||||||
fd := int(os.Stdout.Fd())
|
fd := int(os.Stdout.Fd())
|
||||||
width := 80
|
width := 80
|
||||||
if terminal.IsTerminal(fd) {
|
if term.IsTerminal(fd) {
|
||||||
if w, _, err := terminal.GetSize(fd); err == nil {
|
if w, _, err := term.GetSize(fd); err == nil {
|
||||||
width = w
|
width = w
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import (
|
|||||||
|
|
||||||
// OrganizationDetails prints details of an org with formatting
|
// OrganizationDetails prints details of an org with formatting
|
||||||
func OrganizationDetails(org *gitea.Organization) {
|
func OrganizationDetails(org *gitea.Organization) {
|
||||||
outputMarkdown(fmt.Sprintf(
|
_ = outputMarkdown(fmt.Sprintf(
|
||||||
"# %s\n%s\n\n- Visibility: %s\n- Location: %s\n- Website: %s\n",
|
"# %s\n%s\n\n- Visibility: %s\n- Location: %s\n- Website: %s\n",
|
||||||
org.UserName,
|
org.UserName,
|
||||||
org.Description,
|
org.Description,
|
||||||
|
@ -14,7 +14,7 @@ import (
|
|||||||
|
|
||||||
// ReposList prints a listing of the repos
|
// ReposList prints a listing of the repos
|
||||||
func ReposList(repos []*gitea.Repository, output string, fields []string) {
|
func ReposList(repos []*gitea.Repository, output string, fields []string) {
|
||||||
var printables = make([]printable, len(repos))
|
printables := make([]printable, len(repos))
|
||||||
for i, r := range repos {
|
for i, r := range repos {
|
||||||
printables[i] = &printableRepo{r}
|
printables[i] = &printableRepo{r}
|
||||||
}
|
}
|
||||||
@ -56,7 +56,7 @@ func RepoDetails(repo *gitea.Repository, topics []string) {
|
|||||||
updated := fmt.Sprintf(
|
updated := fmt.Sprintf(
|
||||||
"Updated: %s (%s ago)\n",
|
"Updated: %s (%s ago)\n",
|
||||||
repo.Updated.Format("2006-01-02 15:04"),
|
repo.Updated.Format("2006-01-02 15:04"),
|
||||||
time.Now().Sub(repo.Updated).Truncate(time.Minute),
|
time.Since(repo.Updated).Truncate(time.Minute),
|
||||||
)
|
)
|
||||||
|
|
||||||
urls := fmt.Sprintf(
|
urls := fmt.Sprintf(
|
||||||
|
@ -66,7 +66,6 @@ func (t *table) sort(column uint, desc bool) {
|
|||||||
func (t table) Len() int { return len(t.values) }
|
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) Swap(i, j int) { t.values[i], t.values[j] = t.values[j], t.values[i] }
|
||||||
func (t table) Less(i, j int) bool {
|
func (t table) Less(i, j int) bool {
|
||||||
const column = 0
|
|
||||||
if t.sortDesc {
|
if t.sortDesc {
|
||||||
i, j = j, i
|
i, j = j, i
|
||||||
}
|
}
|
||||||
|
@ -90,8 +90,8 @@ func CreateLogin(name, token, user, passwd, sshKey, giteaURL, sshCertPrincipal,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// we do not have a method to get SSH config from api,
|
// we do not have a method to get SSH config from api,
|
||||||
// so we just use the hostname
|
// so we just use the host
|
||||||
login.SSHHost = serverURL.Hostname()
|
login.SSHHost = serverURL.Host
|
||||||
|
|
||||||
if len(sshKey) == 0 {
|
if len(sshKey) == 0 {
|
||||||
login.SSHKey, err = findSSHKey(client)
|
login.SSHKey, err = findSSHKey(client)
|
||||||
|
@ -91,15 +91,3 @@ func parseKeys(pkinput []byte, sshPath string) string {
|
|||||||
|
|
||||||
return ssh.FingerprintSHA256(pkey) + " " + pkey.Type() + " " + comment + " (" + sshPath + ")"
|
return ssh.FingerprintSHA256(pkey) + " " + pkey.Type() + " " + comment + " (" + sshPath + ")"
|
||||||
}
|
}
|
||||||
|
|
||||||
func getCertPrincipals(pkey ssh.PublicKey) []string {
|
|
||||||
var principals []string
|
|
||||||
|
|
||||||
if cert, ok := pkey.(*ssh.Certificate); ok {
|
|
||||||
for _, principal := range cert.ValidPrincipals {
|
|
||||||
principals = append(principals, principal)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return principals
|
|
||||||
}
|
|
||||||
|
@ -6,6 +6,7 @@ package task
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"code.gitea.io/sdk/gitea"
|
"code.gitea.io/sdk/gitea"
|
||||||
@ -16,6 +17,12 @@ import (
|
|||||||
"code.gitea.io/tea/modules/utils"
|
"code.gitea.io/tea/modules/utils"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var (
|
||||||
|
spaceRegex = regexp.MustCompile(`[\s_-]+`)
|
||||||
|
noSpace = regexp.MustCompile(`^[^a-zA-Z\s]*`)
|
||||||
|
consecutive = regexp.MustCompile(`[\s]{2,}`)
|
||||||
|
)
|
||||||
|
|
||||||
// CreatePull creates a PR in the given repo and prints the result
|
// CreatePull creates a PR in the given repo and prints the result
|
||||||
func CreatePull(ctx *context.TeaContext, base, head string, allowMaintainerEdits bool, opts *gitea.CreateIssueOption) (err error) {
|
func CreatePull(ctx *context.TeaContext, base, head string, allowMaintainerEdits bool, opts *gitea.CreateIssueOption) (err error) {
|
||||||
// default is default branch
|
// default is default branch
|
||||||
@ -65,7 +72,6 @@ func CreatePull(ctx *context.TeaContext, base, head string, allowMaintainerEdits
|
|||||||
Milestone: opts.Milestone,
|
Milestone: opts.Milestone,
|
||||||
Deadline: opts.Deadline,
|
Deadline: opts.Deadline,
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("could not create PR from %s to %s:%s: %s", head, ctx.Owner, base, err)
|
return fmt.Errorf("could not create PR from %s to %s:%s: %s", head, ctx.Owner, base, err)
|
||||||
}
|
}
|
||||||
@ -133,13 +139,18 @@ func GetHeadSpec(owner, branch, baseOwner string) string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GetDefaultPRTitle transforms a string like a branchname to a readable text
|
// GetDefaultPRTitle transforms a string like a branchname to a readable text
|
||||||
func GetDefaultPRTitle(head string) string {
|
func GetDefaultPRTitle(header string) string {
|
||||||
title := head
|
// Extract the part after the last colon in the input string
|
||||||
if strings.Contains(title, ":") {
|
colonIndex := strings.LastIndex(header, ":")
|
||||||
title = strings.SplitN(title, ":", 2)[1]
|
if colonIndex != -1 {
|
||||||
|
header = header[colonIndex+1:]
|
||||||
}
|
}
|
||||||
title = strings.Replace(title, "-", " ", -1)
|
|
||||||
title = strings.Replace(title, "_", " ", -1)
|
title := noSpace.ReplaceAllString(header, "")
|
||||||
|
title = spaceRegex.ReplaceAllString(title, " ")
|
||||||
|
title = strings.TrimSpace(title)
|
||||||
title = strings.Title(strings.ToLower(title))
|
title = strings.Title(strings.ToLower(title))
|
||||||
|
title = consecutive.ReplaceAllString(title, " ")
|
||||||
|
|
||||||
return title
|
return title
|
||||||
}
|
}
|
||||||
|
28
modules/task/pull_create_test.go
Normal file
28
modules/task/pull_create_test.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package task
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestGetDefaultPRTitle(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
input string
|
||||||
|
want string
|
||||||
|
}{
|
||||||
|
{input: "Add new feature", want: "Add New Feature"},
|
||||||
|
{input: "update-docs: Fix typo", want: "Fix Typo"},
|
||||||
|
{input: "remove_long-string", want: "Remove Long String"},
|
||||||
|
{input: "Replace_Underscores_With_Spaces", want: "Replace Underscores With Spaces"},
|
||||||
|
{input: " leading-and-trailing-spaces ", want: "Leading And Trailing Spaces"},
|
||||||
|
{input: "-----No--Upper--Case-----", want: "No Upper Case"},
|
||||||
|
{input: "", want: ""},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
got := GetDefaultPRTitle(test.input)
|
||||||
|
if got != test.want {
|
||||||
|
t.Errorf("GetDefaultPRTitle(%q) = %q, want %q", test.input, got, test.want)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -26,7 +26,6 @@ func RepoClone(
|
|||||||
callback func(string) (string, error),
|
callback func(string) (string, error),
|
||||||
depth int,
|
depth int,
|
||||||
) (*local_git.TeaRepo, error) {
|
) (*local_git.TeaRepo, error) {
|
||||||
|
|
||||||
repoMeta, _, err := login.Client().GetRepo(repoOwner, repoName)
|
repoMeta, _, err := login.Client().GetRepo(repoOwner, repoName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -64,10 +63,14 @@ func RepoClone(
|
|||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
upstreamBranch := repoMeta.Parent.DefaultBranch
|
upstreamBranch := repoMeta.Parent.DefaultBranch
|
||||||
repo.CreateRemote(&git_config.RemoteConfig{
|
_, err = repo.CreateRemote(&git_config.RemoteConfig{
|
||||||
Name: "upstream",
|
Name: "upstream",
|
||||||
URLs: []string{upstreamURL.String()},
|
URLs: []string{upstreamURL.String()},
|
||||||
})
|
})
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
repoConf, err := repo.Config()
|
repoConf, err := repo.Config()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -24,10 +24,7 @@ func ArgsToIndices(args []string) ([]int64, error) {
|
|||||||
|
|
||||||
// ArgToIndex take issue/pull index as string and return int64
|
// ArgToIndex take issue/pull index as string and return int64
|
||||||
func ArgToIndex(arg string) (int64, error) {
|
func ArgToIndex(arg string) (int64, error) {
|
||||||
if strings.HasPrefix(arg, "#") {
|
return strconv.ParseInt(strings.TrimPrefix(arg, "#"), 10, 64)
|
||||||
arg = arg[1:]
|
|
||||||
}
|
|
||||||
return strconv.ParseInt(arg, 10, 64)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// NormalizeURL normalizes the input with a protocol
|
// NormalizeURL normalizes the input with a protocol
|
||||||
|
48
modules/utils/parse_test.go
Normal file
48
modules/utils/parse_test.go
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
// Copyright 2023 The Gitea Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a MIT-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package utils
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestArgToIndex(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
arg string
|
||||||
|
want int64
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Valid argument",
|
||||||
|
arg: "#123",
|
||||||
|
want: 123,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Invalid argument",
|
||||||
|
arg: "abc",
|
||||||
|
want: 0,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Empty argument",
|
||||||
|
arg: "",
|
||||||
|
want: 0,
|
||||||
|
wantErr: true,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
got, err := ArgToIndex(tt.arg)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("ArgToIndex() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if got != tt.want {
|
||||||
|
t.Errorf("ArgToIndex() = %v, want %v", got, tt.want)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user