Add Repo Create subcomand & enhancements (#173)

repos ls: use owner filter and remove org&user one

better desc

refactor

rm local filter, let us fix upstream

split user org

add archive and private filters

use SearchRepos

migrate to sdk v0.13.0

print URL

add CmdRepoCreate,

Add RepoDetails

ListRepos: better desc, add aliases, add note for sdk-release

Co-authored-by: 6543 <6543@obermui.de>
Reviewed-on: https://gitea.com/gitea/tea/pulls/173
Reviewed-by: Andrew Thornton <art27@cantab.net>
Reviewed-by: Norwin <noerw@noreply.gitea.io>
This commit is contained in:
6543 2020-09-23 19:49:59 +00:00
parent eacf1be066
commit 2e701ee8a2
2 changed files with 255 additions and 51 deletions

View File

@ -5,26 +5,32 @@
package cmd package cmd
import ( import (
"fmt"
"log" "log"
"net/http"
"strings"
"code.gitea.io/tea/modules/utils"
"code.gitea.io/sdk/gitea" "code.gitea.io/sdk/gitea"
"github.com/urfave/cli/v2" "github.com/urfave/cli/v2"
) )
// CmdRepos represents to login a gitea server. // CmdRepos represents to login a gitea server.
var CmdRepos = cli.Command{ var CmdRepos = cli.Command{
Name: "repos", Name: "repos",
Usage: "Operate with repositories", Usage: "Show repositories details",
Description: `Operate with repositories`, Description: "Show repositories details",
Action: runReposList, ArgsUsage: "[<repo owner>/<repo name>]",
Action: runRepos,
Subcommands: []*cli.Command{ Subcommands: []*cli.Command{
&CmdReposList, &CmdReposList,
&CmdRepoCreate,
}, },
Flags: LoginOutputFlags, Flags: LoginOutputFlags,
} }
// CmdReposList represents a sub command of issues to list issues // CmdReposList represents a sub command of repos to list them
var CmdReposList = cli.Command{ var CmdReposList = cli.Command{
Name: "ls", Name: "ls",
Usage: "List available repositories", Usage: "List available repositories",
@ -32,66 +38,164 @@ var CmdReposList = cli.Command{
Action: runReposList, Action: runReposList,
Flags: append([]cli.Flag{ Flags: append([]cli.Flag{
&cli.StringFlag{ &cli.StringFlag{
Name: "mode", Name: "mode",
Usage: "Filter listed repositories based on mode, optional - fork, mirror, source", Aliases: []string{"m"},
Required: false,
Usage: "Filter by mode: fork, mirror, source",
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "org", Name: "owner",
Usage: "Filter listed repositories based on organization, optional", Aliases: []string{"O"},
Required: false,
Usage: "Filter by owner",
}, },
&cli.StringFlag{ &cli.StringFlag{
Name: "user", Name: "private",
Usage: "Filter listed repositories absed on user, optional", Required: false,
Usage: "Filter private repos (true|false)",
},
&cli.StringFlag{
Name: "archived",
Required: false,
Usage: "Filter archived repos (true|false)",
}, },
}, LoginOutputFlags...), }, LoginOutputFlags...),
} }
// CmdRepoCreate represents a sub command of repos to create one
var CmdRepoCreate = cli.Command{
Name: "create",
Aliases: []string{"c"},
Usage: "Create a repository",
Description: "Create a repository",
Action: runRepoCreate,
Flags: append([]cli.Flag{
&cli.StringFlag{
Name: "name",
Aliases: []string{""},
Required: true,
Usage: "name of new repo",
},
&cli.StringFlag{
Name: "owner",
Aliases: []string{"O"},
Required: false,
Usage: "name of repo owner",
},
&cli.BoolFlag{
Name: "private",
Required: false,
Value: false,
Usage: "make repo private",
},
&cli.StringFlag{
Name: "description",
Aliases: []string{"desc"},
Required: false,
Usage: "add description to repo",
},
&cli.BoolFlag{
Name: "init",
Required: false,
Value: false,
Usage: "initialize repo",
},
&cli.StringFlag{
Name: "labels",
Required: false,
Usage: "name of label set to add",
},
&cli.StringFlag{
Name: "gitignores",
Aliases: []string{"git"},
Required: false,
Usage: "list of gitignore templates (need --init)",
},
&cli.StringFlag{
Name: "license",
Required: false,
Usage: "add license (need --init)",
},
&cli.StringFlag{
Name: "readme",
Required: false,
Usage: "use readme template (need --init)",
},
&cli.StringFlag{
Name: "branch",
Required: false,
Usage: "use custom default branch (need --init)",
},
}, LoginOutputFlags...),
}
func runRepos(ctx *cli.Context) error {
if ctx.Args().Len() == 1 {
return runRepoDetail(ctx, ctx.Args().First())
}
return runReposList(ctx)
}
// runReposList list repositories // runReposList list repositories
func runReposList(ctx *cli.Context) error { func runReposList(ctx *cli.Context) error {
login := initCommandLoginOnly() login := initCommandLoginOnly()
client := login.Client()
mode := ctx.String("mode") var ownerID int64
org := ctx.String("org") if ctx.IsSet("owner") {
user := ctx.String("user") // test if owner is a organisation
org, resp, err := client.GetOrg(ctx.String("owner"))
var rps []*gitea.Repository if err != nil {
var err error if resp == nil || resp.StatusCode != http.StatusNotFound {
return err
if org != "" { }
rps, _, err = login.Client().ListOrgRepos(org, gitea.ListOrgReposOptions{}) // if owner is no org, its a user
} else if user != "" { user, _, err := client.GetUserInfo(ctx.String("owner"))
rps, _, err = login.Client().ListUserRepos(user, gitea.ListReposOptions{}) if err != nil {
return err
}
ownerID = user.ID
} else {
ownerID = org.ID
}
} else { } else {
rps, _, err = login.Client().ListMyRepos(gitea.ListReposOptions{}) me, _, err := client.GetMyUserInfo()
if err != nil {
return err
}
ownerID = me.ID
} }
var isArchived *bool
if ctx.IsSet("archived") {
archived := strings.ToLower(ctx.String("archived"))[:1] == "t"
isArchived = &archived
}
var isPrivate *bool
if ctx.IsSet("private") {
private := strings.ToLower(ctx.String("private"))[:1] == "t"
isArchived = &private
}
mode := gitea.RepoTypeNone
switch ctx.String("mode") {
case "fork":
mode = gitea.RepoTypeFork
case "mirror":
mode = gitea.RepoTypeMirror
case "source":
mode = gitea.RepoTypeSource
}
rps, _, err := client.SearchRepos(gitea.SearchRepoOptions{
OwnerID: ownerID,
IsPrivate: isPrivate,
IsArchived: isArchived,
Type: mode,
})
if err != nil { if err != nil {
log.Fatal(err) return err
}
var repos []*gitea.Repository
if mode == "" {
repos = rps
} else if mode == "fork" {
for _, rp := range rps {
if rp.Fork == true {
repos = append(repos, rp)
}
}
} else if mode == "mirror" {
for _, rp := range rps {
if rp.Mirror == true {
repos = append(repos, rp)
}
}
} else if mode == "source" {
for _, rp := range rps {
if rp.Mirror != true && rp.Fork != true {
repos = append(repos, rp)
}
}
} else {
log.Fatal("Unknown mode: ", mode, "\nUse one of the following:\n- fork\n- mirror\n- source\n")
return nil
} }
if len(rps) == 0 { if len(rps) == 0 {
@ -107,7 +211,7 @@ func runReposList(ctx *cli.Context) error {
} }
var values [][]string var values [][]string
for _, rp := range repos { for _, rp := range rps {
var mode = "source" var mode = "source"
if rp.Fork { if rp.Fork {
mode = "fork" mode = "fork"
@ -130,3 +234,80 @@ func runReposList(ctx *cli.Context) error {
return nil return nil
} }
func runRepoDetail(_ *cli.Context, path string) error {
login := initCommandLoginOnly()
client := login.Client()
repoOwner, repoName := getOwnerAndRepo(path, login.User)
repo, _, err := client.GetRepo(repoOwner, repoName)
if err != nil {
return err
}
topics, _, err := client.ListRepoTopics(repo.Owner.UserName, repo.Name, gitea.ListRepoTopicsOptions{})
if err != nil {
return err
}
output := repo.FullName
if repo.Mirror {
output += " (mirror)"
}
if repo.Fork {
output += " (fork)"
}
if repo.Archived {
output += " (archived)"
}
if repo.Empty {
output += " (empty)"
}
output += "\n"
if len(topics) != 0 {
output += "Topics: " + strings.Join(topics, ", ") + "\n"
}
output += "\n"
output += repo.Description + "\n\n"
output += fmt.Sprintf(
"Open Issues: %d, Stars: %d, Forks: %d, Size: %s\n\n",
repo.OpenIssues,
repo.Stars,
repo.Forks,
utils.FormatSize(int64(repo.Size)),
)
fmt.Print(output)
return nil
}
func runRepoCreate(ctx *cli.Context) error {
login := initCommandLoginOnly()
client := login.Client()
var (
repo *gitea.Repository
err error
)
opts := gitea.CreateRepoOption{
Name: ctx.String("name"),
Description: ctx.String("description"),
Private: ctx.Bool("private"),
AutoInit: ctx.Bool("init"),
IssueLabels: ctx.String("labels"),
Gitignores: ctx.String("gitignores"),
License: ctx.String("license"),
Readme: ctx.String("readme"),
DefaultBranch: ctx.String("branch"),
}
if len(ctx.String("owner")) != 0 {
repo, _, err = client.CreateOrgRepo(ctx.String("owner"), opts)
} else {
repo, _, err = client.CreateRepo(opts)
}
if err != nil {
return err
}
if err = runRepoDetail(ctx, repo.FullName); err != nil {
return err
}
fmt.Printf("%s\n", repo.HTMLURL)
return nil
}

23
modules/utils/format.go Normal file
View File

@ -0,0 +1,23 @@
// Copyright 2020 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package utils
import "fmt"
// FormatSize get kb in int and return string
func FormatSize(kb int64) string {
if kb < 1024 {
return fmt.Sprintf("%d Kb", kb)
}
mb := kb / 1024
if mb < 1024 {
return fmt.Sprintf("%d Mb", mb)
}
gb := mb / 1024
if gb < 1024 {
return fmt.Sprintf("%d Gb", gb)
}
return fmt.Sprintf("%d Tb", gb/1024)
}