From b7cfa4e67e253bc9626ca72f36cffd014842d6b6 Mon Sep 17 00:00:00 2001 From: wxiaoguang Date: Fri, 28 Aug 2026 00:34:44 +0800 Subject: [PATCH] chore: apply golangci "forbidigo" to all packages (#39151) --- .golangci.yml | 3 --- cmd/actions.go | 3 +-- cmd/admin_user_change_password.go | 2 +- cmd/admin_user_create.go | 6 +++--- cmd/admin_user_disable_2fa.go | 2 +- cmd/admin_user_generate_access_token.go | 4 ++-- cmd/admin_user_must_change_password.go | 3 +-- cmd/doctor.go | 4 ++-- cmd/doctor_convert.go | 7 +++---- cmd/embedded.go | 16 ++++++++-------- cmd/generate.go | 16 ++++++++-------- cmd/helper.go | 14 ++++++++++---- cmd/mailer.go | 7 +++---- cmd/serv.go | 19 ++++++++++++------- routers/web/misc/misc.go | 3 ++- services/agit/agit.go | 2 ++ tests/integration/ssh_key_test.go | 4 ++-- 17 files changed, 61 insertions(+), 54 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 42cdfa70a02..22ea9b9d2b6 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -146,9 +146,6 @@ linters: - linters: - dupl path: modelmigration/v - - linters: - - forbidigo - path: cmd - linters: - dupl text: (?i)webhook diff --git a/cmd/actions.go b/cmd/actions.go index 576be764881..1a1ad281ce8 100644 --- a/cmd/actions.go +++ b/cmd/actions.go @@ -5,7 +5,6 @@ package cmd import ( "context" - "fmt" "gitea.dev/modules/private" "gitea.dev/modules/setting" @@ -49,6 +48,6 @@ func runGenerateActionsRunnerToken(ctx context.Context, c *cli.Command) error { if extra.HasError() { return handleCliResponseExtra(extra) } - _, _ = fmt.Printf("%s\n", respText.Text) + cprintln(c, respText.Text) return nil } diff --git a/cmd/admin_user_change_password.go b/cmd/admin_user_change_password.go index 4d5fe586e1d..46e0588e340 100644 --- a/cmd/admin_user_change_password.go +++ b/cmd/admin_user_change_password.go @@ -73,6 +73,6 @@ func runChangePassword(ctx context.Context, c *cli.Command) error { } } - fmt.Printf("%s's password has been successfully updated!\n", user.Name) + cprintf(c, "%s's password has been successfully updated!\n", user.Name) return nil } diff --git a/cmd/admin_user_create.go b/cmd/admin_user_create.go index 81b6f87a31c..2db926d27af 100644 --- a/cmd/admin_user_create.go +++ b/cmd/admin_user_create.go @@ -152,7 +152,7 @@ func runCreateUser(ctx context.Context, c *cli.Command) error { return err } // codeql[disable-next-line=go/clear-text-logging] - fmt.Printf("generated random password is '%s'\n", password) + cprintf(c, "generated random password is '%s'\n", password) } else if userType == user_model.UserTypeIndividual { return errors.New("must set either password or random-password flag") } @@ -228,7 +228,7 @@ func runCreateUser(ctx context.Context, c *cli.Command) error { if err := user_model.CreateUser(ctx, u, &user_model.Meta{}, overwriteDefault); err != nil { return fmt.Errorf("CreateUser: %w", err) } - fmt.Printf("New user '%s' has been successfully created!\n", username) + cprintf(c, "New user '%s' has been successfully created!\n", username) // create the access token if accessTokenScope != "" { @@ -236,7 +236,7 @@ func runCreateUser(ctx context.Context, c *cli.Command) error { if err := auth_model.NewAccessToken(ctx, t); err != nil { return err } - fmt.Printf("Access token was successfully created... %s\n", t.Token) + cprintf(c, "Access token was successfully created... %s\n", t.Token) } return nil } diff --git a/cmd/admin_user_disable_2fa.go b/cmd/admin_user_disable_2fa.go index 1e8502cf04c..b5b59e59a0f 100644 --- a/cmd/admin_user_disable_2fa.go +++ b/cmd/admin_user_disable_2fa.go @@ -67,6 +67,6 @@ func runDisableTwoFactor(ctx context.Context, c *cli.Command) error { return err } - fmt.Printf("Disabled 2FA for user %q (removed %d TOTP and %d WebAuthn credential(s))\n", user.Name, totp, webAuthn) + cprintf(c, "Disabled 2FA for user %q (removed %d TOTP and %d WebAuthn credential(s))\n", user.Name, totp, webAuthn) return nil } diff --git a/cmd/admin_user_generate_access_token.go b/cmd/admin_user_generate_access_token.go index cf42a97cddb..e1b0e9837c4 100644 --- a/cmd/admin_user_generate_access_token.go +++ b/cmd/admin_user_generate_access_token.go @@ -88,9 +88,9 @@ func runGenerateAccessToken(ctx context.Context, c *cli.Command) error { } if c.Bool("raw") { - fmt.Printf("%s\n", t.Token) + cprintln(c, t.Token) } else { - fmt.Printf("Access token was successfully created: %s\n", t.Token) + cprintf(c, "Access token was successfully created: %s\n", t.Token) } return nil diff --git a/cmd/admin_user_must_change_password.go b/cmd/admin_user_must_change_password.go index ff318dd0bce..185b9e610ba 100644 --- a/cmd/admin_user_must_change_password.go +++ b/cmd/admin_user_must_change_password.go @@ -6,7 +6,6 @@ package cmd import ( "context" "errors" - "fmt" user_model "gitea.dev/models/user" "gitea.dev/modules/setting" @@ -59,6 +58,6 @@ func runMustChangePassword(ctx context.Context, c *cli.Command) error { } // codeql[disable-next-line=go/clear-text-logging] - fmt.Printf("Updated %d users setting MustChangePassword to %t\n", n, mustChangePassword) + cprintf(c, "Updated %d users setting MustChangePassword to %t\n", n, mustChangePassword) return nil } diff --git a/cmd/doctor.go b/cmd/doctor.go index 40edaca566d..7c55c2d070d 100644 --- a/cmd/doctor.go +++ b/cmd/doctor.go @@ -114,8 +114,8 @@ func runRecreateTable(ctx context.Context, cmd *cli.Command) error { setting.Database.LogSQL = debug if err := db.InitEngine(ctx); err != nil { - fmt.Println(err) - fmt.Println("Check if you are using the right config file. You can use a --config directive to specify one.") + cprintln(cmd, err) + cprintln(cmd, "Check if you are using the right config file. You can use a --config directive to specify one.") return nil } diff --git a/cmd/doctor_convert.go b/cmd/doctor_convert.go index eceda00183b..e7123702d56 100644 --- a/cmd/doctor_convert.go +++ b/cmd/doctor_convert.go @@ -5,7 +5,6 @@ package cmd import ( "context" - "fmt" "gitea.dev/models/db" "gitea.dev/modules/log" @@ -40,15 +39,15 @@ func runDoctorConvert(ctx context.Context, cmd *cli.Command) error { log.Fatal("Failed to convert database & table: %v", err) return err } - fmt.Println("Converted successfully, please confirm your database's character set is now utf8mb4") + cprintln(cmd, "Converted successfully, please confirm your database's character set is now utf8mb4") case setting.Database.Type.IsMSSQL(): if err := db.ConvertVarcharToNVarchar(); err != nil { log.Fatal("Failed to convert database from varchar to nvarchar: %v", err) return err } - fmt.Println("Converted successfully, please confirm your database's all columns character is NVARCHAR now") + cprintln(cmd, "Converted successfully, please confirm your database's all columns character is NVARCHAR now") default: - fmt.Println("This command can only be used with a MySQL or MSSQL database") + cprintln(cmd, "This command can only be used with a MySQL or MSSQL database") } return nil diff --git a/cmd/embedded.go b/cmd/embedded.go index 2107071df61..56d7e4cb364 100644 --- a/cmd/embedded.go +++ b/cmd/embedded.go @@ -150,7 +150,7 @@ func runListDo(c *cli.Command) error { } for _, a := range matchedAssetFiles { - fmt.Println(a.path) + cprintln(c, a.path) } return nil @@ -194,7 +194,7 @@ func runExtractDo(c *cli.Command) error { destdir = c.String("destination") } else if c.Bool("custom") { destdir = setting.CustomPath - fmt.Println("Using app.ini at", setting.CustomConf) + cprintln(c, "Using app.ini at", setting.CustomConf) } fi, err := os.Stat(destdir) @@ -213,13 +213,13 @@ func runExtractDo(c *cli.Command) error { return fmt.Errorf("destination %q is not a directory", destdir) } - fmt.Printf("Extracting to %s:\n", destdir) + cprintf(c, "Extracting to %s:\n", destdir) overwrite := c.Bool("overwrite") rename := c.Bool("rename") for _, a := range matchedAssetFiles { - if err := extractAsset(destdir, a, overwrite, rename); err != nil { + if err := extractAsset(c, destdir, a, overwrite, rename); err != nil { // Non-fatal error _, _ = fmt.Fprintf(os.Stderr, "%s: %v\n", a.path, err) } @@ -228,7 +228,7 @@ func runExtractDo(c *cli.Command) error { return nil } -func extractAsset(d string, a assetFile, overwrite, rename bool) error { +func extractAsset(c *cli.Command, d string, a assetFile, overwrite, rename bool) error { dest := filepath.Join(d, filepath.FromSlash(a.path)) dir := filepath.Dir(dest) @@ -249,7 +249,7 @@ func extractAsset(d string, a assetFile, overwrite, rename bool) error { return fmt.Errorf("%s: %w", dest, err) } } else if !overwrite && !rename { - fmt.Printf("%s already exists; skipped.\n", dest) + cprintf(c, "%s already exists; skipped.\n", dest) return nil } else if !fi.Mode().IsRegular() { return fmt.Errorf("%s already exists, but it's not a regular file", dest) @@ -271,7 +271,7 @@ func extractAsset(d string, a assetFile, overwrite, rename bool) error { return fmt.Errorf("%s: %w", dest, err) } - fmt.Println(dest) + cprintln(c, dest) return nil } @@ -306,7 +306,7 @@ func compileCollectPatterns(args []string) (_ []glob.Glob, err error) { pat := make([]glob.Glob, len(args)) for i := range args { if pat[i], err = glob.Compile(args[i], '/'); err != nil { - return nil, fmt.Errorf("invalid glob patterh %q: %w", args[i], err) + return nil, fmt.Errorf("invalid glob pattern %q: %w", args[i], err) } } return pat, nil diff --git a/cmd/generate.go b/cmd/generate.go index 239b75ba9c2..122dbbcccdc 100644 --- a/cmd/generate.go +++ b/cmd/generate.go @@ -106,10 +106,10 @@ func runGenerateInternalToken(_ context.Context, c *cli.Command) error { return err } - fmt.Printf("%s", internalToken) + cprintf(c, "%s", internalToken) if isatty.IsTerminal(os.Stdout.Fd()) { - fmt.Printf("\n") + cprintf(c, "\n") } return nil @@ -117,10 +117,10 @@ func runGenerateInternalToken(_ context.Context, c *cli.Command) error { func runGenerateLfsJwtSecret(_ context.Context, c *cli.Command) error { _, jwtSecretBase64 := generate.NewJwtSecretWithBase64() - fmt.Printf("%s", jwtSecretBase64) + cprintf(c, "%s", jwtSecretBase64) if isatty.IsTerminal(os.Stdout.Fd()) { - fmt.Printf("\n") + cprintf(c, "\n") } return nil @@ -133,10 +133,10 @@ func runGenerateSecretKey(_ context.Context, c *cli.Command) error { } // codeql[disable-next-line=go/clear-text-logging] - fmt.Printf("%s", secretKey) + cprintf(c, "%s", secretKey) if isatty.IsTerminal(os.Stdout.Fd()) { - fmt.Printf("\n") + cprintf(c, "\n") } return nil @@ -168,14 +168,14 @@ func runGenerateKeyPair(_ context.Context, c *cli.Command) error { // Check if file exists to prevent overwriting if _, err := os.Stat(file); err == nil { if !confirm(c.Reader, c.Writer, "%s already exists.\nOverwrite (y/n)? ", file) { - fmt.Println("Aborting") + cprintln(c, "Aborting") return nil } } bits := c.Int("bits") err := ssh.GenKeyPair(file, generate.SSHKeyType(keyType), bits) if err == nil { - fmt.Printf("Your SSH key has been saved in %s\n", file) + cprintf(c, "Your SSH key has been saved in %s\n", file) } return err } diff --git a/cmd/helper.go b/cmd/helper.go index 37b20104379..592eda5328e 100644 --- a/cmd/helper.go +++ b/cmd/helper.go @@ -1,8 +1,6 @@ // Copyright 2018 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -// Package cmd provides subcommands to the gitea binary - such as "web" or -// "admin". package cmd import ( @@ -22,8 +20,8 @@ import ( "github.com/urfave/cli/v3" ) -// argsSet checks that all the required arguments are set. args is a list of -// arguments that must be set in the passed Context. +// argsSet checks that all the required arguments are set. +// args is a list of arguments that must be set in the command context. func argsSet(c *cli.Command, args ...string) error { for _, a := range args { if !c.IsSet(a) { @@ -141,3 +139,11 @@ func isValidDefaultSubCommand(cmd *cli.Command) (string, bool) { } return "", true } + +func cprintf(c *cli.Command, format string, args ...any) { + _, _ = fmt.Fprintf(c.Writer, format, args...) +} + +func cprintln(c *cli.Command, args ...any) { + _, _ = fmt.Fprintln(c.Writer, args...) +} diff --git a/cmd/mailer.go b/cmd/mailer.go index d7b2f6b7bb1..d4c94f17fb8 100644 --- a/cmd/mailer.go +++ b/cmd/mailer.go @@ -5,7 +5,6 @@ package cmd import ( "context" - "fmt" "gitea.dev/modules/private" "gitea.dev/modules/setting" @@ -22,11 +21,11 @@ func runSendMail(ctx context.Context, c *cli.Command) error { if !confirmSkipped { if len(body) == 0 { - fmt.Println("warning: Content is empty") + cprintln(c, "warning: Content is empty") } if !confirm(c.Reader, c.Writer, "Proceed with sending email? [Y/n] ") { - fmt.Println("The mail was not sent") + cprintln(c, "The mail was not sent") return nil } } @@ -35,6 +34,6 @@ func runSendMail(ctx context.Context, c *cli.Command) error { if extra.HasError() { return handleCliResponseExtra(extra) } - _, _ = fmt.Printf("Sent %s email(s) to all users\n", respText.Text) + cprintf(c, "Sent %s email(s) to all users\n", respText.Text) return nil } diff --git a/cmd/serv.go b/cmd/serv.go index 1d9ab781268..00118eea483 100644 --- a/cmd/serv.go +++ b/cmd/serv.go @@ -29,6 +29,7 @@ import ( "gitea.dev/modules/process" repo_module "gitea.dev/modules/repository" "gitea.dev/modules/setting" + "gitea.dev/services/agit" "gitea.dev/services/lfs" "github.com/kballard/go-shellquote" @@ -139,13 +140,13 @@ func runServ(ctx context.Context, c *cli.Command) error { setup(ctx, c.Bool("debug")) if setting.SSH.Disabled { - println("Gitea: SSH has been disabled") + cprintln(c, "Gitea: SSH has been disabled") return nil } if c.NArg() < 1 { if err := cli.ShowSubcommandHelp(c); err != nil { - fmt.Printf("error showing subcommand help: %v\n", err) + cprintf(c, "error showing subcommand help: %v\n", err) } return nil } @@ -171,15 +172,19 @@ func runServ(ctx context.Context, c *cli.Command) error { if err != nil { return fail(ctx, "Key check failed", "Failed to check provided key: %v", err) } + var authSuccessMsg string switch key.Type { case asymkey_model.KeyTypeDeploy: - println("Hi there! You've successfully authenticated with the deploy key named " + key.Name + ", but Gitea does not provide shell access.") + authSuccessMsg = "Hi there! You've successfully authenticated with an SSH deploy key." case asymkey_model.KeyTypePrincipal: - println("Hi there! You've successfully authenticated with the principal " + key.Content + ", but Gitea does not provide shell access.") + authSuccessMsg = "Hi there! You've successfully authenticated with the SSH principal " + key.Content + "." default: - println("Hi there, " + user.Name + "! You've successfully authenticated with the key named " + key.Name + ", but Gitea does not provide shell access.") + authSuccessMsg = "Hi there, " + user.Name + "! You've successfully authenticated with the SSH key named " + key.Name + "." } - println("If this is unexpected, please log in with password and setup Gitea under another user.") + _, _ = fmt.Fprintf(c.ErrWriter, "%s\n%s", + authSuccessMsg, + "Gitea does not provide shell access. If this is unexpected, please setup Gitea under another SSH user or use container to deploy.", + ) return nil } else if c.Bool("debug") { log.Debug("SSH_ORIGINAL_COMMAND: %s", os.Getenv("SSH_ORIGINAL_COMMAND")) @@ -194,7 +199,7 @@ func runServ(ctx context.Context, c *cli.Command) error { if git.DefaultFeatures().SupportProcReceive { // for AGit Flow if cmd == "ssh_info" { - fmt.Print(`{"type":"agit","version":1}`) + cprintf(c, "%s", agit.SshInfoJson) return nil } } diff --git a/routers/web/misc/misc.go b/routers/web/misc/misc.go index 0cfd7c0a492..beb01611dad 100644 --- a/routers/web/misc/misc.go +++ b/routers/web/misc/misc.go @@ -17,6 +17,7 @@ import ( "gitea.dev/modules/setting" "gitea.dev/modules/util" "gitea.dev/modules/web/middleware" + "gitea.dev/services/agit" "gitea.dev/services/context" ) @@ -49,7 +50,7 @@ func SSHInfo(rw http.ResponseWriter, req *http.Request) { return } rw.Header().Set("content-type", "text/json;charset=UTF-8") - _, err := rw.Write([]byte(`{"type":"agit","version":1}`)) + _, err := rw.Write([]byte(agit.SshInfoJson)) if err != nil { log.Error("fail to write result: err: %v", err) rw.WriteHeader(http.StatusInternalServerError) diff --git a/services/agit/agit.go b/services/agit/agit.go index 2ed2e3642c9..4bd3bd85023 100644 --- a/services/agit/agit.go +++ b/services/agit/agit.go @@ -24,6 +24,8 @@ import ( pull_service "gitea.dev/services/pull" ) +const SshInfoJson = `{"type":"agit","version":1}` + func parseAgitPushOptionValue(s string) string { if base64Value, ok := strings.CutPrefix(s, "{base64}"); ok { decoded, err := base64.StdEncoding.DecodeString(base64Value) diff --git a/tests/integration/ssh_key_test.go b/tests/integration/ssh_key_test.go index 260bc485c35..55b0aa19bea 100644 --- a/tests/integration/ssh_key_test.go +++ b/tests/integration/ssh_key_test.go @@ -72,10 +72,10 @@ func TestSSHShellWelcome(t *testing.T) { require.NoError(t, err) var stderr bytes.Buffer - session.Stderr = &stderr // "gitea serv" writes the welcome with println, which goes to stderr + session.Stderr = &stderr require.NoError(t, session.Shell()) require.NoError(t, session.Wait()) // fails unless the server reports exit status 0 - assert.Contains(t, stderr.String(), "You've successfully authenticated with the key named welcome-key") + assert.Contains(t, stderr.String(), "You've successfully authenticated with the SSH key named welcome-key.") }) }) }