diff --git a/cmd/attachments/create.go b/cmd/attachments/create.go index dd46b46..7f8eafe 100644 --- a/cmd/attachments/create.go +++ b/cmd/attachments/create.go @@ -10,6 +10,7 @@ import ( "path/filepath" "code.gitea.io/tea/cmd/flags" + "code.gitea.io/tea/cmd/releases" "code.gitea.io/tea/modules/context" "github.com/urfave/cli/v3" @@ -37,15 +38,15 @@ func runReleaseAttachmentCreate(_ stdctx.Context, cmd *cli.Command) error { client := ctx.Login.Client() if ctx.Args().Len() < 2 { - return fmt.Errorf("No release tag or assets specified.\nUsage:\t%s", ctx.Command.UsageText) + return fmt.Errorf("no release tag or assets specified.\nUsage:\t%s", ctx.Command.UsageText) } tag := ctx.Args().First() if len(tag) == 0 { - return fmt.Errorf("Release tag needed to create attachment") + return fmt.Errorf("release tag needed to create attachment") } - release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client) + release, err := releases.GetReleaseByTag(ctx.Owner, ctx.Repo, tag, client) if err != nil { return err } diff --git a/cmd/attachments/delete.go b/cmd/attachments/delete.go index b9d0625..b6ebd63 100644 --- a/cmd/attachments/delete.go +++ b/cmd/attachments/delete.go @@ -8,6 +8,7 @@ import ( "fmt" "code.gitea.io/tea/cmd/flags" + "code.gitea.io/tea/cmd/releases" "code.gitea.io/tea/modules/context" "code.gitea.io/sdk/gitea" @@ -42,12 +43,12 @@ func runReleaseAttachmentDelete(_ stdctx.Context, cmd *cli.Command) error { client := ctx.Login.Client() if ctx.Args().Len() < 2 { - return fmt.Errorf("No release tag or attachment names specified.\nUsage:\t%s", ctx.Command.UsageText) + return fmt.Errorf("no release tag or attachment names specified.\nUsage:\t%s", ctx.Command.UsageText) } tag := ctx.Args().First() if len(tag) == 0 { - return fmt.Errorf("Release tag needed to delete attachment") + return fmt.Errorf("release tag needed to delete attachment") } if !ctx.Bool("confirm") { @@ -55,7 +56,7 @@ func runReleaseAttachmentDelete(_ stdctx.Context, cmd *cli.Command) error { return nil } - release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client) + release, err := releases.GetReleaseByTag(ctx.Owner, ctx.Repo, tag, client) if err != nil { return err } @@ -75,7 +76,7 @@ func runReleaseAttachmentDelete(_ stdctx.Context, cmd *cli.Command) error { } } if attachment == nil { - return fmt.Errorf("Release does not have attachment named '%s'", name) + return fmt.Errorf("release does not have attachment named '%s'", name) } _, err = client.DeleteReleaseAttachment(ctx.Owner, ctx.Repo, release.ID, attachment.ID) diff --git a/cmd/attachments/list.go b/cmd/attachments/list.go index c070ddc..1c91af3 100644 --- a/cmd/attachments/list.go +++ b/cmd/attachments/list.go @@ -8,6 +8,7 @@ import ( "fmt" "code.gitea.io/tea/cmd/flags" + "code.gitea.io/tea/cmd/releases" "code.gitea.io/tea/modules/context" "code.gitea.io/tea/modules/print" @@ -42,10 +43,10 @@ func RunReleaseAttachmentList(_ stdctx.Context, cmd *cli.Command) error { tag := ctx.Args().First() if len(tag) == 0 { - return fmt.Errorf("Release tag needed to list attachments") + return fmt.Errorf("release tag needed to list attachments") } - release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client) + release, err := releases.GetReleaseByTag(ctx.Owner, ctx.Repo, tag, client) if err != nil { return err } @@ -59,21 +60,3 @@ func RunReleaseAttachmentList(_ stdctx.Context, cmd *cli.Command) error { return print.ReleaseAttachmentsList(attachments, ctx.Output) } - -func getReleaseByTag(owner, repo, tag string, client *gitea.Client) (*gitea.Release, error) { - rl, _, err := client.ListReleases(owner, repo, gitea.ListReleasesOptions{ - ListOptions: gitea.ListOptions{Page: -1}, - }) - if err != nil { - return nil, err - } - if len(rl) == 0 { - return nil, fmt.Errorf("Repo does not have any release") - } - for _, r := range rl { - if r.TagName == tag { - return r, nil - } - } - return nil, fmt.Errorf("Release tag does not exist") -} diff --git a/cmd/clone.go b/cmd/clone.go index f634a5e..d65a5c2 100644 --- a/cmd/clone.go +++ b/cmd/clone.go @@ -76,9 +76,13 @@ func runRepoClone(ctx stdctx.Context, cmd *cli.Command) error { owner, repo = utils.GetOwnerAndRepo(url.Path, login.User) if url.Host != "" { - login = config.GetLoginByHost(url.Host) + var lookupErr error + login, lookupErr = config.GetLoginByHost(url.Host) + if lookupErr != nil { + return lookupErr + } if login == nil { - return fmt.Errorf("No login configured matching host '%s', run `tea login add` first", url.Host) + return fmt.Errorf("no login configured matching host '%s', run 'tea login add' first", url.Host) } debug.Printf("Matched login '%s' for host '%s'", login.Name, url.Host) } diff --git a/cmd/comment.go b/cmd/comment.go index cb69041..cdccbe6 100644 --- a/cmd/comment.go +++ b/cmd/comment.go @@ -46,7 +46,7 @@ func runAddComment(_ stdctx.Context, cmd *cli.Command) error { args := ctx.Args() if args.Len() == 0 { - return fmt.Errorf("Please specify issue / pr index") + return fmt.Errorf("please specify issue / pr index") } idx, err := utils.ArgToIndex(ctx.Args().First()) diff --git a/cmd/flags/csvflag.go b/cmd/flags/csvflag.go index a5ab6ec..a881f01 100644 --- a/cmd/flags/csvflag.go +++ b/cmd/flags/csvflag.go @@ -44,7 +44,7 @@ func (f CsvFlag) GetValues(cmd *cli.Command) ([]string, error) { if f.AvailableFields != nil && val != "" { for _, field := range selection { if !utils.Contains(f.AvailableFields, field) { - return nil, fmt.Errorf("Invalid field '%s'", field) + return nil, fmt.Errorf("invalid field '%s'", field) } } } diff --git a/cmd/flags/generic.go b/cmd/flags/generic.go index 46b1e5d..ee1362f 100644 --- a/cmd/flags/generic.go +++ b/cmd/flags/generic.go @@ -5,6 +5,7 @@ package flags import ( "errors" + "fmt" "code.gitea.io/sdk/gitea" "github.com/urfave/cli/v3" @@ -167,7 +168,7 @@ func ParseState(stateStr string) (gitea.StateType, error) { case "closed": return gitea.StateClosed, nil default: - return "", errors.New("unknown state '" + stateStr + "'") + return "", fmt.Errorf("unknown state '%s'", stateStr) } } @@ -184,6 +185,6 @@ func ParseIssueKind(kindStr string, defaultKind gitea.IssueType) (gitea.IssueTyp case "pull", "pulls", "pr": return gitea.IssueTypePull, nil default: - return "", errors.New("unknown kind '" + kindStr + "'") + return "", fmt.Errorf("unknown kind '%s'", kindStr) } } diff --git a/cmd/flags/issue_pr.go b/cmd/flags/issue_pr.go index 49aa72a..67a21e8 100644 --- a/cmd/flags/issue_pr.go +++ b/cmd/flags/issue_pr.go @@ -165,7 +165,7 @@ func GetIssuePRCreateFlags(ctx *context.TeaContext) (*gitea.CreateIssueOption, e } ms, _, err := client.GetMilestoneByName(ctx.Owner, ctx.Repo, milestoneName) if err != nil { - return nil, fmt.Errorf("Milestone '%s' not found", milestoneName) + return nil, fmt.Errorf("milestone '%s' not found", milestoneName) } opts.Milestone = ms.ID } diff --git a/cmd/labels.go b/cmd/labels.go index 9e00b73..cd0aef1 100644 --- a/cmd/labels.go +++ b/cmd/labels.go @@ -37,5 +37,5 @@ func runLabels(ctx context.Context, cmd *cli.Command) error { } func runLabelsDetails(cmd *cli.Command) error { - return fmt.Errorf("Not yet implemented") + return fmt.Errorf("not yet implemented") } diff --git a/cmd/login/delete.go b/cmd/login/delete.go index e0f6e5c..f9039be 100644 --- a/cmd/login/delete.go +++ b/cmd/login/delete.go @@ -5,8 +5,7 @@ package login import ( "context" - "errors" - "log" + "fmt" "code.gitea.io/tea/modules/config" @@ -27,7 +26,7 @@ var CmdLoginDelete = cli.Command{ func RunLoginDelete(_ context.Context, cmd *cli.Command) error { logins, err := config.GetLogins() if err != nil { - log.Fatal(err) + return err } var name string @@ -37,7 +36,7 @@ func RunLoginDelete(_ context.Context, cmd *cli.Command) error { } else if len(logins) == 1 { name = logins[0].Name } else { - return errors.New("Please specify a login name") + return fmt.Errorf("please specify a login name") } return config.DeleteLogin(name) diff --git a/cmd/login/edit.go b/cmd/login/edit.go index 4fa362e..a413715 100644 --- a/cmd/login/edit.go +++ b/cmd/login/edit.go @@ -5,7 +5,6 @@ package login import ( "context" - "log" "os" "os/exec" @@ -34,7 +33,7 @@ func runLoginEdit(_ context.Context, _ *cli.Command) error { cmd.Stdout = os.Stdout cmd.Stderr = os.Stderr if err := cmd.Run(); err != nil { - log.Fatal(err.Error()) + return err } } return open.Start(config.GetConfigPath()) diff --git a/cmd/login/helper.go b/cmd/login/helper.go index 62858ea..174c85f 100644 --- a/cmd/login/helper.go +++ b/cmd/login/helper.go @@ -7,7 +7,6 @@ import ( "bufio" "context" "fmt" - "log" "net/url" "os" "strings" @@ -93,7 +92,7 @@ var CmdLoginHelper = cli.Command{ } if len(wants["host"]) == 0 { - log.Fatal("Hostname is required") + return fmt.Errorf("hostname is required") } else if len(wants["protocol"]) == 0 { wants["protocol"] = "http" } @@ -104,20 +103,24 @@ var CmdLoginHelper = cli.Command{ var lookupErr error userConfig, lookupErr = config.GetLoginByName(loginName) if lookupErr != nil { - log.Fatal(lookupErr) + return lookupErr } if userConfig == nil { - log.Fatalf("Login '%s' not found", loginName) + return fmt.Errorf("login '%s' not found", loginName) } } else { - userConfig = config.GetLoginByHost(wants["host"]) + var lookupErr error + userConfig, lookupErr = config.GetLoginByHost(wants["host"]) + if lookupErr != nil { + return lookupErr + } if userConfig == nil { - log.Fatalf("No login found for host '%s'", wants["host"]) + return fmt.Errorf("no login found for host '%s'", wants["host"]) } } if len(userConfig.GetAccessToken()) == 0 { - log.Fatal("User not set") + return fmt.Errorf("user not set") } host, err := url.Parse(userConfig.URL) diff --git a/cmd/releases/create.go b/cmd/releases/create.go index 03d5eb7..bb525b5 100644 --- a/cmd/releases/create.go +++ b/cmd/releases/create.go @@ -104,7 +104,7 @@ func runReleaseCreate(_ stdctx.Context, cmd *cli.Command) error { }) if err != nil { if resp != nil && resp.StatusCode == http.StatusConflict { - return fmt.Errorf("There already is a release for this tag") + return fmt.Errorf("there is already a release for this tag") } return err } diff --git a/cmd/releases/delete.go b/cmd/releases/delete.go index e4c7609..9d6974d 100644 --- a/cmd/releases/delete.go +++ b/cmd/releases/delete.go @@ -55,7 +55,7 @@ func runReleaseDelete(_ stdctx.Context, cmd *cli.Command) error { } for _, tag := range ctx.Args().Slice() { - release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client) + release, err := GetReleaseByTag(ctx.Owner, ctx.Repo, tag, client) if err != nil { return err } diff --git a/cmd/releases/edit.go b/cmd/releases/edit.go index 641a7fc..cc53078 100644 --- a/cmd/releases/edit.go +++ b/cmd/releases/edit.go @@ -81,7 +81,7 @@ func runReleaseEdit(_ stdctx.Context, cmd *cli.Command) error { } for _, tag := range ctx.Args().Slice() { - release, err := getReleaseByTag(ctx.Owner, ctx.Repo, tag, client) + release, err := GetReleaseByTag(ctx.Owner, ctx.Repo, tag, client) if err != nil { return err } diff --git a/cmd/releases/list.go b/cmd/releases/list.go index adb3573..8d9af53 100644 --- a/cmd/releases/list.go +++ b/cmd/releases/list.go @@ -5,7 +5,6 @@ package releases import ( stdctx "context" - "fmt" "code.gitea.io/tea/cmd/flags" "code.gitea.io/tea/modules/context" @@ -48,21 +47,3 @@ func RunReleasesList(_ stdctx.Context, cmd *cli.Command) error { return print.ReleasesList(releases, ctx.Output) } - -func getReleaseByTag(owner, repo, tag string, client *gitea.Client) (*gitea.Release, error) { - rl, _, err := client.ListReleases(owner, repo, gitea.ListReleasesOptions{ - ListOptions: gitea.ListOptions{Page: -1}, - }) - if err != nil { - return nil, err - } - if len(rl) == 0 { - return nil, fmt.Errorf("Repo does not have any release") - } - for _, r := range rl { - if r.TagName == tag { - return r, nil - } - } - return nil, fmt.Errorf("Release tag does not exist") -} diff --git a/cmd/releases/utils.go b/cmd/releases/utils.go new file mode 100644 index 0000000..1e0ab50 --- /dev/null +++ b/cmd/releases/utils.go @@ -0,0 +1,29 @@ +// Copyright 2020 The Gitea Authors. All rights reserved. +// SPDX-License-Identifier: MIT + +package releases + +import ( + "fmt" + + "code.gitea.io/sdk/gitea" +) + +// GetReleaseByTag finds a release by its tag name. +func GetReleaseByTag(owner, repo, tag string, client *gitea.Client) (*gitea.Release, error) { + rl, _, err := client.ListReleases(owner, repo, gitea.ListReleasesOptions{ + ListOptions: gitea.ListOptions{Page: -1}, + }) + if err != nil { + return nil, err + } + if len(rl) == 0 { + return nil, fmt.Errorf("repo does not have any release") + } + for _, r := range rl { + if r.TagName == tag { + return r, nil + } + } + return nil, fmt.Errorf("release tag does not exist") +} diff --git a/cmd/repos/search.go b/cmd/repos/search.go index e395a2d..d4bb0fd 100644 --- a/cmd/repos/search.go +++ b/cmd/repos/search.go @@ -70,7 +70,7 @@ func runReposSearch(_ stdctx.Context, cmd *cli.Command) error { org, resp, err := client.GetOrg(teaCmd.String("owner")) if err != nil { if resp == nil || resp.StatusCode != http.StatusNotFound { - return fmt.Errorf("Could not find owner: %w", err) + return fmt.Errorf("could not find owner: %w", err) } // if owner is no org, its a user diff --git a/cmd/times/add.go b/cmd/times/add.go index efeca25..2877218 100644 --- a/cmd/times/add.go +++ b/cmd/times/add.go @@ -41,7 +41,7 @@ func runTrackedTimesAdd(_ stdctx.Context, cmd *cli.Command) error { } if ctx.Args().Len() < 2 { - return fmt.Errorf("No issue or duration specified.\nUsage:\t%s", ctx.Command.UsageText) + return fmt.Errorf("no issue or duration specified.\nUsage:\t%s", ctx.Command.UsageText) } issue, err := utils.ArgToIndex(ctx.Args().First()) diff --git a/cmd/times/delete.go b/cmd/times/delete.go index b1101b9..cbb9284 100644 --- a/cmd/times/delete.go +++ b/cmd/times/delete.go @@ -36,7 +36,7 @@ func runTrackedTimesDelete(_ stdctx.Context, cmd *cli.Command) error { client := ctx.Login.Client() if ctx.Args().Len() < 2 { - return fmt.Errorf("No issue or time ID specified.\nUsage:\t%s", ctx.Command.UsageText) + return fmt.Errorf("no issue or time ID specified.\nUsage:\t%s", ctx.Command.UsageText) } issue, err := utils.ArgToIndex(ctx.Args().First()) diff --git a/cmd/times/reset.go b/cmd/times/reset.go index c2dd1b3..08f8f93 100644 --- a/cmd/times/reset.go +++ b/cmd/times/reset.go @@ -35,7 +35,7 @@ func runTrackedTimesReset(_ stdctx.Context, cmd *cli.Command) error { client := ctx.Login.Client() if ctx.Args().Len() != 1 { - return fmt.Errorf("No issue specified.\nUsage:\t%s", ctx.Command.UsageText) + return fmt.Errorf("no issue specified.\nUsage:\t%s", ctx.Command.UsageText) } issue, err := utils.ArgToIndex(ctx.Args().First()) diff --git a/modules/auth/oauth.go b/modules/auth/oauth.go index 82f0b43..e1fd47c 100644 --- a/modules/auth/oauth.go +++ b/modules/auth/oauth.go @@ -226,7 +226,6 @@ func startLocalServerAndOpenBrowser(authURL, expectedState string, opts OAuthOpt codeChan := make(chan string, 1) stateChan := make(chan string, 1) errChan := make(chan error, 1) - portChan := make(chan int, 1) // Parse the redirect URL to get the path parsedURL, err := url.Parse(opts.RedirectURL) @@ -311,7 +310,6 @@ func startLocalServerAndOpenBrowser(authURL, expectedState string, opts OAuthOpt if port == 0 { addr := listener.Addr().(*net.TCPAddr) port = addr.Port - portChan <- port // Update redirect URL with actual port parsedURL.Host = fmt.Sprintf("%s:%d", hostname, port) diff --git a/modules/config/config.go b/modules/config/config.go index 247c3a9..18a2241 100644 --- a/modules/config/config.go +++ b/modules/config/config.go @@ -5,7 +5,6 @@ package config import ( "fmt" - "log" "os" "path/filepath" "sync" @@ -74,7 +73,8 @@ func GetConfigPath() string { } if err != nil { - log.Fatal("unable to get or create config file") + fmt.Fprintln(os.Stderr, "unable to get or create config file") + os.Exit(1) } return configFilePath diff --git a/modules/config/login.go b/modules/config/login.go index 0e83892..9a7849d 100644 --- a/modules/config/login.go +++ b/modules/config/login.go @@ -8,7 +8,6 @@ import ( "crypto/tls" "errors" "fmt" - "log" "net/http" "net/http/cookiejar" "net/url" @@ -132,7 +131,7 @@ func GetDefaultLogin() (*Login, error) { } if len(config.Logins) == 0 { - return nil, errors.New("No available login") + return nil, errors.New("no available login") } for _, l := range config.Logins { if l.Default { @@ -178,50 +177,51 @@ func GetLoginByName(name string) (*Login, error) { } // GetLoginByToken get login by token -func GetLoginByToken(token string) *Login { +func GetLoginByToken(token string) (*Login, error) { if token == "" { - return nil + return nil, nil } - err := loadConfig() - if err != nil { - log.Fatal(err) + if err := loadConfig(); err != nil { + return nil, err } for _, l := range config.Logins { if l.Token == token { - return &l + return &l, nil } } - return nil + return nil, nil } -// GetLoginByHost finds a login by it's server URL -func GetLoginByHost(host string) *Login { - logins := GetLoginsByHost(host) - if len(logins) > 0 { - return logins[0] +// GetLoginByHost finds a login by its server URL +func GetLoginByHost(host string) (*Login, error) { + logins, err := GetLoginsByHost(host) + if err != nil { + return nil, err } - return nil + if len(logins) > 0 { + return logins[0], nil + } + return nil, nil } // GetLoginsByHost returns all logins matching a host -func GetLoginsByHost(host string) []*Login { - err := loadConfig() - if err != nil { - log.Fatal(err) +func GetLoginsByHost(host string) ([]*Login, error) { + if err := loadConfig(); err != nil { + return nil, err } var matches []*Login for i := range config.Logins { loginURL, err := url.Parse(config.Logins[i].URL) if err != nil { - log.Fatal(err) + return nil, err } if loginURL.Host == host { matches = append(matches, &config.Logins[i]) } } - return matches + return matches, nil } // DeleteLogin delete a login by name from config @@ -417,12 +417,13 @@ func doOAuthRefresh(l *Login) (*oauth2.Token, error) { func (l *Login) Client(options ...gitea.ClientOption) *gitea.Client { // Refresh OAuth token if expired or near expiry if err := l.RefreshOAuthTokenIfNeeded(); err != nil { - log.Fatalf("Failed to refresh token: %s\nPlease use 'tea login oauth-refresh %s' to manually refresh the token.\n", err, l.Name) + fmt.Fprintf(os.Stderr, "Failed to refresh token: %s\nPlease use 'tea login oauth-refresh %s' to manually refresh the token.\n", err, l.Name) + os.Exit(1) } httpClient := &http.Client{} if l.Insecure { - cookieJar, _ := cookiejar.New(nil) + cookieJar, _ := cookiejar.New(nil) // New with nil options never returns an error httpClient = &http.Client{ Jar: cookieJar, @@ -443,12 +444,18 @@ func (l *Login) Client(options ...gitea.ClientOption) *gitea.Client { } if l.SSHCertPrincipal != "" { - l.askForSSHPassphrase() + if err := l.askForSSHPassphrase(); err != nil { + fmt.Fprintf(os.Stderr, "Failed to read SSH passphrase: %s\n", err) + os.Exit(1) + } options = append(options, gitea.UseSSHCert(l.SSHCertPrincipal, l.SSHKey, l.SSHPassphrase)) } if l.SSHKeyFingerprint != "" { - l.askForSSHPassphrase() + if err := l.askForSSHPassphrase(); err != nil { + fmt.Fprintf(os.Stderr, "Failed to read SSH passphrase: %s\n", err) + os.Exit(1) + } options = append(options, gitea.UseSSHPubkey(l.SSHKeyFingerprint, l.SSHKey, l.SSHPassphrase)) } @@ -456,25 +463,25 @@ func (l *Login) Client(options ...gitea.ClientOption) *gitea.Client { if err != nil { var versionError *gitea.ErrUnknownVersion if !errors.As(err, &versionError) { - log.Fatal(err) + fmt.Fprintf(os.Stderr, "Failed to create Gitea client: %s\n", err) + os.Exit(1) } fmt.Fprintf(os.Stderr, "WARNING: could not detect gitea version: %s\nINFO: set gitea version: to last supported one\n", versionError) } return client } -func (l *Login) askForSSHPassphrase() { +func (l *Login) askForSSHPassphrase() error { if ok, err := utils.IsKeyEncrypted(l.SSHKey); ok && err == nil && l.SSHPassphrase == "" { - if err := huh.NewInput(). + return huh.NewInput(). Title("ssh-key is encrypted please enter the passphrase: "). Validate(huh.ValidateNotEmpty()). EchoMode(huh.EchoModePassword). Value(&l.SSHPassphrase). WithTheme(theme.GetTheme()). - Run(); err != nil { - log.Fatal(err) - } + Run() } + return nil } // GetSSHHost returns SSH host name diff --git a/modules/context/context.go b/modules/context/context.go index b692036..0fe55b3 100644 --- a/modules/context/context.go +++ b/modules/context/context.go @@ -20,7 +20,7 @@ import ( "golang.org/x/term" ) -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") // ErrCommandCanceled is returned when the user explicitly cancels an interactive prompt. var ErrCommandCanceled = errors.New("command canceled") diff --git a/modules/git/branch.go b/modules/git/branch.go index 7963c2e..6c709ad 100644 --- a/modules/git/branch.go +++ b/modules/git/branch.go @@ -80,7 +80,7 @@ func (r TeaRepo) TeaFindBranchBySha(sha, repoURL string) (b *git_config.Branch, return nil, err } if remote == nil { - return nil, fmt.Errorf("No remote found for '%s'", repoURL) + return nil, fmt.Errorf("no remote found for '%s'", repoURL) } remoteName := remote.Config().Name @@ -133,7 +133,7 @@ func (r TeaRepo) TeaFindBranchByName(branchName, repoURL string) (b *git_config. return nil, err } if remote == nil { - return nil, fmt.Errorf("No remote found for '%s'", repoURL) + return nil, fmt.Errorf("no remote found for '%s'", repoURL) } remoteName := remote.Config().Name diff --git a/modules/interact/login.go b/modules/interact/login.go index 2b0abab..a6aef27 100644 --- a/modules/interact/login.go +++ b/modules/interact/login.go @@ -41,7 +41,7 @@ func CreateLogin() error { } _, err := url.Parse(s) if err != nil { - return fmt.Errorf("Invalid URL: %v", err) + return fmt.Errorf("invalid URL: %v", err) } return nil }). @@ -69,7 +69,7 @@ func CreateLogin() error { } for _, login := range logins { if login.Name == name { - return fmt.Errorf("Login with name '%s' already exists", name) + return fmt.Errorf("login with name '%s' already exists", name) } } return nil @@ -154,7 +154,7 @@ func CreateLogin() error { Value(&tokenScopes). Validate(func(s []string) error { if len(s) == 0 { - return errors.New("At least one scope is required") + return errors.New("at least one scope is required") } return nil }). diff --git a/modules/interact/pull_merge.go b/modules/interact/pull_merge.go index 3191677..f3d9973 100644 --- a/modules/interact/pull_merge.go +++ b/modules/interact/pull_merge.go @@ -58,7 +58,7 @@ func getPullIndex(ctx *context.TeaContext, branch string) (int64, error) { return 0, err } if len(prs) == 0 { - return 0, fmt.Errorf("No open PRs found") + return 0, fmt.Errorf("no open PRs found") } opts.ListOptions.Page++ prOptions := make([]string, 0) diff --git a/modules/print/table.go b/modules/print/table.go index 7f9ca04..41dd43f 100644 --- a/modules/print/table.go +++ b/modules/print/table.go @@ -150,8 +150,7 @@ func outputYaml(f io.Writer, headers []string, values [][]string) error { }) valueNode := &yaml.Node{Kind: yaml.ScalarNode, Value: val} - intVal, _ := strconv.Atoi(val) - if strconv.Itoa(intVal) == val { + if _, err := strconv.ParseInt(val, 10, 64); err == nil { valueNode.Tag = "!!int" } else { valueNode.Tag = "!!str" diff --git a/modules/task/issue_create.go b/modules/task/issue_create.go index 25f843f..f1ccf3b 100644 --- a/modules/task/issue_create.go +++ b/modules/task/issue_create.go @@ -15,7 +15,7 @@ import ( func CreateIssue(login *config.Login, repoOwner, repoName string, opts gitea.CreateIssueOption) error { // title is required if len(opts.Title) == 0 { - return fmt.Errorf("Title is required") + return fmt.Errorf("title is required") } issue, _, err := login.Client().CreateIssue(repoOwner, repoName, opts) diff --git a/modules/task/login_create.go b/modules/task/login_create.go index 0759809..ac45c46 100644 --- a/modules/task/login_create.go +++ b/modules/task/login_create.go @@ -20,12 +20,13 @@ import ( func SetupHelper(login config.Login) (ok bool, err error) { // Check that the URL is not blank if login.URL == "" { - return false, fmt.Errorf("Invalid gitea url") + return false, fmt.Errorf("invalid Gitea URL") } // get all helper to URL in git config + helperKey := fmt.Sprintf("credential.%s.helper", login.URL) var currentHelpers []byte - if currentHelpers, err = exec.Command("git", "config", "--global", "--get-all", fmt.Sprintf("credential.%s.helper", login.URL)).Output(); err != nil { + if currentHelpers, err = exec.Command("git", "config", "--global", "--get-all", helperKey).Output(); err != nil { currentHelpers = []byte{} } @@ -37,10 +38,10 @@ func SetupHelper(login config.Login) (ok bool, err error) { } // Add tea helper - if _, err = exec.Command("git", "config", "--global", fmt.Sprintf("credential.%s.helper", login.URL), "").Output(); err != nil { - return false, fmt.Errorf("git config --global %s, error: %s", fmt.Sprintf("credential.%s.helper", login.URL), err) - } else if _, err = exec.Command("git", "config", "--global", "--add", fmt.Sprintf("credential.%s.helper", login.URL), "!tea login helper").Output(); err != nil { - return false, fmt.Errorf("git config --global --add %s %s, error: %s", fmt.Sprintf("credential.%s.helper", login.URL), "!tea login helper", err) + if _, err = exec.Command("git", "config", "--global", helperKey, "").Output(); err != nil { + return false, fmt.Errorf("git config --global %s, error: %s", helperKey, err) + } else if _, err = exec.Command("git", "config", "--global", "--add", helperKey, "!tea login helper").Output(); err != nil { + return false, fmt.Errorf("git config --global --add %s %s, error: %s", helperKey, "!tea login helper", err) } return true, nil @@ -62,7 +63,11 @@ func CreateLogin(name, token, user, passwd, otp, scopes, sshKey, giteaURL, sshCe } // ... if we already use this token if shouldCheckTokenUniqueness(token, sshAgent, sshKey, sshCertPrincipal, sshKeyFingerprint) { - if login := config.GetLoginByToken(token); login != nil { + login, err := config.GetLoginByToken(token) + if err != nil { + return err + } + if login != nil { return fmt.Errorf("token already been used, delete login '%s' first", login.Name) } } diff --git a/modules/task/milestone_create.go b/modules/task/milestone_create.go index bbde1df..d6ee093 100644 --- a/modules/task/milestone_create.go +++ b/modules/task/milestone_create.go @@ -17,7 +17,7 @@ import ( func CreateMilestone(login *config.Login, repoOwner, repoName, title, description string, deadline *time.Time, state gitea.StateType) error { // title is required if len(title) == 0 { - return fmt.Errorf("Title is required") + return fmt.Errorf("title is required") } mile, _, err := login.Client().CreateMilestone(repoOwner, repoName, gitea.CreateMilestoneOption{ diff --git a/modules/task/pull_clean.go b/modules/task/pull_clean.go index 0f1ad82..5b3512b 100644 --- a/modules/task/pull_clean.go +++ b/modules/task/pull_clean.go @@ -39,7 +39,7 @@ func PullClean(login *config.Login, repoOwner, repoName string, index int64, ign // if remote head branch is already deleted, pr.Head.Ref points to "pulls//head" remoteBranch := pr.Head.Ref - remoteDeleted := remoteBranch == fmt.Sprintf("refs/pull/%d/head", pr.Index) + remoteDeleted := isRemoteDeleted(pr) if remoteDeleted { remoteBranch = pr.Head.Name // this still holds the original branch name fmt.Printf("Remote branch '%s' already deleted.\n", remoteBranch) @@ -62,9 +62,9 @@ func PullClean(login *config.Login, repoOwner, repoName string, index int64, ign } if branch == nil { if ignoreSHA { - return fmt.Errorf("Remote branch %s not found in local repo", remoteBranch) + return fmt.Errorf("remote branch %s not found in local repo", remoteBranch) } - return fmt.Errorf(`Remote branch %s not found in local repo. + return fmt.Errorf(`remote branch %s not found in local repo. Either you don't track this PR, or the local branch has diverged from the remote. If you still want to continue & are sure you don't loose any important commits, call me again with the --ignore-sha flag`, remoteBranch) diff --git a/modules/task/pull_merge.go b/modules/task/pull_merge.go index 8a2018a..1e28a58 100644 --- a/modules/task/pull_merge.go +++ b/modules/task/pull_merge.go @@ -18,7 +18,7 @@ func PullMerge(login *config.Login, repoOwner, repoName string, index int64, opt return err } if !success { - return fmt.Errorf("Failed to merge PR. Is it still open?") + return fmt.Errorf("failed to merge PR, is it still open?") } return nil } diff --git a/modules/utils/path.go b/modules/utils/path.go index 16621aa..aac9ded 100644 --- a/modules/utils/path.go +++ b/modules/utils/path.go @@ -9,6 +9,7 @@ import ( "os/user" "path/filepath" "strings" + "syscall" ) // PathExists returns whether the given file or directory exists or not @@ -38,18 +39,19 @@ func exists(path string, expectDir bool) (bool, error) { if err != nil { if errors.Is(err, os.ErrNotExist) { return false, nil - } else if err.(*os.PathError).Err.Error() == "not a directory" { - // some middle segment of path is a file, cannot traverse - // FIXME: catches error on linux; go does not provide a way to catch this properly.. + } + var pathErr *os.PathError + if errors.As(err, &pathErr) && errors.Is(pathErr.Err, syscall.ENOTDIR) { + // a middle segment of path is a file, cannot traverse return false, nil } return false, err } isDir := f.IsDir() if isDir && !expectDir { - return false, errors.New("A directory with the same name exists") + return false, errors.New("a directory with the same name exists") } else if !isDir && expectDir { - return false, errors.New("A file with the same name exists") + return false, errors.New("a file with the same name exists") } return true, nil } diff --git a/modules/utils/validate.go b/modules/utils/validate.go index 9924c2f..8f16931 100644 --- a/modules/utils/validate.go +++ b/modules/utils/validate.go @@ -21,17 +21,17 @@ func ValidateAuthenticationMethod( // Normalize URL serverURL, err := NormalizeURL(giteaURL) if err != nil { - return nil, fmt.Errorf("Unable to parse URL: %s", err) + return nil, fmt.Errorf("unable to parse URL: %s", err) } if !sshAgent && sshCertPrincipal == "" && sshKey == "" { // .. if we have enough information to authenticate if len(token) == 0 && (len(user)+len(passwd)) == 0 { - return nil, fmt.Errorf("No token set") + return nil, fmt.Errorf("no token set") } else if len(user) != 0 && len(passwd) == 0 { - return nil, fmt.Errorf("No password set") + return nil, fmt.Errorf("no password set") } else if len(user) == 0 && len(passwd) != 0 { - return nil, fmt.Errorf("No user set") + return nil, fmt.Errorf("no user set") } } return serverURL, nil