Refactor: apply new internal structurs #206
256
cmd/config.go
256
cmd/config.go
|
@ -5,103 +5,11 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/modules/git"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"github.com/muesli/termenv"
|
||||
"github.com/urfave/cli/v2"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// Login represents a login to a gitea server, you even could add multiple logins for one gitea server
|
||||
type Login struct {
|
||||
Name string `yaml:"name"`
|
||||
URL string `yaml:"url"`
|
||||
Token string `yaml:"token"`
|
||||
Default bool `yaml:"default"`
|
||||
SSHHost string `yaml:"ssh_host"`
|
||||
// optional path to the private key
|
||||
SSHKey string `yaml:"ssh_key"`
|
||||
Insecure bool `yaml:"insecure"`
|
||||
// optional gitea username
|
||||
User string `yaml:"user"`
|
||||
}
|
||||
|
||||
// Client returns a client to operate Gitea API
|
||||
func (l *Login) Client() *gitea.Client {
|
||||
httpClient := &http.Client{}
|
||||
if l.Insecure {
|
||||
cookieJar, _ := cookiejar.New(nil)
|
||||
|
||||
httpClient = &http.Client{
|
||||
Jar: cookieJar,
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}}
|
||||
}
|
||||
|
||||
client, err := gitea.NewClient(l.URL,
|
||||
gitea.SetToken(l.Token),
|
||||
gitea.SetHTTPClient(httpClient),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// GetSSHHost returns SSH host name
|
||||
func (l *Login) GetSSHHost() string {
|
||||
if l.SSHHost != "" {
|
||||
return l.SSHHost
|
||||
}
|
||||
|
||||
u, err := url.Parse(l.URL)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return u.Hostname()
|
||||
}
|
||||
|
||||
// Config reprensents local configurations
|
||||
type Config struct {
|
||||
Logins []Login `yaml:"logins"`
|
||||
}
|
||||
|
||||
var (
|
||||
config Config
|
||||
yamlConfigPath string
|
||||
)
|
||||
|
||||
func init() {
|
||||
homeDir, err := utils.Home()
|
||||
if err != nil {
|
||||
log.Fatal("Retrieve home dir failed")
|
||||
}
|
||||
|
||||
dir := filepath.Join(homeDir, ".tea")
|
||||
err = os.MkdirAll(dir, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Fatal("Init tea config dir " + dir + " failed")
|
||||
}
|
||||
|
||||
yamlConfigPath = filepath.Join(dir, "tea.yml")
|
||||
}
|
||||
|
||||
func getGlamourTheme() string {
|
||||
if termenv.HasDarkBackground() {
|
||||
return "dark"
|
||||
|
@ -109,170 +17,6 @@ func getGlamourTheme() string {
|
|||
return "light"
|
||||
}
|
||||
|
||||
func getOwnerAndRepo(repoPath, user string) (string, string) {
|
||||
if len(repoPath) == 0 {
|
||||
return "", ""
|
||||
}
|
||||
p := strings.Split(repoPath, "/")
|
||||
if len(p) >= 2 {
|
||||
return p[0], p[1]
|
||||
}
|
||||
return user, repoPath
|
||||
}
|
||||
|
||||
func getDefaultLogin() (*Login, error) {
|
||||
if len(config.Logins) == 0 {
|
||||
return nil, errors.New("No available login")
|
||||
}
|
||||
for _, l := range config.Logins {
|
||||
if l.Default {
|
||||
return &l, nil
|
||||
}
|
||||
}
|
||||
|
||||
return &config.Logins[0], nil
|
||||
}
|
||||
|
||||
func getLoginByName(name string) *Login {
|
||||
for _, l := range config.Logins {
|
||||
if l.Name == name {
|
||||
return &l
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func addLogin(login Login) error {
|
||||
for _, l := range config.Logins {
|
||||
if l.Name == login.Name {
|
||||
if l.URL == login.URL && l.Token == login.Token {
|
||||
return nil
|
||||
}
|
||||
return errors.New("Login name has already been used")
|
||||
}
|
||||
if l.URL == login.URL && l.Token == login.Token {
|
||||
return errors.New("URL has been added")
|
||||
}
|
||||
}
|
||||
|
||||
u, err := url.Parse(login.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if login.SSHHost == "" {
|
||||
login.SSHHost = u.Hostname()
|
||||
}
|
||||
config.Logins = append(config.Logins, login)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func isFileExist(fileName string) (bool, error) {
|
||||
f, err := os.Stat(fileName)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if f.IsDir() {
|
||||
return false, errors.New("A directory with the same name exists")
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
||||
func loadConfig(ymlPath string) error {
|
||||
exist, _ := isFileExist(ymlPath)
|
||||
if exist {
|
||||
Println("Found config file", ymlPath)
|
||||
bs, err := ioutil.ReadFile(ymlPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(bs, &config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func saveConfig(ymlPath string) error {
|
||||
bs, err := yaml.Marshal(&config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(ymlPath, bs, 0660)
|
||||
}
|
||||
|
||||
func curGitRepoPath(path string) (*Login, string, error) {
|
||||
var err error
|
||||
var repo *git.TeaRepo
|
||||
if len(path) == 0 {
|
||||
repo, err = git.RepoForWorkdir()
|
||||
} else {
|
||||
repo, err = git.RepoFromPath(path)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
gitConfig, err := repo.Config()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
// if no remote
|
||||
if len(gitConfig.Remotes) == 0 {
|
||||
return nil, "", errors.New("No remote(s) found in this Git repository")
|
||||
}
|
||||
|
||||
// if only one remote exists
|
||||
if len(gitConfig.Remotes) >= 1 && len(remoteValue) == 0 {
|
||||
for remote := range gitConfig.Remotes {
|
||||
remoteValue = remote
|
||||
}
|
||||
if len(gitConfig.Remotes) > 1 {
|
||||
// if master branch is present, use it as the default remote
|
||||
masterBranch, ok := gitConfig.Branches["master"]
|
||||
if ok {
|
||||
if len(masterBranch.Remote) > 0 {
|
||||
remoteValue = masterBranch.Remote
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
remoteConfig, ok := gitConfig.Remotes[remoteValue]
|
||||
if !ok || remoteConfig == nil {
|
||||
return nil, "", errors.New("Remote " + remoteValue + " not found in this Git repository")
|
||||
}
|
||||
|
||||
for _, l := range config.Logins {
|
||||
for _, u := range remoteConfig.URLs {
|
||||
p, err := git.ParseURL(strings.TrimSpace(u))
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("Git remote URL parse failed: %s", err.Error())
|
||||
}
|
||||
if strings.EqualFold(p.Scheme, "http") || strings.EqualFold(p.Scheme, "https") {
|
||||
if strings.HasPrefix(u, l.URL) {
|
||||
ps := strings.Split(p.Path, "/")
|
||||
path := strings.Join(ps[len(ps)-2:], "/")
|
||||
return &l, strings.TrimSuffix(path, ".git"), nil
|
||||
}
|
||||
} else if strings.EqualFold(p.Scheme, "ssh") {
|
||||
if l.GetSSHHost() == strings.Split(p.Host, ":")[0] {
|
||||
return &l, strings.TrimLeft(strings.TrimSuffix(p.Path, ".git"), "/"), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, "", errors.New("No Gitea login found. You might want to specify --repo (and --login) to work outside of a repository")
|
||||
}
|
||||
|
||||
func getListOptions(ctx *cli.Context) gitea.ListOptions {
|
||||
page := ctx.Int("page")
|
||||
limit := ctx.Int("limit")
|
||||
|
|
79
cmd/flags.go
79
cmd/flags.go
|
@ -5,20 +5,16 @@
|
|||
package cmd
|
||||
|
||||
import (
|
||||
"log"
|
||||
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
// create global variables for global Flags to simplify
|
||||
// access to the options without requiring cli.Context
|
||||
var (
|
||||
loginValue string
|
||||
repoValue string
|
||||
outputValue string
|
||||
remoteValue string
|
||||
globalLoginValue string
|
||||
globalRepoValue string
|
||||
globalOutputValue string
|
||||
globalRemoteValue string
|
||||
)
|
||||
|
||||
// LoginFlag provides flag to specify tea login profile
|
||||
|
@ -26,7 +22,7 @@ var LoginFlag = cli.StringFlag{
|
|||
Name: "login",
|
||||
Aliases: []string{"l"},
|
||||
Usage: "Use a different Gitea login. Optional",
|
||||
Destination: &loginValue,
|
||||
Destination: &globalLoginValue,
|
||||
}
|
||||
|
||||
// RepoFlag provides flag to specify repository
|
||||
|
@ -34,7 +30,7 @@ var RepoFlag = cli.StringFlag{
|
|||
Name: "repo",
|
||||
Aliases: []string{"r"},
|
||||
Usage: "Repository to interact with. Optional",
|
||||
Destination: &repoValue,
|
||||
Destination: &globalRepoValue,
|
||||
}
|
||||
|
||||
// RemoteFlag provides flag to specify remote repository
|
||||
|
@ -42,7 +38,7 @@ var RemoteFlag = cli.StringFlag{
|
|||
Name: "remote",
|
||||
Aliases: []string{"R"},
|
||||
Usage: "Discover Gitea login from remote. Optional",
|
||||
Destination: &remoteValue,
|
||||
Destination: &globalRemoteValue,
|
||||
}
|
||||
|
||||
// OutputFlag provides flag to specify output type
|
||||
|
@ -50,7 +46,7 @@ var OutputFlag = cli.StringFlag{
|
|||
Name: "output",
|
||||
Aliases: []string{"o"},
|
||||
Usage: "Output format. (csv, simple, table, tsv, yaml)",
|
||||
Destination: &outputValue,
|
||||
Destination: &globalOutputValue,
|
||||
}
|
||||
|
||||
// StateFlag provides flag to specify issue/pr state, defaulting to "open"
|
||||
|
@ -108,62 +104,3 @@ var IssuePRFlags = append([]cli.Flag{
|
|||
&PaginationPageFlag,
|
||||
&PaginationLimitFlag,
|
||||
}, AllDefaultFlags...)
|
||||
|
||||
// initCommand returns repository and *Login based on flags
|
||||
func initCommand() (*Login, string, string) {
|
||||
var login *Login
|
||||
|
||||
err := loadConfig(yamlConfigPath)
|
||||
if err != nil {
|
||||
log.Fatal("load config file failed ", yamlConfigPath)
|
||||
}
|
||||
|
||||
if login, err = getDefaultLogin(); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
exist, err := utils.PathExists(repoValue)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if exist || len(repoValue) == 0 {
|
||||
login, repoValue, err = curGitRepoPath(repoValue)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if loginValue != "" {
|
||||
login = getLoginByName(loginValue)
|
||||
if login == nil {
|
||||
log.Fatal("Login name " + loginValue + " does not exist")
|
||||
}
|
||||
}
|
||||
|
||||
owner, repo := getOwnerAndRepo(repoValue, login.User)
|
||||
return login, owner, repo
|
||||
}
|
||||
|
||||
// initCommandLoginOnly return *Login based on flags
|
||||
func initCommandLoginOnly() *Login {
|
||||
err := loadConfig(yamlConfigPath)
|
||||
if err != nil {
|
||||
log.Fatal("load config file failed ", yamlConfigPath)
|
||||
}
|
||||
|
||||
var login *Login
|
||||
if loginValue == "" {
|
||||
login, err = getDefaultLogin()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
login = getLoginByName(loginValue)
|
||||
if login == nil {
|
||||
log.Fatal("Login name " + loginValue + " does not exist")
|
||||
}
|
||||
}
|
||||
|
||||
return login
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ import (
|
|||
"log"
|
||||
"strconv"
|
||||
6543 marked this conversation as resolved
Outdated
|
||||
|
||||
"code.gitea.io/tea/modules/intern"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/charmbracelet/glamour"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
@ -47,7 +49,7 @@ func runIssues(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
func runIssueDetail(ctx *cli.Context, index string) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
idx, err := argToIndex(index)
|
||||
if err != nil {
|
||||
|
@ -71,7 +73,7 @@ func runIssueDetail(ctx *cli.Context, index string) error {
|
|||
}
|
||||
|
||||
func runIssuesList(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
state := gitea.StateOpen
|
||||
switch ctx.String("state") {
|
||||
|
@ -105,7 +107,7 @@ func runIssuesList(ctx *cli.Context) error {
|
|||
var values [][]string
|
||||
|
||||
if len(issues) == 0 {
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -130,7 +132,7 @@ func runIssuesList(ctx *cli.Context) error {
|
|||
},
|
||||
)
|
||||
}
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -156,7 +158,7 @@ var CmdIssuesCreate = cli.Command{
|
|||
}
|
||||
|
||||
func runIssuesCreate(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
_, _, err := login.Client().CreateIssue(owner, repo, gitea.CreateIssueOption{
|
||||
Title: ctx.String("title"),
|
||||
|
@ -206,7 +208,7 @@ var CmdIssuesClose = cli.Command{
|
|||
|
||||
// editIssueState abstracts the arg parsing to edit the given issue
|
||||
func editIssueState(ctx *cli.Context, opts gitea.EditIssueOption) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
if ctx.Args().Len() == 0 {
|
||||
log.Fatal(ctx.Command.ArgsUsage)
|
||||
}
|
||||
|
|
|
@ -12,8 +12,9 @@ import (
|
|||
"strconv"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/modules/intern"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/muesli/termenv"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
@ -41,7 +42,7 @@ var CmdLabels = cli.Command{
|
|||
}
|
||||
|
||||
func runLabels(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
headers := []string{
|
||||
"Index",
|
||||
|
@ -58,7 +59,7 @@ func runLabels(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
if len(labels) == 0 {
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -89,7 +90,7 @@ func runLabels(ctx *cli.Context) error {
|
|||
},
|
||||
)
|
||||
}
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
@ -143,7 +144,7 @@ func splitLabelLine(line string) (string, string, string) {
|
|||
}
|
||||
|
||||
func runLabelCreate(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
labelFile := ctx.String("file")
|
||||
var err error
|
||||
|
@ -214,7 +215,7 @@ var CmdLabelUpdate = cli.Command{
|
|||
}
|
||||
|
||||
func runLabelUpdate(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
id := ctx.Int64("id")
|
||||
var pName, pColor, pDescription *string
|
||||
|
@ -262,7 +263,7 @@ var CmdLabelDelete = cli.Command{
|
|||
}
|
||||
|
||||
func runLabelDelete(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
_, err := login.Client().DeleteLabel(owner, repo, ctx.Int64("id"))
|
||||
if err != nil {
|
||||
|
|
37
cmd/login.go
37
cmd/login.go
|
@ -15,8 +15,9 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/modules/intern"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/skratchdot/open-golang/open"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
@ -45,7 +46,7 @@ var cmdLoginEdit = cli.Command{
|
|||
}
|
||||
|
||||
func runLoginEdit(ctx *cli.Context) error {
|
||||
return open.Start(yamlConfigPath)
|
||||
return open.Start(intern.GetConfigPath())
|
||||
}
|
||||
|
||||
// cmdLoginSetDefault represents to login a gitea server.
|
||||
|
@ -59,11 +60,11 @@ var cmdLoginSetDefault = cli.Command{
|
|||
}
|
||||
|
||||
func runLoginSetDefault(ctx *cli.Context) error {
|
||||
if err := loadConfig(yamlConfigPath); err != nil {
|
||||
if err := intern.LoadConfig(); err != nil {
|
||||
return err
|
||||
}
|
||||
if ctx.Args().Len() == 0 {
|
||||
l, err := getDefaultLogin()
|
||||
l, err := intern.GetDefaultLogin()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
@ -71,10 +72,10 @@ func runLoginSetDefault(ctx *cli.Context) error {
|
|||
return nil
|
||||
}
|
||||
loginExist := false
|
||||
for i := range config.Logins {
|
||||
config.Logins[i].Default = false
|
||||
if config.Logins[i].Name == ctx.Args().First() {
|
||||
config.Logins[i].Default = true
|
||||
for i := range intern.Config.Logins {
|
||||
intern.Config.Logins[i].Default = false
|
||||
if intern.Config.Logins[i].Name == ctx.Args().First() {
|
||||
intern.Config.Logins[i].Default = true
|
||||
loginExist = true
|
||||
}
|
||||
}
|
||||
|
@ -83,7 +84,7 @@ func runLoginSetDefault(ctx *cli.Context) error {
|
|||
return fmt.Errorf("login '%s' not found", ctx.Args().First())
|
||||
}
|
||||
|
||||
return saveConfig(yamlConfigPath)
|
||||
return intern.SaveConfig()
|
||||
}
|
||||
|
||||
// CmdLogin represents to login a gitea server.
|
||||
|
@ -236,9 +237,9 @@ func runLoginAddMain(name, token, user, passwd, sshKey, giteaURL string, insecur
|
|||
log.Fatal("No user set")
|
||||
}
|
||||
|
||||
err := loadConfig(yamlConfigPath)
|
||||
err := intern.LoadConfig()
|
||||
if err != nil {
|
||||
log.Fatal("Unable to load config file " + yamlConfigPath)
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
httpClient := &http.Client{}
|
||||
|
@ -293,7 +294,7 @@ func runLoginAddMain(name, token, user, passwd, sshKey, giteaURL string, insecur
|
|||
return err
|
||||
}
|
||||
name = strings.ReplaceAll(strings.Title(parsedURL.Host), ".", "")
|
||||
for _, l := range config.Logins {
|
||||
for _, l := range intern.Config.Logins {
|
||||
if l.Name == name {
|
||||
name += "_" + u.UserName
|
||||
break
|
||||
|
@ -301,7 +302,7 @@ func runLoginAddMain(name, token, user, passwd, sshKey, giteaURL string, insecur
|
|||
}
|
||||
}
|
||||
|
||||
err = addLogin(Login{
|
||||
err = intern.AddLogin(intern.Login{
|
||||
Name: name,
|
||||
URL: giteaURL,
|
||||
Token: token,
|
||||
|
@ -313,7 +314,7 @@ func runLoginAddMain(name, token, user, passwd, sshKey, giteaURL string, insecur
|
|||
log.Fatal(err)
|
||||
}
|
||||
|
||||
err = saveConfig(yamlConfigPath)
|
||||
err = intern.SaveConfig()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
@ -331,9 +332,9 @@ var cmdLoginList = cli.Command{
|
|||
}
|
||||
|
||||
func runLoginList(ctx *cli.Context) error {
|
||||
err := loadConfig(yamlConfigPath)
|
||||
err := intern.LoadConfig()
|
||||
if err != nil {
|
||||
log.Fatal("Unable to load config file " + yamlConfigPath)
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
headers := []string{
|
||||
|
@ -346,7 +347,7 @@ func runLoginList(ctx *cli.Context) error {
|
|||
|
||||
var values [][]string
|
||||
|
||||
for _, l := range config.Logins {
|
||||
for _, l := range intern.Config.Logins {
|
||||
values = append(values, []string{
|
||||
l.Name,
|
||||
l.URL,
|
||||
|
@ -356,7 +357,7 @@ func runLoginList(ctx *cli.Context) error {
|
|||
})
|
||||
}
|
||||
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -9,6 +9,8 @@ import (
|
|||
"log"
|
||||
"os"
|
||||
|
||||
"code.gitea.io/tea/modules/intern"
|
||||
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
|
@ -37,23 +39,23 @@ func runLogout(ctx *cli.Context) error {
|
|||
return errors.New("Please specify a login name")
|
||||
}
|
||||
|
||||
err := loadConfig(yamlConfigPath)
|
||||
err := intern.LoadConfig()
|
||||
if err != nil {
|
||||
log.Fatal("Unable to load config file " + yamlConfigPath)
|
||||
log.Fatal(err)
|
||||
}
|
||||
|
||||
var idx = -1
|
||||
for i, l := range config.Logins {
|
||||
for i, l := range intern.Config.Logins {
|
||||
if l.Name == name {
|
||||
idx = i
|
||||
break
|
||||
}
|
||||
}
|
||||
if idx > -1 {
|
||||
config.Logins = append(config.Logins[:idx], config.Logins[idx+1:]...)
|
||||
err = saveConfig(yamlConfigPath)
|
||||
intern.Config.Logins = append(intern.Config.Logins[:idx], intern.Config.Logins[idx+1:]...)
|
||||
err = intern.SaveConfig()
|
||||
if err != nil {
|
||||
log.Fatal("Unable to save config file " + yamlConfigPath)
|
||||
log.Fatal(err)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -8,6 +8,8 @@ import (
|
|||
"fmt"
|
||||
"strconv"
|
||||
|
||||
"code.gitea.io/tea/modules/intern"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
@ -62,7 +64,7 @@ var CmdMilestoneRemoveIssue = cli.Command{
|
|||
}
|
||||
|
||||
func runMilestoneIssueList(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
client := login.Client()
|
||||
|
||||
state := gitea.StateOpen
|
||||
|
@ -112,7 +114,7 @@ func runMilestoneIssueList(ctx *cli.Context) error {
|
|||
var values [][]string
|
||||
|
||||
if len(issues) == 0 {
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -137,12 +139,12 @@ func runMilestoneIssueList(ctx *cli.Context) error {
|
|||
},
|
||||
)
|
||||
}
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
return nil
|
||||
}
|
||||
|
||||
func runMilestoneIssueAdd(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
client := login.Client()
|
||||
if ctx.Args().Len() == 0 {
|
||||
return fmt.Errorf("need two arguments")
|
||||
|
@ -168,7 +170,7 @@ func runMilestoneIssueAdd(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
func runMilestoneIssueRemove(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
client := login.Client()
|
||||
if ctx.Args().Len() == 0 {
|
||||
return fmt.Errorf("need two arguments")
|
||||
|
|
|
@ -8,6 +8,8 @@ import (
|
|||
"fmt"
|
||||
"log"
|
||||
|
||||
"code.gitea.io/tea/modules/intern"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
@ -56,7 +58,7 @@ func runMilestones(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
func runMilestoneDetail(ctx *cli.Context, name string) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
client := login.Client()
|
||||
|
||||
milestone, _, err := client.GetMilestoneByName(owner, repo, name)
|
||||
|
@ -77,7 +79,7 @@ func runMilestoneDetail(ctx *cli.Context, name string) error {
|
|||
}
|
||||
|
||||
func runMilestonesList(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
state := gitea.StateOpen
|
||||
switch ctx.String("state") {
|
||||
|
@ -129,7 +131,7 @@ func runMilestonesList(ctx *cli.Context) error {
|
|||
|
||||
values = append(values, item)
|
||||
}
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -160,7 +162,7 @@ var CmdMilestonesCreate = cli.Command{
|
|||
}
|
||||
|
||||
func runMilestonesCreate(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
title := ctx.String("title")
|
||||
if len(title) == 0 {
|
||||
|
@ -207,7 +209,7 @@ var CmdMilestonesClose = cli.Command{
|
|||
}
|
||||
|
||||
func editMilestoneStatus(ctx *cli.Context, close bool) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
client := login.Client()
|
||||
|
||||
state := gitea.StateOpen
|
||||
|
@ -234,7 +236,7 @@ var CmdMilestonesDelete = cli.Command{
|
|||
}
|
||||
|
||||
func deleteMilestone(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
client := login.Client()
|
||||
|
||||
_, err := client.DeleteMilestoneByName(owner, repo, ctx.Args().First())
|
||||
|
|
|
@ -8,6 +8,8 @@ import (
|
|||
"log"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/tea/modules/intern"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
@ -57,13 +59,13 @@ func runNotifications(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
if ctx.Bool("all") {
|
||||
login := initCommandLoginOnly()
|
||||
login := intern.InitCommandLoginOnly(globalLoginValue)
|
||||
news, _, err = login.Client().ListNotifications(gitea.ListNotificationOptions{
|
||||
ListOptions: listOpts,
|
||||
Status: status,
|
||||
})
|
||||
} else {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
news, _, err = login.Client().ListRepoNotifications(owner, repo, gitea.ListNotificationOptions{
|
||||
ListOptions: listOpts,
|
||||
Status: status,
|
||||
|
@ -107,7 +109,7 @@ func runNotifications(ctx *cli.Context) error {
|
|||
}
|
||||
|
||||
if len(values) != 0 {
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
"strings"
|
||||
|
||||
local_git "code.gitea.io/tea/modules/git"
|
||||
"code.gitea.io/tea/modules/intern"
|
||||
|
||||
"github.com/skratchdot/open-golang/open"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
@ -25,7 +26,7 @@ var CmdOpen = cli.Command{
|
|||
}
|
||||
|
||||
func runOpen(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
var suffix string
|
||||
number := ctx.Args().Get(0)
|
||||
|
|
17
cmd/pulls.go
17
cmd/pulls.go
|
@ -11,6 +11,7 @@ import (
|
|||
"strings"
|
||||
|
||||
local_git "code.gitea.io/tea/modules/git"
|
||||
"code.gitea.io/tea/modules/intern"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/charmbracelet/glamour"
|
||||
|
@ -53,7 +54,7 @@ var CmdPullsList = cli.Command{
|
|||
}
|
||||
|
||||
func runPullDetail(ctx *cli.Context, index string) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
idx, err := argToIndex(index)
|
||||
if err != nil {
|
||||
|
@ -75,7 +76,7 @@ func runPullDetail(ctx *cli.Context, index string) error {
|
|||
}
|
||||
|
||||
func runPullsList(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
state := gitea.StateOpen
|
||||
switch ctx.String("state") {
|
||||
|
@ -107,7 +108,7 @@ func runPullsList(ctx *cli.Context) error {
|
|||
var values [][]string
|
||||
|
||||
if len(prs) == 0 {
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -135,7 +136,7 @@ func runPullsList(ctx *cli.Context) error {
|
|||
},
|
||||
)
|
||||
}
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -151,7 +152,7 @@ var CmdPullsCheckout = cli.Command{
|
|||
}
|
||||
|
||||
func runPullsCheckout(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
if ctx.Args().Len() != 1 {
|
||||
log.Fatal("Must specify a PR index")
|
||||
}
|
||||
|
@ -235,7 +236,7 @@ var CmdPullsClean = cli.Command{
|
|||
}
|
||||
|
||||
func runPullsClean(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
if ctx.Args().Len() != 1 {
|
||||
return fmt.Errorf("Must specify a PR index")
|
||||
}
|
||||
|
@ -336,7 +337,7 @@ var CmdPullsCreate = cli.Command{
|
|||
}
|
||||
|
||||
func runPullsCreate(ctx *cli.Context) error {
|
||||
login, ownerArg, repoArg := initCommand()
|
||||
login, ownerArg, repoArg := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
client := login.Client()
|
||||
|
||||
repo, _, err := client.GetRepo(ownerArg, repoArg)
|
||||
|
@ -393,7 +394,7 @@ func runPullsCreate(ctx *cli.Context) error {
|
|||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
owner, _ := getOwnerAndRepo(strings.TrimLeft(url.Path, "/"), "")
|
||||
owner, _ := intern.GetOwnerAndRepo(strings.TrimLeft(url.Path, "/"), "")
|
||||
head = fmt.Sprintf("%s:%s", owner, branchName)
|
||||
}
|
||||
|
||||
|
|
|
@ -12,8 +12,9 @@ import (
|
|||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/modules/intern"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
||||
|
@ -46,7 +47,7 @@ var CmdReleaseList = cli.Command{
|
|||
}
|
||||
|
||||
func runReleases(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
releases, _, err := login.Client().ListReleases(owner, repo, gitea.ListReleasesOptions{ListOptions: getListOptions(ctx)})
|
||||
if err != nil {
|
||||
|
@ -64,7 +65,7 @@ func runReleases(ctx *cli.Context) error {
|
|||
var values [][]string
|
||||
|
||||
if len(releases) == 0 {
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -86,7 +87,7 @@ func runReleases(ctx *cli.Context) error {
|
|||
},
|
||||
)
|
||||
}
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -135,7 +136,7 @@ var CmdReleaseCreate = cli.Command{
|
|||
}
|
||||
|
||||
func runReleaseCreate(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
release, resp, err := login.Client().CreateRelease(owner, repo, gitea.CreateReleaseOption{
|
||||
TagName: ctx.String("tag"),
|
||||
|
@ -185,7 +186,7 @@ var CmdReleaseDelete = cli.Command{
|
|||
}
|
||||
|
||||
func runReleaseDelete(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
client := login.Client()
|
||||
|
||||
tag := ctx.Args().First()
|
||||
|
@ -266,7 +267,7 @@ var CmdReleaseEdit = cli.Command{
|
|||
}
|
||||
|
||||
func runReleaseEdit(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
client := login.Client()
|
||||
|
||||
tag := ctx.Args().First()
|
||||
|
|
11
cmd/repos.go
11
cmd/repos.go
|
@ -10,6 +10,7 @@ import (
|
|||
"net/http"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/tea/modules/intern"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
|
@ -140,7 +141,7 @@ func runRepos(ctx *cli.Context) error {
|
|||
|
||||
// runReposList list repositories
|
||||
func runReposList(ctx *cli.Context) error {
|
||||
login := initCommandLoginOnly()
|
||||
login := intern.InitCommandLoginOnly(globalLoginValue)
|
||||
client := login.Client()
|
||||
|
||||
var ownerID int64
|
||||
|
@ -233,15 +234,15 @@ func runReposList(ctx *cli.Context) error {
|
|||
},
|
||||
)
|
||||
}
|
||||
Output(outputValue, headers, values)
|
||||
Output(globalOutputValue, headers, values)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func runRepoDetail(_ *cli.Context, path string) error {
|
||||
login := initCommandLoginOnly()
|
||||
login := intern.InitCommandLoginOnly(globalLoginValue)
|
||||
client := login.Client()
|
||||
repoOwner, repoName := getOwnerAndRepo(path, login.User)
|
||||
repoOwner, repoName := intern.GetOwnerAndRepo(path, login.User)
|
||||
repo, _, err := client.GetRepo(repoOwner, repoName)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -283,7 +284,7 @@ func runRepoDetail(_ *cli.Context, path string) error {
|
|||
}
|
||||
|
||||
func runRepoCreate(ctx *cli.Context) error {
|
||||
login := initCommandLoginOnly()
|
||||
login := intern.InitCommandLoginOnly(globalLoginValue)
|
||||
client := login.Client()
|
||||
var (
|
||||
repo *gitea.Repository
|
||||
|
|
13
cmd/times.go
13
cmd/times.go
|
@ -11,8 +11,9 @@ import (
|
|||
"strings"
|
||||
"time"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"code.gitea.io/tea/modules/intern"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
"github.com/araddon/dateparse"
|
||||
"github.com/urfave/cli/v2"
|
||||
)
|
||||
|
@ -52,7 +53,7 @@ var CmdTrackedTimes = cli.Command{
|
|||
}
|
||||
|
||||
func runTrackedTimes(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
client := login.Client()
|
||||
|
||||
if err := client.CheckServerVersionConstraint(">= 1.11"); err != nil {
|
||||
|
@ -97,7 +98,7 @@ func runTrackedTimes(ctx *cli.Context) error {
|
|||
}
|
||||
}
|
||||
|
||||
printTrackedTimes(times, outputValue, from, until, ctx.Bool("total"))
|
||||
printTrackedTimes(times, globalOutputValue, from, until, ctx.Bool("total"))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -169,7 +170,7 @@ var CmdTrackedTimesAdd = cli.Command{
|
|||
}
|
||||
|
||||
func runTrackedTimesAdd(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
|
||||
if ctx.Args().Len() < 2 {
|
||||
return fmt.Errorf("No issue or duration specified.\nUsage:\t%s", ctx.Command.UsageText)
|
||||
|
@ -206,7 +207,7 @@ var CmdTrackedTimesDelete = cli.Command{
|
|||
}
|
||||
|
||||
func runTrackedTimesDelete(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
client := login.Client()
|
||||
|
||||
if err := client.CheckServerVersionConstraint(">= 1.11"); err != nil {
|
||||
|
@ -246,7 +247,7 @@ var CmdTrackedTimesReset = cli.Command{
|
|||
}
|
||||
|
||||
func runTrackedTimesReset(ctx *cli.Context) error {
|
||||
login, owner, repo := initCommand()
|
||||
login, owner, repo := intern.InitCommand(globalRepoValue, globalLoginValue, globalRemoteValue)
|
||||
client := login.Client()
|
||||
|
||||
if err := client.CheckServerVersionConstraint(">= 1.11"); err != nil {
|
||||
|
|
153
modules/intern/config.go
Normal file
153
modules/intern/config.go
Normal file
|
@ -0,0 +1,153 @@
|
|||
// Copyright 2018 The Gitea Authors. All rights reserved.
|
||||
6543 marked this conversation as resolved
Outdated
6543
commented
2020 2020
|
||||
// Use of this source code is governed by a MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package intern
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
|
||||
"code.gitea.io/tea/modules/git"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// Config reprensents local configurations
|
||||
6543 marked this conversation as resolved
Outdated
6543
commented
LocalConfig LocalConfig
|
||||
type LocalConfig struct {
|
||||
Logins []Login `yaml:"logins"`
|
||||
}
|
||||
|
||||
var (
|
||||
Config LocalConfig
|
||||
yamlConfigPath string
|
||||
)
|
||||
|
||||
func init() {
|
||||
6543 marked this conversation as resolved
Outdated
6543
commented
// TODO: dont rely on intransparent init func to detect tea config // TODO: dont rely on intransparent init func to detect tea config
|
||||
homeDir, err := utils.Home()
|
||||
if err != nil {
|
||||
log.Fatal("Retrieve home dir failed")
|
||||
}
|
||||
|
||||
dir := filepath.Join(homeDir, ".tea")
|
||||
err = os.MkdirAll(dir, os.ModePerm)
|
||||
if err != nil {
|
||||
log.Fatal("Init tea config dir " + dir + " failed")
|
||||
}
|
||||
|
||||
yamlConfigPath = filepath.Join(dir, "tea.yml")
|
||||
}
|
||||
|
||||
func LoadConfig() error {
|
||||
ymlPath := yamlConfigPath
|
||||
exist, _ := utils.FileExist(ymlPath)
|
||||
if exist {
|
||||
fmt.Println("Found config file", ymlPath)
|
||||
bs, err := ioutil.ReadFile(ymlPath)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
err = yaml.Unmarshal(bs, &Config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func SaveConfig() error {
|
||||
ymlPath := yamlConfigPath
|
||||
bs, err := yaml.Marshal(Config)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return ioutil.WriteFile(ymlPath, bs, 0660)
|
||||
}
|
||||
|
||||
func curGitRepoPath(repoValue, remoteValue string) (*Login, string, error) {
|
||||
var err error
|
||||
var repo *git.TeaRepo
|
||||
if len(repoValue) == 0 {
|
||||
repo, err = git.RepoForWorkdir()
|
||||
} else {
|
||||
repo, err = git.RepoFromPath(repoValue)
|
||||
}
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
gitConfig, err := repo.Config()
|
||||
if err != nil {
|
||||
return nil, "", err
|
||||
}
|
||||
|
||||
// if no remote
|
||||
if len(gitConfig.Remotes) == 0 {
|
||||
return nil, "", errors.New("No remote(s) found in this Git repository")
|
||||
}
|
||||
|
||||
// if only one remote exists
|
||||
if len(gitConfig.Remotes) >= 1 && len(remoteValue) == 0 {
|
||||
for remote := range gitConfig.Remotes {
|
||||
remoteValue = remote
|
||||
}
|
||||
if len(gitConfig.Remotes) > 1 {
|
||||
// if master branch is present, use it as the default remote
|
||||
masterBranch, ok := gitConfig.Branches["master"]
|
||||
if ok {
|
||||
if len(masterBranch.Remote) > 0 {
|
||||
remoteValue = masterBranch.Remote
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
remoteConfig, ok := gitConfig.Remotes[remoteValue]
|
||||
if !ok || remoteConfig == nil {
|
||||
return nil, "", errors.New("Remote " + remoteValue + " not found in this Git repository")
|
||||
}
|
||||
|
||||
for _, l := range Config.Logins {
|
||||
for _, u := range remoteConfig.URLs {
|
||||
p, err := git.ParseURL(strings.TrimSpace(u))
|
||||
if err != nil {
|
||||
return nil, "", fmt.Errorf("Git remote URL parse failed: %s", err.Error())
|
||||
}
|
||||
if strings.EqualFold(p.Scheme, "http") || strings.EqualFold(p.Scheme, "https") {
|
||||
if strings.HasPrefix(u, l.URL) {
|
||||
ps := strings.Split(p.Path, "/")
|
||||
path := strings.Join(ps[len(ps)-2:], "/")
|
||||
return &l, strings.TrimSuffix(path, ".git"), nil
|
||||
}
|
||||
} else if strings.EqualFold(p.Scheme, "ssh") {
|
||||
if l.GetSSHHost() == strings.Split(p.Host, ":")[0] {
|
||||
return &l, strings.TrimLeft(strings.TrimSuffix(p.Path, ".git"), "/"), nil
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return nil, "", errors.New("No Gitea login found. You might want to specify --repo (and --login) to work outside of a repository")
|
||||
}
|
||||
|
||||
func GetConfigPath() string {
|
||||
return yamlConfigPath
|
||||
}
|
||||
|
||||
func GetOwnerAndRepo(repoPath, user string) (string, string) {
|
||||
if len(repoPath) == 0 {
|
||||
return "", ""
|
||||
}
|
||||
p := strings.Split(repoPath, "/")
|
||||
if len(p) >= 2 {
|
||||
return p[0], p[1]
|
||||
}
|
||||
return user, repoPath
|
||||
}
|
176
modules/intern/login.go
Normal file
176
modules/intern/login.go
Normal file
|
@ -0,0 +1,176 @@
|
|||
// 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 intern
|
||||
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"log"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"code.gitea.io/sdk/gitea"
|
||||
)
|
||||
|
||||
// Login represents a login to a gitea server, you even could add multiple logins for one gitea server
|
||||
type Login struct {
|
||||
Name string `yaml:"name"`
|
||||
URL string `yaml:"url"`
|
||||
Token string `yaml:"token"`
|
||||
Default bool `yaml:"default"`
|
||||
SSHHost string `yaml:"ssh_host"`
|
||||
// optional path to the private key
|
||||
SSHKey string `yaml:"ssh_key"`
|
||||
Insecure bool `yaml:"insecure"`
|
||||
// optional gitea username
|
||||
User string `yaml:"user"`
|
||||
}
|
||||
|
||||
// Client returns a client to operate Gitea API
|
||||
func (l *Login) Client() *gitea.Client {
|
||||
httpClient := &http.Client{}
|
||||
if l.Insecure {
|
||||
cookieJar, _ := cookiejar.New(nil)
|
||||
|
||||
httpClient = &http.Client{
|
||||
Jar: cookieJar,
|
||||
Transport: &http.Transport{
|
||||
TLSClientConfig: &tls.Config{InsecureSkipVerify: true},
|
||||
}}
|
||||
}
|
||||
|
||||
client, err := gitea.NewClient(l.URL,
|
||||
gitea.SetToken(l.Token),
|
||||
gitea.SetHTTPClient(httpClient),
|
||||
)
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
return client
|
||||
}
|
||||
|
||||
// GetSSHHost returns SSH host name
|
||||
func (l *Login) GetSSHHost() string {
|
||||
if l.SSHHost != "" {
|
||||
return l.SSHHost
|
||||
}
|
||||
|
||||
u, err := url.Parse(l.URL)
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
return u.Hostname()
|
||||
}
|
||||
|
||||
func GetDefaultLogin() (*Login, error) {
|
||||
if len(Config.Logins) == 0 {
|
||||
return nil, errors.New("No available login")
|
||||
}
|
||||
for _, l := range Config.Logins {
|
||||
if l.Default {
|
||||
return &l, nil
|
||||
}
|
||||
}
|
||||
|
||||
return &Config.Logins[0], nil
|
||||
}
|
||||
|
||||
func GetLoginByName(name string) *Login {
|
||||
for _, l := range Config.Logins {
|
||||
if l.Name == name {
|
||||
return &l
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func AddLogin(login Login) error {
|
||||
for _, l := range Config.Logins {
|
||||
if l.Name == login.Name {
|
||||
if l.URL == login.URL && l.Token == login.Token {
|
||||
return nil
|
||||
}
|
||||
return errors.New("Login name has already been used")
|
||||
}
|
||||
if l.URL == login.URL && l.Token == login.Token {
|
||||
return errors.New("URL has been added")
|
||||
}
|
||||
}
|
||||
|
||||
u, err := url.Parse(login.URL)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if login.SSHHost == "" {
|
||||
login.SSHHost = u.Hostname()
|
||||
}
|
||||
Config.Logins = append(Config.Logins, login)
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// InitCommand returns repository and *Login based on flags
|
||||
func InitCommand(repoValue, loginValue, remoteValue string) (*Login, string, string) {
|
||||
var login *Login
|
||||
|
||||
err := LoadConfig()
|
||||
if err != nil {
|
||||
log.Fatal("load config file failed ", yamlConfigPath)
|
||||
}
|
||||
|
||||
if login, err = GetDefaultLogin(); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
exist, err := utils.PathExists(repoValue)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
|
||||
if exist || len(repoValue) == 0 {
|
||||
login, repoValue, err = curGitRepoPath(repoValue, remoteValue)
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if loginValue != "" {
|
||||
login = GetLoginByName(loginValue)
|
||||
if login == nil {
|
||||
log.Fatal("Login name " + loginValue + " does not exist")
|
||||
}
|
||||
}
|
||||
|
||||
owner, repo := GetOwnerAndRepo(repoValue, login.User)
|
||||
return login, owner, repo
|
||||
}
|
||||
|
||||
// InitCommandLoginOnly return *Login based on flags
|
||||
func InitCommandLoginOnly(loginValue string) *Login {
|
||||
err := LoadConfig()
|
||||
if err != nil {
|
||||
log.Fatal("load config file failed ", yamlConfigPath)
|
||||
}
|
||||
|
||||
var login *Login
|
||||
if loginValue == "" {
|
||||
login, err = GetDefaultLogin()
|
||||
if err != nil {
|
||||
log.Fatal(err)
|
||||
}
|
||||
} else {
|
||||
login = GetLoginByName(loginValue)
|
||||
if login == nil {
|
||||
log.Fatal("Login name " + loginValue + " does not exist")
|
||||
}
|
||||
}
|
||||
|
||||
return login
|
||||
}
|
|
@ -5,6 +5,7 @@
|
|||
package utils
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"os"
|
||||
)
|
||||
|
||||
|
@ -19,3 +20,18 @@ func PathExists(path string) (bool, error) {
|
|||
}
|
||||
return true, err
|
||||
}
|
||||
|
||||
// FileExist returns whether the given file exists or not
|
||||
func FileExist(fileName string) (bool, error) {
|
||||
f, err := os.Stat(fileName)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
return false, nil
|
||||
}
|
||||
return false, err
|
||||
}
|
||||
if f.IsDir() {
|
||||
return false, errors.New("A directory with the same name exists")
|
||||
}
|
||||
return true, nil
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue
Block a user
We need a blank line.
between internal modues ?!?