mirror of
https://gitea.com/gitea/tea.git
synced 2025-10-30 16:55:25 +01:00
When there is no login detected, list all possible logins to select
This commit is contained in:
@@ -6,7 +6,6 @@ package context
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"log"
|
||||
"os"
|
||||
"path"
|
||||
"strconv"
|
||||
@@ -16,15 +15,11 @@ import (
|
||||
"code.gitea.io/tea/modules/config"
|
||||
"code.gitea.io/tea/modules/debug"
|
||||
"code.gitea.io/tea/modules/git"
|
||||
"code.gitea.io/tea/modules/theme"
|
||||
"code.gitea.io/tea/modules/utils"
|
||||
|
||||
"github.com/charmbracelet/huh"
|
||||
gogit "github.com/go-git/go-git/v5"
|
||||
"github.com/urfave/cli/v3"
|
||||
)
|
||||
|
||||
var errNotAGiteaRepo = errors.New("No Gitea login found. You might want to specify --repo (and --login) to work outside of a repository")
|
||||
var ErrNotAGiteaRepo = errors.New("No Gitea login found. You might want to specify --repo (and --login) to work outside of a repository")
|
||||
|
||||
// TeaContext contains all context derived during command initialization and wraps cli.Context
|
||||
type TeaContext struct {
|
||||
@@ -65,108 +60,8 @@ type CtxRequirement struct {
|
||||
RemoteRepo bool
|
||||
}
|
||||
|
||||
// InitCommand resolves the application context, and returns the active login, and if
|
||||
// available the repo slug. It does this by reading the config file for logins, parsing
|
||||
// the remotes of the .git repo specified in repoFlag or $PWD, and using overrides from
|
||||
// command flags. If a local git repo can't be found, repo slug values are unset.
|
||||
func InitCommand(cmd *cli.Command) *TeaContext {
|
||||
// these flags are used as overrides to the context detection via local git repo
|
||||
repoFlag := cmd.String("repo")
|
||||
loginFlag := cmd.String("login")
|
||||
remoteFlag := cmd.String("remote")
|
||||
|
||||
var (
|
||||
c TeaContext
|
||||
err error
|
||||
repoPath string // empty means PWD
|
||||
repoFlagPathExists bool
|
||||
)
|
||||
|
||||
// check if repoFlag can be interpreted as path to local repo.
|
||||
if len(repoFlag) != 0 {
|
||||
if repoFlagPathExists, err = utils.DirExists(repoFlag); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
if repoFlagPathExists {
|
||||
repoPath = repoFlag
|
||||
}
|
||||
}
|
||||
|
||||
if len(remoteFlag) == 0 {
|
||||
remoteFlag = config.GetPreferences().FlagDefaults.Remote
|
||||
}
|
||||
|
||||
if repoPath == "" {
|
||||
if repoPath, err = os.Getwd(); err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
// try to read local git repo & extract context: if repoFlag specifies a valid path, read repo in that dir,
|
||||
// otherwise attempt PWD. if no repo is found, continue with default login
|
||||
if c.LocalRepo, c.Login, c.RepoSlug, err = contextFromLocalRepo(repoPath, remoteFlag); err != nil {
|
||||
if err == errNotAGiteaRepo || err == gogit.ErrRepositoryNotExists {
|
||||
// we can deal with that, commands needing the optional values use ctx.Ensure()
|
||||
} else {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
if len(repoFlag) != 0 && !repoFlagPathExists {
|
||||
// if repoFlag is not a valid path, use it to override repoSlug
|
||||
c.RepoSlug = repoFlag
|
||||
}
|
||||
|
||||
// override config user with env variable
|
||||
envLogin := GetLoginByEnvVar()
|
||||
if envLogin != nil {
|
||||
_, err := utils.ValidateAuthenticationMethod(envLogin.URL, envLogin.Token, "", "", false, "", "")
|
||||
if err != nil {
|
||||
log.Fatal(err.Error())
|
||||
}
|
||||
c.Login = envLogin
|
||||
}
|
||||
|
||||
// override login from flag, or use default login if repo based detection failed
|
||||
if len(loginFlag) != 0 {
|
||||
c.Login = config.GetLoginByName(loginFlag)
|
||||
if c.Login == nil {
|
||||
log.Fatalf("Login name '%s' does not exist", loginFlag)
|
||||
}
|
||||
} else if c.Login == nil {
|
||||
if c.Login, err = config.GetDefaultLogin(); err != nil {
|
||||
if err.Error() == "No available login" {
|
||||
// TODO: maybe we can directly start interact.CreateLogin() (only if
|
||||
// we're sure we can interactively!), as gh cli does.
|
||||
fmt.Println(`No gitea login configured. To start using tea, first run
|
||||
tea login add
|
||||
and then run your command again.`)
|
||||
}
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
fallback := false
|
||||
if err := huh.NewConfirm().
|
||||
Title(fmt.Sprintf("NOTE: no gitea login detected, whether falling back to login '%s'?", c.Login.Name)).
|
||||
Value(&fallback).
|
||||
WithTheme(theme.GetTheme()).
|
||||
Run(); err != nil {
|
||||
log.Fatalf("Get confirm failed: %v", err)
|
||||
}
|
||||
if !fallback {
|
||||
os.Exit(1)
|
||||
}
|
||||
}
|
||||
|
||||
// parse reposlug (owner falling back to login owner if reposlug contains only repo name)
|
||||
c.Owner, c.Repo = utils.GetOwnerAndRepo(c.RepoSlug, c.Login.User)
|
||||
c.Command = cmd
|
||||
c.Output = cmd.String("output")
|
||||
return &c
|
||||
}
|
||||
|
||||
// contextFromLocalRepo discovers login & repo slug from the default branch remote of the given local repo
|
||||
func contextFromLocalRepo(repoPath, remoteValue string) (*git.TeaRepo, *config.Login, string, error) {
|
||||
// ContextFromLocalRepo discovers login & repo slug from the default branch remote of the given local repo
|
||||
func ContextFromLocalRepo(repoPath, remoteValue string) (*git.TeaRepo, *config.Login, string, error) {
|
||||
repo, err := git.RepoFromPath(repoPath)
|
||||
if err != nil {
|
||||
return nil, nil, "", err
|
||||
@@ -178,7 +73,7 @@ func contextFromLocalRepo(repoPath, remoteValue string) (*git.TeaRepo, *config.L
|
||||
debug.Printf("Get git config %v of %s in repo %s", gitConfig, remoteValue, repoPath)
|
||||
|
||||
if len(gitConfig.Remotes) == 0 {
|
||||
return repo, nil, "", errNotAGiteaRepo
|
||||
return repo, nil, "", ErrNotAGiteaRepo
|
||||
}
|
||||
|
||||
// When no preferred value is given, choose a remote to find a
|
||||
@@ -229,7 +124,7 @@ func contextFromLocalRepo(repoPath, remoteValue string) (*git.TeaRepo, *config.L
|
||||
}
|
||||
}
|
||||
|
||||
return repo, nil, "", errNotAGiteaRepo
|
||||
return repo, nil, "", ErrNotAGiteaRepo
|
||||
}
|
||||
|
||||
// MatchLogins matches the given remoteURL against the provided logins and returns
|
||||
@@ -274,7 +169,7 @@ func MatchLogins(remoteURL string, logins []config.Login) (*config.Login, string
|
||||
}
|
||||
}
|
||||
}
|
||||
return nil, "", errNotAGiteaRepo
|
||||
return nil, "", ErrNotAGiteaRepo
|
||||
}
|
||||
|
||||
// GetLoginByEnvVar returns a login based on environment variables, or nil if no login can be created
|
||||
|
||||
Reference in New Issue
Block a user