mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 08:30:25 +08:00 
			
		
		
		
	Refactor to use urfave/cli/v2 (#25959)
Replace #10912 And there are many new tests to cover the CLI behavior There were some concerns about the "option order in hook scripts" (https://github.com/go-gitea/gitea/pull/10912#issuecomment-1137543314), it's not a problem now. Because the hook script uses `/gitea hook --config=/app.ini pre-receive` format. The "config" is a global option, it can appear anywhere. ---- ## ⚠️ BREAKING ⚠️ This PR does it best to avoid breaking anything. The major changes are: * `gitea` itself won't accept web's options: `--install-port` / `--pid` / `--port` / `--quiet` / `--verbose` .... They are `web` sub-command's options. * Use `./gitea web --pid ....` instead * `./gitea` can still run the `web` sub-command as shorthand, with default options * The sub-command's options must follow the sub-command * Before: `./gitea --sub-opt subcmd` might equal to `./gitea subcmd --sub-opt` (well, might not ...) * After: only `./gitea subcmd --sub-opt` could be used * The global options like `--config` are not affected
This commit is contained in:
		
							
								
								
									
										11
									
								
								assets/go-licenses.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										11
									
								
								assets/go-licenses.json
									
									
									
										generated
									
									
									
								
							
										
											
												File diff suppressed because one or more lines are too long
											
										
									
								
							@@ -9,28 +9,29 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/private"
 | 
						"code.gitea.io/gitea/modules/private"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	// CmdActions represents the available actions sub-commands.
 | 
						// CmdActions represents the available actions sub-commands.
 | 
				
			||||||
	CmdActions = cli.Command{
 | 
						CmdActions = &cli.Command{
 | 
				
			||||||
		Name:        "actions",
 | 
							Name:        "actions",
 | 
				
			||||||
		Usage:       "",
 | 
							Usage:       "",
 | 
				
			||||||
		Description: "Commands for managing Gitea Actions",
 | 
							Description: "Commands for managing Gitea Actions",
 | 
				
			||||||
		Subcommands: []cli.Command{
 | 
							Subcommands: []*cli.Command{
 | 
				
			||||||
			subcmdActionsGenRunnerToken,
 | 
								subcmdActionsGenRunnerToken,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	subcmdActionsGenRunnerToken = cli.Command{
 | 
						subcmdActionsGenRunnerToken = &cli.Command{
 | 
				
			||||||
		Name:    "generate-runner-token",
 | 
							Name:    "generate-runner-token",
 | 
				
			||||||
		Usage:   "Generate a new token for a runner to use to register with the server",
 | 
							Usage:   "Generate a new token for a runner to use to register with the server",
 | 
				
			||||||
		Action:  runGenerateActionsRunnerToken,
 | 
							Action:  runGenerateActionsRunnerToken,
 | 
				
			||||||
		Aliases: []string{"grt"},
 | 
							Aliases: []string{"grt"},
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.StringFlag{
 | 
								&cli.StringFlag{
 | 
				
			||||||
				Name:  "scope, s",
 | 
									Name:    "scope",
 | 
				
			||||||
 | 
									Aliases: []string{"s"},
 | 
				
			||||||
				Value:   "",
 | 
									Value:   "",
 | 
				
			||||||
				Usage:   "{owner}[/{repo}] - leave empty for a global runner",
 | 
									Usage:   "{owner}[/{repo}] - leave empty for a global runner",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										131
									
								
								cmd/admin.go
									
									
									
									
									
								
							
							
						
						
									
										131
									
								
								cmd/admin.go
									
									
									
									
									
								
							@@ -26,15 +26,15 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/services/auth/source/smtp"
 | 
						"code.gitea.io/gitea/services/auth/source/smtp"
 | 
				
			||||||
	repo_service "code.gitea.io/gitea/services/repository"
 | 
						repo_service "code.gitea.io/gitea/services/repository"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	// CmdAdmin represents the available admin sub-command.
 | 
						// CmdAdmin represents the available admin sub-command.
 | 
				
			||||||
	CmdAdmin = cli.Command{
 | 
						CmdAdmin = &cli.Command{
 | 
				
			||||||
		Name:  "admin",
 | 
							Name:  "admin",
 | 
				
			||||||
		Usage: "Command line interface to perform common administrative operations",
 | 
							Usage: "Command line interface to perform common administrative operations",
 | 
				
			||||||
		Subcommands: []cli.Command{
 | 
							Subcommands: []*cli.Command{
 | 
				
			||||||
			subcmdUser,
 | 
								subcmdUser,
 | 
				
			||||||
			subcmdRepoSyncReleases,
 | 
								subcmdRepoSyncReleases,
 | 
				
			||||||
			subcmdRegenerate,
 | 
								subcmdRegenerate,
 | 
				
			||||||
@@ -43,37 +43,37 @@ var (
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	subcmdRepoSyncReleases = cli.Command{
 | 
						subcmdRepoSyncReleases = &cli.Command{
 | 
				
			||||||
		Name:   "repo-sync-releases",
 | 
							Name:   "repo-sync-releases",
 | 
				
			||||||
		Usage:  "Synchronize repository releases with tags",
 | 
							Usage:  "Synchronize repository releases with tags",
 | 
				
			||||||
		Action: runRepoSyncReleases,
 | 
							Action: runRepoSyncReleases,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	subcmdRegenerate = cli.Command{
 | 
						subcmdRegenerate = &cli.Command{
 | 
				
			||||||
		Name:  "regenerate",
 | 
							Name:  "regenerate",
 | 
				
			||||||
		Usage: "Regenerate specific files",
 | 
							Usage: "Regenerate specific files",
 | 
				
			||||||
		Subcommands: []cli.Command{
 | 
							Subcommands: []*cli.Command{
 | 
				
			||||||
			microcmdRegenHooks,
 | 
								microcmdRegenHooks,
 | 
				
			||||||
			microcmdRegenKeys,
 | 
								microcmdRegenKeys,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	microcmdRegenHooks = cli.Command{
 | 
						microcmdRegenHooks = &cli.Command{
 | 
				
			||||||
		Name:   "hooks",
 | 
							Name:   "hooks",
 | 
				
			||||||
		Usage:  "Regenerate git-hooks",
 | 
							Usage:  "Regenerate git-hooks",
 | 
				
			||||||
		Action: runRegenerateHooks,
 | 
							Action: runRegenerateHooks,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	microcmdRegenKeys = cli.Command{
 | 
						microcmdRegenKeys = &cli.Command{
 | 
				
			||||||
		Name:   "keys",
 | 
							Name:   "keys",
 | 
				
			||||||
		Usage:  "Regenerate authorized_keys file",
 | 
							Usage:  "Regenerate authorized_keys file",
 | 
				
			||||||
		Action: runRegenerateKeys,
 | 
							Action: runRegenerateKeys,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	subcmdAuth = cli.Command{
 | 
						subcmdAuth = &cli.Command{
 | 
				
			||||||
		Name:  "auth",
 | 
							Name:  "auth",
 | 
				
			||||||
		Usage: "Modify external auth providers",
 | 
							Usage: "Modify external auth providers",
 | 
				
			||||||
		Subcommands: []cli.Command{
 | 
							Subcommands: []*cli.Command{
 | 
				
			||||||
			microcmdAuthAddOauth,
 | 
								microcmdAuthAddOauth,
 | 
				
			||||||
			microcmdAuthUpdateOauth,
 | 
								microcmdAuthUpdateOauth,
 | 
				
			||||||
			cmdAuthAddLdapBindDn,
 | 
								cmdAuthAddLdapBindDn,
 | 
				
			||||||
@@ -87,44 +87,44 @@ var (
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	microcmdAuthList = cli.Command{
 | 
						microcmdAuthList = &cli.Command{
 | 
				
			||||||
		Name:   "list",
 | 
							Name:   "list",
 | 
				
			||||||
		Usage:  "List auth sources",
 | 
							Usage:  "List auth sources",
 | 
				
			||||||
		Action: runListAuth,
 | 
							Action: runListAuth,
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.IntFlag{
 | 
								&cli.IntFlag{
 | 
				
			||||||
				Name:  "min-width",
 | 
									Name:  "min-width",
 | 
				
			||||||
				Usage: "Minimal cell width including any padding for the formatted table",
 | 
									Usage: "Minimal cell width including any padding for the formatted table",
 | 
				
			||||||
				Value: 0,
 | 
									Value: 0,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.IntFlag{
 | 
								&cli.IntFlag{
 | 
				
			||||||
				Name:  "tab-width",
 | 
									Name:  "tab-width",
 | 
				
			||||||
				Usage: "width of tab characters in formatted table (equivalent number of spaces)",
 | 
									Usage: "width of tab characters in formatted table (equivalent number of spaces)",
 | 
				
			||||||
				Value: 8,
 | 
									Value: 8,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.IntFlag{
 | 
								&cli.IntFlag{
 | 
				
			||||||
				Name:  "padding",
 | 
									Name:  "padding",
 | 
				
			||||||
				Usage: "padding added to a cell before computing its width",
 | 
									Usage: "padding added to a cell before computing its width",
 | 
				
			||||||
				Value: 1,
 | 
									Value: 1,
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.StringFlag{
 | 
								&cli.StringFlag{
 | 
				
			||||||
				Name:  "pad-char",
 | 
									Name:  "pad-char",
 | 
				
			||||||
				Usage: `ASCII char used for padding if padchar == '\\t', the Writer will assume that the width of a '\\t' in the formatted output is tabwidth, and cells are left-aligned independent of align_left (for correct-looking results, tabwidth must correspond to the tab width in the viewer displaying the result)`,
 | 
									Usage: `ASCII char used for padding if padchar == '\\t', the Writer will assume that the width of a '\\t' in the formatted output is tabwidth, and cells are left-aligned independent of align_left (for correct-looking results, tabwidth must correspond to the tab width in the viewer displaying the result)`,
 | 
				
			||||||
				Value: "\t",
 | 
									Value: "\t",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name:  "vertical-bars",
 | 
									Name:  "vertical-bars",
 | 
				
			||||||
				Usage: "Set to true to print vertical bars between columns",
 | 
									Usage: "Set to true to print vertical bars between columns",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	idFlag = cli.Int64Flag{
 | 
						idFlag = &cli.Int64Flag{
 | 
				
			||||||
		Name:  "id",
 | 
							Name:  "id",
 | 
				
			||||||
		Usage: "ID of authentication source",
 | 
							Usage: "ID of authentication source",
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	microcmdAuthDelete = cli.Command{
 | 
						microcmdAuthDelete = &cli.Command{
 | 
				
			||||||
		Name:   "delete",
 | 
							Name:   "delete",
 | 
				
			||||||
		Usage:  "Delete specific auth source",
 | 
							Usage:  "Delete specific auth source",
 | 
				
			||||||
		Flags:  []cli.Flag{idFlag},
 | 
							Flags:  []cli.Flag{idFlag},
 | 
				
			||||||
@@ -132,207 +132,208 @@ var (
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	oauthCLIFlags = []cli.Flag{
 | 
						oauthCLIFlags = []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "name",
 | 
								Name:  "name",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Application Name",
 | 
								Usage: "Application Name",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "provider",
 | 
								Name:  "provider",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "OAuth2 Provider",
 | 
								Usage: "OAuth2 Provider",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "key",
 | 
								Name:  "key",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Client ID (Key)",
 | 
								Usage: "Client ID (Key)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "secret",
 | 
								Name:  "secret",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Client Secret",
 | 
								Usage: "Client Secret",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "auto-discover-url",
 | 
								Name:  "auto-discover-url",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "OpenID Connect Auto Discovery URL (only required when using OpenID Connect as provider)",
 | 
								Usage: "OpenID Connect Auto Discovery URL (only required when using OpenID Connect as provider)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "use-custom-urls",
 | 
								Name:  "use-custom-urls",
 | 
				
			||||||
			Value: "false",
 | 
								Value: "false",
 | 
				
			||||||
			Usage: "Use custom URLs for GitLab/GitHub OAuth endpoints",
 | 
								Usage: "Use custom URLs for GitLab/GitHub OAuth endpoints",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "custom-tenant-id",
 | 
								Name:  "custom-tenant-id",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Use custom Tenant ID for OAuth endpoints",
 | 
								Usage: "Use custom Tenant ID for OAuth endpoints",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "custom-auth-url",
 | 
								Name:  "custom-auth-url",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Use a custom Authorization URL (option for GitLab/GitHub)",
 | 
								Usage: "Use a custom Authorization URL (option for GitLab/GitHub)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "custom-token-url",
 | 
								Name:  "custom-token-url",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Use a custom Token URL (option for GitLab/GitHub)",
 | 
								Usage: "Use a custom Token URL (option for GitLab/GitHub)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "custom-profile-url",
 | 
								Name:  "custom-profile-url",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Use a custom Profile URL (option for GitLab/GitHub)",
 | 
								Usage: "Use a custom Profile URL (option for GitLab/GitHub)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "custom-email-url",
 | 
								Name:  "custom-email-url",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Use a custom Email URL (option for GitHub)",
 | 
								Usage: "Use a custom Email URL (option for GitHub)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "icon-url",
 | 
								Name:  "icon-url",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Custom icon URL for OAuth2 login source",
 | 
								Usage: "Custom icon URL for OAuth2 login source",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "skip-local-2fa",
 | 
								Name:  "skip-local-2fa",
 | 
				
			||||||
			Usage: "Set to true to skip local 2fa for users authenticated by this source",
 | 
								Usage: "Set to true to skip local 2fa for users authenticated by this source",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringSliceFlag{
 | 
							&cli.StringSliceFlag{
 | 
				
			||||||
			Name:  "scopes",
 | 
								Name:  "scopes",
 | 
				
			||||||
			Value: nil,
 | 
								Value: nil,
 | 
				
			||||||
			Usage: "Scopes to request when to authenticate against this OAuth2 source",
 | 
								Usage: "Scopes to request when to authenticate against this OAuth2 source",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "required-claim-name",
 | 
								Name:  "required-claim-name",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Claim name that has to be set to allow users to login with this source",
 | 
								Usage: "Claim name that has to be set to allow users to login with this source",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "required-claim-value",
 | 
								Name:  "required-claim-value",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Claim value that has to be set to allow users to login with this source",
 | 
								Usage: "Claim value that has to be set to allow users to login with this source",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "group-claim-name",
 | 
								Name:  "group-claim-name",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Claim name providing group names for this source",
 | 
								Usage: "Claim name providing group names for this source",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "admin-group",
 | 
								Name:  "admin-group",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Group Claim value for administrator users",
 | 
								Usage: "Group Claim value for administrator users",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "restricted-group",
 | 
								Name:  "restricted-group",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Group Claim value for restricted users",
 | 
								Usage: "Group Claim value for restricted users",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "group-team-map",
 | 
								Name:  "group-team-map",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "JSON mapping between groups and org teams",
 | 
								Usage: "JSON mapping between groups and org teams",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "group-team-map-removal",
 | 
								Name:  "group-team-map-removal",
 | 
				
			||||||
			Usage: "Activate automatic team membership removal depending on groups",
 | 
								Usage: "Activate automatic team membership removal depending on groups",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	microcmdAuthUpdateOauth = cli.Command{
 | 
						microcmdAuthUpdateOauth = &cli.Command{
 | 
				
			||||||
		Name:   "update-oauth",
 | 
							Name:   "update-oauth",
 | 
				
			||||||
		Usage:  "Update existing Oauth authentication source",
 | 
							Usage:  "Update existing Oauth authentication source",
 | 
				
			||||||
		Action: runUpdateOauth,
 | 
							Action: runUpdateOauth,
 | 
				
			||||||
		Flags:  append(oauthCLIFlags[:1], append([]cli.Flag{idFlag}, oauthCLIFlags[1:]...)...),
 | 
							Flags:  append(oauthCLIFlags[:1], append([]cli.Flag{idFlag}, oauthCLIFlags[1:]...)...),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	microcmdAuthAddOauth = cli.Command{
 | 
						microcmdAuthAddOauth = &cli.Command{
 | 
				
			||||||
		Name:   "add-oauth",
 | 
							Name:   "add-oauth",
 | 
				
			||||||
		Usage:  "Add new Oauth authentication source",
 | 
							Usage:  "Add new Oauth authentication source",
 | 
				
			||||||
		Action: runAddOauth,
 | 
							Action: runAddOauth,
 | 
				
			||||||
		Flags:  oauthCLIFlags,
 | 
							Flags:  oauthCLIFlags,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	subcmdSendMail = cli.Command{
 | 
						subcmdSendMail = &cli.Command{
 | 
				
			||||||
		Name:   "sendmail",
 | 
							Name:   "sendmail",
 | 
				
			||||||
		Usage:  "Send a message to all users",
 | 
							Usage:  "Send a message to all users",
 | 
				
			||||||
		Action: runSendMail,
 | 
							Action: runSendMail,
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.StringFlag{
 | 
								&cli.StringFlag{
 | 
				
			||||||
				Name:  "title",
 | 
									Name:  "title",
 | 
				
			||||||
				Usage: `a title of a message`,
 | 
									Usage: `a title of a message`,
 | 
				
			||||||
				Value: "",
 | 
									Value: "",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.StringFlag{
 | 
								&cli.StringFlag{
 | 
				
			||||||
				Name:  "content",
 | 
									Name:  "content",
 | 
				
			||||||
				Usage: "a content of a message",
 | 
									Usage: "a content of a message",
 | 
				
			||||||
				Value: "",
 | 
									Value: "",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name:  "force,f",
 | 
									Name:    "force",
 | 
				
			||||||
 | 
									Aliases: []string{"f"},
 | 
				
			||||||
				Usage:   "A flag to bypass a confirmation step",
 | 
									Usage:   "A flag to bypass a confirmation step",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	smtpCLIFlags = []cli.Flag{
 | 
						smtpCLIFlags = []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "name",
 | 
								Name:  "name",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Application Name",
 | 
								Usage: "Application Name",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "auth-type",
 | 
								Name:  "auth-type",
 | 
				
			||||||
			Value: "PLAIN",
 | 
								Value: "PLAIN",
 | 
				
			||||||
			Usage: "SMTP Authentication Type (PLAIN/LOGIN/CRAM-MD5) default PLAIN",
 | 
								Usage: "SMTP Authentication Type (PLAIN/LOGIN/CRAM-MD5) default PLAIN",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "host",
 | 
								Name:  "host",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "SMTP Host",
 | 
								Usage: "SMTP Host",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.IntFlag{
 | 
							&cli.IntFlag{
 | 
				
			||||||
			Name:  "port",
 | 
								Name:  "port",
 | 
				
			||||||
			Usage: "SMTP Port",
 | 
								Usage: "SMTP Port",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolTFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "force-smtps",
 | 
								Name:  "force-smtps",
 | 
				
			||||||
			Usage: "SMTPS is always used on port 465. Set this to force SMTPS on other ports.",
 | 
								Usage: "SMTPS is always used on port 465. Set this to force SMTPS on other ports.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolTFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "skip-verify",
 | 
								Name:  "skip-verify",
 | 
				
			||||||
			Usage: "Skip TLS verify.",
 | 
								Usage: "Skip TLS verify.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "helo-hostname",
 | 
								Name:  "helo-hostname",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Hostname sent with HELO. Leave blank to send current hostname",
 | 
								Usage: "Hostname sent with HELO. Leave blank to send current hostname",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolTFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "disable-helo",
 | 
								Name:  "disable-helo",
 | 
				
			||||||
			Usage: "Disable SMTP helo.",
 | 
								Usage: "Disable SMTP helo.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "allowed-domains",
 | 
								Name:  "allowed-domains",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Leave empty to allow all domains. Separate multiple domains with a comma (',')",
 | 
								Usage: "Leave empty to allow all domains. Separate multiple domains with a comma (',')",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolTFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "skip-local-2fa",
 | 
								Name:  "skip-local-2fa",
 | 
				
			||||||
			Usage: "Skip 2FA to log on.",
 | 
								Usage: "Skip 2FA to log on.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolTFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "active",
 | 
								Name:  "active",
 | 
				
			||||||
			Usage: "This Authentication Source is Activated.",
 | 
								Usage: "This Authentication Source is Activated.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	microcmdAuthAddSMTP = cli.Command{
 | 
						microcmdAuthAddSMTP = &cli.Command{
 | 
				
			||||||
		Name:   "add-smtp",
 | 
							Name:   "add-smtp",
 | 
				
			||||||
		Usage:  "Add new SMTP authentication source",
 | 
							Usage:  "Add new SMTP authentication source",
 | 
				
			||||||
		Action: runAddSMTP,
 | 
							Action: runAddSMTP,
 | 
				
			||||||
		Flags:  smtpCLIFlags,
 | 
							Flags:  smtpCLIFlags,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	microcmdAuthUpdateSMTP = cli.Command{
 | 
						microcmdAuthUpdateSMTP = &cli.Command{
 | 
				
			||||||
		Name:   "update-smtp",
 | 
							Name:   "update-smtp",
 | 
				
			||||||
		Usage:  "Update existing SMTP authentication source",
 | 
							Usage:  "Update existing SMTP authentication source",
 | 
				
			||||||
		Action: runUpdateSMTP,
 | 
							Action: runUpdateSMTP,
 | 
				
			||||||
@@ -611,19 +612,19 @@ func parseSMTPConfig(c *cli.Context, conf *smtp.Source) error {
 | 
				
			|||||||
		conf.AllowedDomains = c.String("allowed-domains")
 | 
							conf.AllowedDomains = c.String("allowed-domains")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if c.IsSet("force-smtps") {
 | 
						if c.IsSet("force-smtps") {
 | 
				
			||||||
		conf.ForceSMTPS = c.BoolT("force-smtps")
 | 
							conf.ForceSMTPS = c.Bool("force-smtps")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if c.IsSet("skip-verify") {
 | 
						if c.IsSet("skip-verify") {
 | 
				
			||||||
		conf.SkipVerify = c.BoolT("skip-verify")
 | 
							conf.SkipVerify = c.Bool("skip-verify")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if c.IsSet("helo-hostname") {
 | 
						if c.IsSet("helo-hostname") {
 | 
				
			||||||
		conf.HeloHostname = c.String("helo-hostname")
 | 
							conf.HeloHostname = c.String("helo-hostname")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if c.IsSet("disable-helo") {
 | 
						if c.IsSet("disable-helo") {
 | 
				
			||||||
		conf.DisableHelo = c.BoolT("disable-helo")
 | 
							conf.DisableHelo = c.Bool("disable-helo")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if c.IsSet("skip-local-2fa") {
 | 
						if c.IsSet("skip-local-2fa") {
 | 
				
			||||||
		conf.SkipLocalTwoFA = c.BoolT("skip-local-2fa")
 | 
							conf.SkipLocalTwoFA = c.Bool("skip-local-2fa")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -647,7 +648,7 @@ func runAddSMTP(c *cli.Context) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	active := true
 | 
						active := true
 | 
				
			||||||
	if c.IsSet("active") {
 | 
						if c.IsSet("active") {
 | 
				
			||||||
		active = c.BoolT("active")
 | 
							active = c.Bool("active")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	var smtpConfig smtp.Source
 | 
						var smtpConfig smtp.Source
 | 
				
			||||||
@@ -696,7 +697,7 @@ func runUpdateSMTP(c *cli.Context) error {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if c.IsSet("active") {
 | 
						if c.IsSet("active") {
 | 
				
			||||||
		source.IsActive = c.BoolT("active")
 | 
							source.IsActive = c.Bool("active")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	source.Cfg = smtpConfig
 | 
						source.Cfg = smtpConfig
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/models/auth"
 | 
						"code.gitea.io/gitea/models/auth"
 | 
				
			||||||
	"code.gitea.io/gitea/services/auth/source/ldap"
 | 
						"code.gitea.io/gitea/services/auth/source/ldap"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type (
 | 
					type (
 | 
				
			||||||
@@ -25,117 +25,117 @@ type (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	commonLdapCLIFlags = []cli.Flag{
 | 
						commonLdapCLIFlags = []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "name",
 | 
								Name:  "name",
 | 
				
			||||||
			Usage: "Authentication name.",
 | 
								Usage: "Authentication name.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "not-active",
 | 
								Name:  "not-active",
 | 
				
			||||||
			Usage: "Deactivate the authentication source.",
 | 
								Usage: "Deactivate the authentication source.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "active",
 | 
								Name:  "active",
 | 
				
			||||||
			Usage: "Activate the authentication source.",
 | 
								Usage: "Activate the authentication source.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "security-protocol",
 | 
								Name:  "security-protocol",
 | 
				
			||||||
			Usage: "Security protocol name.",
 | 
								Usage: "Security protocol name.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "skip-tls-verify",
 | 
								Name:  "skip-tls-verify",
 | 
				
			||||||
			Usage: "Disable TLS verification.",
 | 
								Usage: "Disable TLS verification.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "host",
 | 
								Name:  "host",
 | 
				
			||||||
			Usage: "The address where the LDAP server can be reached.",
 | 
								Usage: "The address where the LDAP server can be reached.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.IntFlag{
 | 
							&cli.IntFlag{
 | 
				
			||||||
			Name:  "port",
 | 
								Name:  "port",
 | 
				
			||||||
			Usage: "The port to use when connecting to the LDAP server.",
 | 
								Usage: "The port to use when connecting to the LDAP server.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "user-search-base",
 | 
								Name:  "user-search-base",
 | 
				
			||||||
			Usage: "The LDAP base at which user accounts will be searched for.",
 | 
								Usage: "The LDAP base at which user accounts will be searched for.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "user-filter",
 | 
								Name:  "user-filter",
 | 
				
			||||||
			Usage: "An LDAP filter declaring how to find the user record that is attempting to authenticate.",
 | 
								Usage: "An LDAP filter declaring how to find the user record that is attempting to authenticate.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "admin-filter",
 | 
								Name:  "admin-filter",
 | 
				
			||||||
			Usage: "An LDAP filter specifying if a user should be given administrator privileges.",
 | 
								Usage: "An LDAP filter specifying if a user should be given administrator privileges.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "restricted-filter",
 | 
								Name:  "restricted-filter",
 | 
				
			||||||
			Usage: "An LDAP filter specifying if a user should be given restricted status.",
 | 
								Usage: "An LDAP filter specifying if a user should be given restricted status.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "allow-deactivate-all",
 | 
								Name:  "allow-deactivate-all",
 | 
				
			||||||
			Usage: "Allow empty search results to deactivate all users.",
 | 
								Usage: "Allow empty search results to deactivate all users.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "username-attribute",
 | 
								Name:  "username-attribute",
 | 
				
			||||||
			Usage: "The attribute of the user’s LDAP record containing the user name.",
 | 
								Usage: "The attribute of the user’s LDAP record containing the user name.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "firstname-attribute",
 | 
								Name:  "firstname-attribute",
 | 
				
			||||||
			Usage: "The attribute of the user’s LDAP record containing the user’s first name.",
 | 
								Usage: "The attribute of the user’s LDAP record containing the user’s first name.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "surname-attribute",
 | 
								Name:  "surname-attribute",
 | 
				
			||||||
			Usage: "The attribute of the user’s LDAP record containing the user’s surname.",
 | 
								Usage: "The attribute of the user’s LDAP record containing the user’s surname.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "email-attribute",
 | 
								Name:  "email-attribute",
 | 
				
			||||||
			Usage: "The attribute of the user’s LDAP record containing the user’s email address.",
 | 
								Usage: "The attribute of the user’s LDAP record containing the user’s email address.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "public-ssh-key-attribute",
 | 
								Name:  "public-ssh-key-attribute",
 | 
				
			||||||
			Usage: "The attribute of the user’s LDAP record containing the user’s public ssh key.",
 | 
								Usage: "The attribute of the user’s LDAP record containing the user’s public ssh key.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "skip-local-2fa",
 | 
								Name:  "skip-local-2fa",
 | 
				
			||||||
			Usage: "Set to true to skip local 2fa for users authenticated by this source",
 | 
								Usage: "Set to true to skip local 2fa for users authenticated by this source",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "avatar-attribute",
 | 
								Name:  "avatar-attribute",
 | 
				
			||||||
			Usage: "The attribute of the user’s LDAP record containing the user’s avatar.",
 | 
								Usage: "The attribute of the user’s LDAP record containing the user’s avatar.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ldapBindDnCLIFlags = append(commonLdapCLIFlags,
 | 
						ldapBindDnCLIFlags = append(commonLdapCLIFlags,
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "bind-dn",
 | 
								Name:  "bind-dn",
 | 
				
			||||||
			Usage: "The DN to bind to the LDAP server with when searching for the user.",
 | 
								Usage: "The DN to bind to the LDAP server with when searching for the user.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "bind-password",
 | 
								Name:  "bind-password",
 | 
				
			||||||
			Usage: "The password for the Bind DN, if any.",
 | 
								Usage: "The password for the Bind DN, if any.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "attributes-in-bind",
 | 
								Name:  "attributes-in-bind",
 | 
				
			||||||
			Usage: "Fetch attributes in bind DN context.",
 | 
								Usage: "Fetch attributes in bind DN context.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "synchronize-users",
 | 
								Name:  "synchronize-users",
 | 
				
			||||||
			Usage: "Enable user synchronization.",
 | 
								Usage: "Enable user synchronization.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "disable-synchronize-users",
 | 
								Name:  "disable-synchronize-users",
 | 
				
			||||||
			Usage: "Disable user synchronization.",
 | 
								Usage: "Disable user synchronization.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.UintFlag{
 | 
							&cli.UintFlag{
 | 
				
			||||||
			Name:  "page-size",
 | 
								Name:  "page-size",
 | 
				
			||||||
			Usage: "Search page size.",
 | 
								Usage: "Search page size.",
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	ldapSimpleAuthCLIFlags = append(commonLdapCLIFlags,
 | 
						ldapSimpleAuthCLIFlags = append(commonLdapCLIFlags,
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "user-dn",
 | 
								Name:  "user-dn",
 | 
				
			||||||
			Usage: "The user’s DN.",
 | 
								Usage: "The user’s DN.",
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmdAuthAddLdapBindDn = cli.Command{
 | 
						cmdAuthAddLdapBindDn = &cli.Command{
 | 
				
			||||||
		Name:  "add-ldap",
 | 
							Name:  "add-ldap",
 | 
				
			||||||
		Usage: "Add new LDAP (via Bind DN) authentication source",
 | 
							Usage: "Add new LDAP (via Bind DN) authentication source",
 | 
				
			||||||
		Action: func(c *cli.Context) error {
 | 
							Action: func(c *cli.Context) error {
 | 
				
			||||||
@@ -144,7 +144,7 @@ var (
 | 
				
			|||||||
		Flags: ldapBindDnCLIFlags,
 | 
							Flags: ldapBindDnCLIFlags,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmdAuthUpdateLdapBindDn = cli.Command{
 | 
						cmdAuthUpdateLdapBindDn = &cli.Command{
 | 
				
			||||||
		Name:  "update-ldap",
 | 
							Name:  "update-ldap",
 | 
				
			||||||
		Usage: "Update existing LDAP (via Bind DN) authentication source",
 | 
							Usage: "Update existing LDAP (via Bind DN) authentication source",
 | 
				
			||||||
		Action: func(c *cli.Context) error {
 | 
							Action: func(c *cli.Context) error {
 | 
				
			||||||
@@ -153,7 +153,7 @@ var (
 | 
				
			|||||||
		Flags: append([]cli.Flag{idFlag}, ldapBindDnCLIFlags...),
 | 
							Flags: append([]cli.Flag{idFlag}, ldapBindDnCLIFlags...),
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmdAuthAddLdapSimpleAuth = cli.Command{
 | 
						cmdAuthAddLdapSimpleAuth = &cli.Command{
 | 
				
			||||||
		Name:  "add-ldap-simple",
 | 
							Name:  "add-ldap-simple",
 | 
				
			||||||
		Usage: "Add new LDAP (simple auth) authentication source",
 | 
							Usage: "Add new LDAP (simple auth) authentication source",
 | 
				
			||||||
		Action: func(c *cli.Context) error {
 | 
							Action: func(c *cli.Context) error {
 | 
				
			||||||
@@ -162,7 +162,7 @@ var (
 | 
				
			|||||||
		Flags: ldapSimpleAuthCLIFlags,
 | 
							Flags: ldapSimpleAuthCLIFlags,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmdAuthUpdateLdapSimpleAuth = cli.Command{
 | 
						cmdAuthUpdateLdapSimpleAuth = &cli.Command{
 | 
				
			||||||
		Name:  "update-ldap-simple",
 | 
							Name:  "update-ldap-simple",
 | 
				
			||||||
		Usage: "Update existing LDAP (simple auth) authentication source",
 | 
							Usage: "Update existing LDAP (simple auth) authentication source",
 | 
				
			||||||
		Action: func(c *cli.Context) error {
 | 
							Action: func(c *cli.Context) error {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,7 +11,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/services/auth/source/ldap"
 | 
						"code.gitea.io/gitea/services/auth/source/ldap"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/stretchr/testify/assert"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestAddLdapBindDn(t *testing.T) {
 | 
					func TestAddLdapBindDn(t *testing.T) {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -4,13 +4,13 @@
 | 
				
			|||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var subcmdUser = cli.Command{
 | 
					var subcmdUser = &cli.Command{
 | 
				
			||||||
	Name:  "user",
 | 
						Name:  "user",
 | 
				
			||||||
	Usage: "Modify users",
 | 
						Usage: "Modify users",
 | 
				
			||||||
	Subcommands: []cli.Command{
 | 
						Subcommands: []*cli.Command{
 | 
				
			||||||
		microcmdUserCreate,
 | 
							microcmdUserCreate,
 | 
				
			||||||
		microcmdUserList,
 | 
							microcmdUserList,
 | 
				
			||||||
		microcmdUserChangePassword,
 | 
							microcmdUserChangePassword,
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,21 +12,23 @@ import (
 | 
				
			|||||||
	pwd "code.gitea.io/gitea/modules/auth/password"
 | 
						pwd "code.gitea.io/gitea/modules/auth/password"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var microcmdUserChangePassword = cli.Command{
 | 
					var microcmdUserChangePassword = &cli.Command{
 | 
				
			||||||
	Name:   "change-password",
 | 
						Name:   "change-password",
 | 
				
			||||||
	Usage:  "Change a user's password",
 | 
						Usage:  "Change a user's password",
 | 
				
			||||||
	Action: runChangePassword,
 | 
						Action: runChangePassword,
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "username,u",
 | 
								Name:    "username",
 | 
				
			||||||
 | 
								Aliases: []string{"u"},
 | 
				
			||||||
			Value:   "",
 | 
								Value:   "",
 | 
				
			||||||
			Usage:   "The user to change password for",
 | 
								Usage:   "The user to change password for",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "password,p",
 | 
								Name:    "password",
 | 
				
			||||||
 | 
								Aliases: []string{"p"},
 | 
				
			||||||
			Value:   "",
 | 
								Value:   "",
 | 
				
			||||||
			Usage:   "New password to set for user",
 | 
								Usage:   "New password to set for user",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -14,52 +14,52 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var microcmdUserCreate = cli.Command{
 | 
					var microcmdUserCreate = &cli.Command{
 | 
				
			||||||
	Name:   "create",
 | 
						Name:   "create",
 | 
				
			||||||
	Usage:  "Create a new user in database",
 | 
						Usage:  "Create a new user in database",
 | 
				
			||||||
	Action: runCreateUser,
 | 
						Action: runCreateUser,
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "name",
 | 
								Name:  "name",
 | 
				
			||||||
			Usage: "Username. DEPRECATED: use username instead",
 | 
								Usage: "Username. DEPRECATED: use username instead",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "username",
 | 
								Name:  "username",
 | 
				
			||||||
			Usage: "Username",
 | 
								Usage: "Username",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "password",
 | 
								Name:  "password",
 | 
				
			||||||
			Usage: "User password",
 | 
								Usage: "User password",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "email",
 | 
								Name:  "email",
 | 
				
			||||||
			Usage: "User email address",
 | 
								Usage: "User email address",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "admin",
 | 
								Name:  "admin",
 | 
				
			||||||
			Usage: "User is an admin",
 | 
								Usage: "User is an admin",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "random-password",
 | 
								Name:  "random-password",
 | 
				
			||||||
			Usage: "Generate a random password for the user",
 | 
								Usage: "Generate a random password for the user",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "must-change-password",
 | 
								Name:  "must-change-password",
 | 
				
			||||||
			Usage: "Set this option to false to prevent forcing the user to change their password after initial login, (Default: true)",
 | 
								Usage: "Set this option to false to prevent forcing the user to change their password after initial login, (Default: true)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.IntFlag{
 | 
							&cli.IntFlag{
 | 
				
			||||||
			Name:  "random-password-length",
 | 
								Name:  "random-password-length",
 | 
				
			||||||
			Usage: "Length of the random password to be generated",
 | 
								Usage: "Length of the random password to be generated",
 | 
				
			||||||
			Value: 12,
 | 
								Value: 12,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "access-token",
 | 
								Name:  "access-token",
 | 
				
			||||||
			Usage: "Generate access token for the user",
 | 
								Usage: "Generate access token for the user",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "restricted",
 | 
								Name:  "restricted",
 | 
				
			||||||
			Usage: "Make a restricted user account",
 | 
								Usage: "Make a restricted user account",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,26 +11,28 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/storage"
 | 
						"code.gitea.io/gitea/modules/storage"
 | 
				
			||||||
	user_service "code.gitea.io/gitea/services/user"
 | 
						user_service "code.gitea.io/gitea/services/user"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var microcmdUserDelete = cli.Command{
 | 
					var microcmdUserDelete = &cli.Command{
 | 
				
			||||||
	Name:  "delete",
 | 
						Name:  "delete",
 | 
				
			||||||
	Usage: "Delete specific user by id, name or email",
 | 
						Usage: "Delete specific user by id, name or email",
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.Int64Flag{
 | 
							&cli.Int64Flag{
 | 
				
			||||||
			Name:  "id",
 | 
								Name:  "id",
 | 
				
			||||||
			Usage: "ID of user of the user to delete",
 | 
								Usage: "ID of user of the user to delete",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "username,u",
 | 
								Name:    "username",
 | 
				
			||||||
 | 
								Aliases: []string{"u"},
 | 
				
			||||||
			Usage:   "Username of the user to delete",
 | 
								Usage:   "Username of the user to delete",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "email,e",
 | 
								Name:    "email",
 | 
				
			||||||
 | 
								Aliases: []string{"e"},
 | 
				
			||||||
			Usage:   "Email of the user to delete",
 | 
								Usage:   "Email of the user to delete",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "purge",
 | 
								Name:  "purge",
 | 
				
			||||||
			Usage: "Purge user, all their repositories, organizations and comments",
 | 
								Usage: "Purge user, all their repositories, organizations and comments",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,27 +9,29 @@ import (
 | 
				
			|||||||
	auth_model "code.gitea.io/gitea/models/auth"
 | 
						auth_model "code.gitea.io/gitea/models/auth"
 | 
				
			||||||
	user_model "code.gitea.io/gitea/models/user"
 | 
						user_model "code.gitea.io/gitea/models/user"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var microcmdUserGenerateAccessToken = cli.Command{
 | 
					var microcmdUserGenerateAccessToken = &cli.Command{
 | 
				
			||||||
	Name:  "generate-access-token",
 | 
						Name:  "generate-access-token",
 | 
				
			||||||
	Usage: "Generate an access token for a specific user",
 | 
						Usage: "Generate an access token for a specific user",
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "username,u",
 | 
								Name:    "username",
 | 
				
			||||||
 | 
								Aliases: []string{"u"},
 | 
				
			||||||
			Usage:   "Username",
 | 
								Usage:   "Username",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "token-name,t",
 | 
								Name:    "token-name",
 | 
				
			||||||
 | 
								Aliases: []string{"t"},
 | 
				
			||||||
			Usage:   "Token name",
 | 
								Usage:   "Token name",
 | 
				
			||||||
			Value:   "gitea-admin",
 | 
								Value:   "gitea-admin",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "raw",
 | 
								Name:  "raw",
 | 
				
			||||||
			Usage: "Display only the token value",
 | 
								Usage: "Display only the token value",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "scopes",
 | 
								Name:  "scopes",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Comma separated list of scopes to apply to access token",
 | 
								Usage: "Comma separated list of scopes to apply to access token",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,15 +10,15 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	user_model "code.gitea.io/gitea/models/user"
 | 
						user_model "code.gitea.io/gitea/models/user"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var microcmdUserList = cli.Command{
 | 
					var microcmdUserList = &cli.Command{
 | 
				
			||||||
	Name:   "list",
 | 
						Name:   "list",
 | 
				
			||||||
	Usage:  "List users",
 | 
						Usage:  "List users",
 | 
				
			||||||
	Action: runListUsers,
 | 
						Action: runListUsers,
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "admin",
 | 
								Name:  "admin",
 | 
				
			||||||
			Usage: "List only admin users",
 | 
								Usage: "List only admin users",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,23 +9,25 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	user_model "code.gitea.io/gitea/models/user"
 | 
						user_model "code.gitea.io/gitea/models/user"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var microcmdUserMustChangePassword = cli.Command{
 | 
					var microcmdUserMustChangePassword = &cli.Command{
 | 
				
			||||||
	Name:   "must-change-password",
 | 
						Name:   "must-change-password",
 | 
				
			||||||
	Usage:  "Set the must change password flag for the provided users or all users",
 | 
						Usage:  "Set the must change password flag for the provided users or all users",
 | 
				
			||||||
	Action: runMustChangePassword,
 | 
						Action: runMustChangePassword,
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "all,A",
 | 
								Name:    "all",
 | 
				
			||||||
 | 
								Aliases: []string{"A"},
 | 
				
			||||||
			Usage:   "All users must change password, except those explicitly excluded with --exclude",
 | 
								Usage:   "All users must change password, except those explicitly excluded with --exclude",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringSliceFlag{
 | 
							&cli.StringSliceFlag{
 | 
				
			||||||
			Name:  "exclude,e",
 | 
								Name:    "exclude",
 | 
				
			||||||
 | 
								Aliases: []string{"e"},
 | 
				
			||||||
			Usage:   "Do not change the must-change-password flag for these users",
 | 
								Usage:   "Do not change the must-change-password flag for these users",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "unset",
 | 
								Name:  "unset",
 | 
				
			||||||
			Usage: "Instead of setting the must-change-password flag, unset it",
 | 
								Usage: "Instead of setting the must-change-password flag, unset it",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -48,7 +50,7 @@ func runMustChangePassword(c *cli.Context) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	n, err := user_model.SetMustChangePassword(ctx, all, mustChangePassword, c.Args(), exclude)
 | 
						n, err := user_model.SetMustChangePassword(ctx, all, mustChangePassword, c.Args().Slice(), exclude)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										16
									
								
								cmd/cert.go
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								cmd/cert.go
									
									
									
									
									
								
							@@ -20,43 +20,43 @@ import (
 | 
				
			|||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CmdCert represents the available cert sub-command.
 | 
					// CmdCert represents the available cert sub-command.
 | 
				
			||||||
var CmdCert = cli.Command{
 | 
					var CmdCert = &cli.Command{
 | 
				
			||||||
	Name:  "cert",
 | 
						Name:  "cert",
 | 
				
			||||||
	Usage: "Generate self-signed certificate",
 | 
						Usage: "Generate self-signed certificate",
 | 
				
			||||||
	Description: `Generate a self-signed X.509 certificate for a TLS server.
 | 
						Description: `Generate a self-signed X.509 certificate for a TLS server.
 | 
				
			||||||
Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
 | 
					Outputs to 'cert.pem' and 'key.pem' and will overwrite existing files.`,
 | 
				
			||||||
	Action: runCert,
 | 
						Action: runCert,
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "host",
 | 
								Name:  "host",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Comma-separated hostnames and IPs to generate a certificate for",
 | 
								Usage: "Comma-separated hostnames and IPs to generate a certificate for",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "ecdsa-curve",
 | 
								Name:  "ecdsa-curve",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521",
 | 
								Usage: "ECDSA curve to use to generate a key. Valid values are P224, P256, P384, P521",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.IntFlag{
 | 
							&cli.IntFlag{
 | 
				
			||||||
			Name:  "rsa-bits",
 | 
								Name:  "rsa-bits",
 | 
				
			||||||
			Value: 2048,
 | 
								Value: 2048,
 | 
				
			||||||
			Usage: "Size of RSA key to generate. Ignored if --ecdsa-curve is set",
 | 
								Usage: "Size of RSA key to generate. Ignored if --ecdsa-curve is set",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "start-date",
 | 
								Name:  "start-date",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Creation date formatted as Jan 1 15:04:05 2011",
 | 
								Usage: "Creation date formatted as Jan 1 15:04:05 2011",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.DurationFlag{
 | 
							&cli.DurationFlag{
 | 
				
			||||||
			Name:  "duration",
 | 
								Name:  "duration",
 | 
				
			||||||
			Value: 365 * 24 * time.Hour,
 | 
								Value: 365 * 24 * time.Hour,
 | 
				
			||||||
			Usage: "Duration that certificate is valid for",
 | 
								Usage: "Duration that certificate is valid for",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "ca",
 | 
								Name:  "ca",
 | 
				
			||||||
			Usage: "whether this cert should be its own Certificate Authority",
 | 
								Usage: "whether this cert should be its own Certificate Authority",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										15
									
								
								cmd/cmd.go
									
									
									
									
									
								
							
							
						
						
									
										15
									
								
								cmd/cmd.go
									
									
									
									
									
								
							@@ -20,7 +20,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// argsSet checks that all the required arguments are set. args is a list of
 | 
					// argsSet checks that all the required arguments are set. args is a list of
 | 
				
			||||||
@@ -109,15 +109,24 @@ func setupConsoleLogger(level log.Level, colorize bool, out io.Writer) {
 | 
				
			|||||||
	log.GetManager().GetLogger(log.DEFAULT).ReplaceAllWriters(writer)
 | 
						log.GetManager().GetLogger(log.DEFAULT).ReplaceAllWriters(writer)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func globalBool(c *cli.Context, name string) bool {
 | 
				
			||||||
 | 
						for _, ctx := range c.Lineage() {
 | 
				
			||||||
 | 
							if ctx.Bool(name) {
 | 
				
			||||||
 | 
								return true
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return false
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PrepareConsoleLoggerLevel by default, use INFO level for console logger, but some sub-commands (for git/ssh protocol) shouldn't output any log to stdout.
 | 
					// PrepareConsoleLoggerLevel by default, use INFO level for console logger, but some sub-commands (for git/ssh protocol) shouldn't output any log to stdout.
 | 
				
			||||||
// Any log appears in git stdout pipe will break the git protocol, eg: client can't push and hangs forever.
 | 
					// Any log appears in git stdout pipe will break the git protocol, eg: client can't push and hangs forever.
 | 
				
			||||||
func PrepareConsoleLoggerLevel(defaultLevel log.Level) func(*cli.Context) error {
 | 
					func PrepareConsoleLoggerLevel(defaultLevel log.Level) func(*cli.Context) error {
 | 
				
			||||||
	return func(c *cli.Context) error {
 | 
						return func(c *cli.Context) error {
 | 
				
			||||||
		level := defaultLevel
 | 
							level := defaultLevel
 | 
				
			||||||
		if c.Bool("quiet") || c.GlobalBoolT("quiet") {
 | 
							if globalBool(c, "quiet") {
 | 
				
			||||||
			level = log.FATAL
 | 
								level = log.FATAL
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if c.Bool("debug") || c.GlobalBool("debug") || c.Bool("verbose") || c.GlobalBool("verbose") {
 | 
							if globalBool(c, "debug") || globalBool(c, "verbose") {
 | 
				
			||||||
			level = log.TRACE
 | 
								level = log.TRACE
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		log.SetConsoleLogger(log.DEFAULT, "console-default", level)
 | 
							log.SetConsoleLogger(log.DEFAULT, "console-default", level)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,11 +10,11 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CmdConvert represents the available convert sub-command.
 | 
					// CmdConvert represents the available convert sub-command.
 | 
				
			||||||
var CmdConvert = cli.Command{
 | 
					var CmdConvert = &cli.Command{
 | 
				
			||||||
	Name:        "convert",
 | 
						Name:        "convert",
 | 
				
			||||||
	Usage:       "Convert the database",
 | 
						Usage:       "Convert the database",
 | 
				
			||||||
	Description: "A command to convert an existing MySQL database from utf8 to utf8mb4 or MSSQL database from varchar to nvarchar",
 | 
						Description: "A command to convert an existing MySQL database from utf8 to utf8mb4 or MSSQL database from varchar to nvarchar",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -8,11 +8,11 @@ import (
 | 
				
			|||||||
	"os"
 | 
						"os"
 | 
				
			||||||
	"strings"
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CmdDocs represents the available docs sub-command.
 | 
					// CmdDocs represents the available docs sub-command.
 | 
				
			||||||
var CmdDocs = cli.Command{
 | 
					var CmdDocs = &cli.Command{
 | 
				
			||||||
	Name:        "docs",
 | 
						Name:        "docs",
 | 
				
			||||||
	Usage:       "Output CLI documentation",
 | 
						Usage:       "Output CLI documentation",
 | 
				
			||||||
	Description: "A command to output Gitea's CLI documentation, optionally to a file.",
 | 
						Description: "A command to output Gitea's CLI documentation, optionally to a file.",
 | 
				
			||||||
@@ -23,7 +23,8 @@ var CmdDocs = cli.Command{
 | 
				
			|||||||
			Usage: "Output man pages instead",
 | 
								Usage: "Output man pages instead",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		&cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "output, o",
 | 
								Name:    "output",
 | 
				
			||||||
 | 
								Aliases: []string{"o"},
 | 
				
			||||||
			Usage:   "Path to output to instead of stdout (will overwrite if exists)",
 | 
								Usage:   "Path to output to instead of stdout (will overwrite if exists)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,57 +18,58 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
	"xorm.io/xorm"
 | 
						"xorm.io/xorm"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CmdDoctor represents the available doctor sub-command.
 | 
					// CmdDoctor represents the available doctor sub-command.
 | 
				
			||||||
var CmdDoctor = cli.Command{
 | 
					var CmdDoctor = &cli.Command{
 | 
				
			||||||
	Name:        "doctor",
 | 
						Name:        "doctor",
 | 
				
			||||||
	Usage:       "Diagnose and optionally fix problems",
 | 
						Usage:       "Diagnose and optionally fix problems",
 | 
				
			||||||
	Description: "A command to diagnose problems with the current Gitea instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.",
 | 
						Description: "A command to diagnose problems with the current Gitea instance according to the given configuration. Some problems can optionally be fixed by modifying the database or data storage.",
 | 
				
			||||||
	Action:      runDoctor,
 | 
						Action:      runDoctor,
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "list",
 | 
								Name:  "list",
 | 
				
			||||||
			Usage: "List the available checks",
 | 
								Usage: "List the available checks",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "default",
 | 
								Name:  "default",
 | 
				
			||||||
			Usage: "Run the default checks (if neither --run or --all is set, this is the default behaviour)",
 | 
								Usage: "Run the default checks (if neither --run or --all is set, this is the default behaviour)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringSliceFlag{
 | 
							&cli.StringSliceFlag{
 | 
				
			||||||
			Name:  "run",
 | 
								Name:  "run",
 | 
				
			||||||
			Usage: "Run the provided checks - (if --default is set, the default checks will also run)",
 | 
								Usage: "Run the provided checks - (if --default is set, the default checks will also run)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "all",
 | 
								Name:  "all",
 | 
				
			||||||
			Usage: "Run all the available checks",
 | 
								Usage: "Run all the available checks",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "fix",
 | 
								Name:  "fix",
 | 
				
			||||||
			Usage: "Automatically fix what we can",
 | 
								Usage: "Automatically fix what we can",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "log-file",
 | 
								Name:  "log-file",
 | 
				
			||||||
			Usage: `Name of the log file (default: "doctor.log"). Set to "-" to output to stdout, set to "" to disable`,
 | 
								Usage: `Name of the log file (default: "doctor.log"). Set to "-" to output to stdout, set to "" to disable`,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "color, H",
 | 
								Name:    "color",
 | 
				
			||||||
 | 
								Aliases: []string{"H"},
 | 
				
			||||||
			Usage:   "Use color for outputted information",
 | 
								Usage:   "Use color for outputted information",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
	Subcommands: []cli.Command{
 | 
						Subcommands: []*cli.Command{
 | 
				
			||||||
		cmdRecreateTable,
 | 
							cmdRecreateTable,
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var cmdRecreateTable = cli.Command{
 | 
					var cmdRecreateTable = &cli.Command{
 | 
				
			||||||
	Name:      "recreate-table",
 | 
						Name:      "recreate-table",
 | 
				
			||||||
	Usage:     "Recreate tables from XORM definitions and copy the data.",
 | 
						Usage:     "Recreate tables from XORM definitions and copy the data.",
 | 
				
			||||||
	ArgsUsage: "[TABLE]... : (TABLEs to recreate - leave blank for all)",
 | 
						ArgsUsage: "[TABLE]... : (TABLEs to recreate - leave blank for all)",
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "debug",
 | 
								Name:  "debug",
 | 
				
			||||||
			Usage: "Print SQL commands sent",
 | 
								Usage: "Print SQL commands sent",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										51
									
								
								cmd/dump.go
									
									
									
									
									
								
							
							
						
						
									
										51
									
								
								cmd/dump.go
									
									
									
									
									
								
							@@ -22,7 +22,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"gitea.com/go-chi/session"
 | 
						"gitea.com/go-chi/session"
 | 
				
			||||||
	"github.com/mholt/archiver/v3"
 | 
						"github.com/mholt/archiver/v3"
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func addReader(w archiver.Writer, r io.ReadCloser, info os.FileInfo, customName string, verbose bool) error {
 | 
					func addReader(w archiver.Writer, r io.ReadCloser, info os.FileInfo, customName string, verbose bool) error {
 | 
				
			||||||
@@ -96,64 +96,71 @@ var outputTypeEnum = &outputType{
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CmdDump represents the available dump sub-command.
 | 
					// CmdDump represents the available dump sub-command.
 | 
				
			||||||
var CmdDump = cli.Command{
 | 
					var CmdDump = &cli.Command{
 | 
				
			||||||
	Name:  "dump",
 | 
						Name:  "dump",
 | 
				
			||||||
	Usage: "Dump Gitea files and database",
 | 
						Usage: "Dump Gitea files and database",
 | 
				
			||||||
	Description: `Dump compresses all related files and database into zip file.
 | 
						Description: `Dump compresses all related files and database into zip file.
 | 
				
			||||||
It can be used for backup and capture Gitea server image to send to maintainer`,
 | 
					It can be used for backup and capture Gitea server image to send to maintainer`,
 | 
				
			||||||
	Action: runDump,
 | 
						Action: runDump,
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "file, f",
 | 
								Name:    "file",
 | 
				
			||||||
 | 
								Aliases: []string{"f"},
 | 
				
			||||||
			Value:   fmt.Sprintf("gitea-dump-%d.zip", time.Now().Unix()),
 | 
								Value:   fmt.Sprintf("gitea-dump-%d.zip", time.Now().Unix()),
 | 
				
			||||||
			Usage:   "Name of the dump file which will be created. Supply '-' for stdout. See type for available types.",
 | 
								Usage:   "Name of the dump file which will be created. Supply '-' for stdout. See type for available types.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "verbose, V",
 | 
								Name:    "verbose",
 | 
				
			||||||
 | 
								Aliases: []string{"V"},
 | 
				
			||||||
			Usage:   "Show process details",
 | 
								Usage:   "Show process details",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "quiet, q",
 | 
								Name:    "quiet",
 | 
				
			||||||
 | 
								Aliases: []string{"q"},
 | 
				
			||||||
			Usage:   "Only display warnings and errors",
 | 
								Usage:   "Only display warnings and errors",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "tempdir, t",
 | 
								Name:    "tempdir",
 | 
				
			||||||
 | 
								Aliases: []string{"t"},
 | 
				
			||||||
			Value:   os.TempDir(),
 | 
								Value:   os.TempDir(),
 | 
				
			||||||
			Usage:   "Temporary dir path",
 | 
								Usage:   "Temporary dir path",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "database, d",
 | 
								Name:    "database",
 | 
				
			||||||
 | 
								Aliases: []string{"d"},
 | 
				
			||||||
			Usage:   "Specify the database SQL syntax",
 | 
								Usage:   "Specify the database SQL syntax",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "skip-repository, R",
 | 
								Name:    "skip-repository",
 | 
				
			||||||
 | 
								Aliases: []string{"R"},
 | 
				
			||||||
			Usage:   "Skip the repository dumping",
 | 
								Usage:   "Skip the repository dumping",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "skip-log, L",
 | 
								Name:    "skip-log",
 | 
				
			||||||
 | 
								Aliases: []string{"L"},
 | 
				
			||||||
			Usage:   "Skip the log dumping",
 | 
								Usage:   "Skip the log dumping",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "skip-custom-dir",
 | 
								Name:  "skip-custom-dir",
 | 
				
			||||||
			Usage: "Skip custom directory",
 | 
								Usage: "Skip custom directory",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "skip-lfs-data",
 | 
								Name:  "skip-lfs-data",
 | 
				
			||||||
			Usage: "Skip LFS data",
 | 
								Usage: "Skip LFS data",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "skip-attachment-data",
 | 
								Name:  "skip-attachment-data",
 | 
				
			||||||
			Usage: "Skip attachment data",
 | 
								Usage: "Skip attachment data",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "skip-package-data",
 | 
								Name:  "skip-package-data",
 | 
				
			||||||
			Usage: "Skip package data",
 | 
								Usage: "Skip package data",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "skip-index",
 | 
								Name:  "skip-index",
 | 
				
			||||||
			Usage: "Skip bleve index data",
 | 
								Usage: "Skip bleve index data",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.GenericFlag{
 | 
							&cli.GenericFlag{
 | 
				
			||||||
			Name:  "type",
 | 
								Name:  "type",
 | 
				
			||||||
			Value: outputTypeEnum,
 | 
								Value: outputTypeEnum,
 | 
				
			||||||
			Usage: fmt.Sprintf("Dump output format: %s", outputTypeEnum.Join()),
 | 
								Usage: fmt.Sprintf("Dump output format: %s", outputTypeEnum.Join()),
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,57 +19,58 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/services/convert"
 | 
						"code.gitea.io/gitea/services/convert"
 | 
				
			||||||
	"code.gitea.io/gitea/services/migrations"
 | 
						"code.gitea.io/gitea/services/migrations"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CmdDumpRepository represents the available dump repository sub-command.
 | 
					// CmdDumpRepository represents the available dump repository sub-command.
 | 
				
			||||||
var CmdDumpRepository = cli.Command{
 | 
					var CmdDumpRepository = &cli.Command{
 | 
				
			||||||
	Name:        "dump-repo",
 | 
						Name:        "dump-repo",
 | 
				
			||||||
	Usage:       "Dump the repository from git/github/gitea/gitlab",
 | 
						Usage:       "Dump the repository from git/github/gitea/gitlab",
 | 
				
			||||||
	Description: "This is a command for dumping the repository data.",
 | 
						Description: "This is a command for dumping the repository data.",
 | 
				
			||||||
	Action:      runDumpRepository,
 | 
						Action:      runDumpRepository,
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "git_service",
 | 
								Name:  "git_service",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Git service, git, github, gitea, gitlab. If clone_addr could be recognized, this could be ignored.",
 | 
								Usage: "Git service, git, github, gitea, gitlab. If clone_addr could be recognized, this could be ignored.",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "repo_dir, r",
 | 
								Name:    "repo_dir",
 | 
				
			||||||
 | 
								Aliases: []string{"r"},
 | 
				
			||||||
			Value:   "./data",
 | 
								Value:   "./data",
 | 
				
			||||||
			Usage:   "Repository dir path to store the data",
 | 
								Usage:   "Repository dir path to store the data",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "clone_addr",
 | 
								Name:  "clone_addr",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "The URL will be clone, currently could be a git/github/gitea/gitlab http/https URL",
 | 
								Usage: "The URL will be clone, currently could be a git/github/gitea/gitlab http/https URL",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "auth_username",
 | 
								Name:  "auth_username",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "The username to visit the clone_addr",
 | 
								Usage: "The username to visit the clone_addr",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "auth_password",
 | 
								Name:  "auth_password",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "The password to visit the clone_addr",
 | 
								Usage: "The password to visit the clone_addr",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "auth_token",
 | 
								Name:  "auth_token",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "The personal token to visit the clone_addr",
 | 
								Usage: "The personal token to visit the clone_addr",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "owner_name",
 | 
								Name:  "owner_name",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "The data will be stored on a directory with owner name if not empty",
 | 
								Usage: "The data will be stored on a directory with owner name if not empty",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "repo_name",
 | 
								Name:  "repo_name",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "The data will be stored on a directory with repository name if not empty",
 | 
								Usage: "The data will be stored on a directory with repository name if not empty",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "units",
 | 
								Name:  "units",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: `Which items will be migrated, one or more units should be separated as comma.
 | 
								Usage: `Which items will be migrated, one or more units should be separated as comma.
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -19,69 +19,73 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/gobwas/glob"
 | 
						"github.com/gobwas/glob"
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CmdEmbedded represents the available extract sub-command.
 | 
					// CmdEmbedded represents the available extract sub-command.
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	CmdEmbedded = cli.Command{
 | 
						CmdEmbedded = &cli.Command{
 | 
				
			||||||
		Name:        "embedded",
 | 
							Name:        "embedded",
 | 
				
			||||||
		Usage:       "Extract embedded resources",
 | 
							Usage:       "Extract embedded resources",
 | 
				
			||||||
		Description: "A command for extracting embedded resources, like templates and images",
 | 
							Description: "A command for extracting embedded resources, like templates and images",
 | 
				
			||||||
		Subcommands: []cli.Command{
 | 
							Subcommands: []*cli.Command{
 | 
				
			||||||
			subcmdList,
 | 
								subcmdList,
 | 
				
			||||||
			subcmdView,
 | 
								subcmdView,
 | 
				
			||||||
			subcmdExtract,
 | 
								subcmdExtract,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	subcmdList = cli.Command{
 | 
						subcmdList = &cli.Command{
 | 
				
			||||||
		Name:   "list",
 | 
							Name:   "list",
 | 
				
			||||||
		Usage:  "List files matching the given pattern",
 | 
							Usage:  "List files matching the given pattern",
 | 
				
			||||||
		Action: runList,
 | 
							Action: runList,
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name:  "include-vendored,vendor",
 | 
									Name:    "include-vendored",
 | 
				
			||||||
 | 
									Aliases: []string{"vendor"},
 | 
				
			||||||
				Usage:   "Include files under public/vendor as well",
 | 
									Usage:   "Include files under public/vendor as well",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	subcmdView = cli.Command{
 | 
						subcmdView = &cli.Command{
 | 
				
			||||||
		Name:   "view",
 | 
							Name:   "view",
 | 
				
			||||||
		Usage:  "View a file matching the given pattern",
 | 
							Usage:  "View a file matching the given pattern",
 | 
				
			||||||
		Action: runView,
 | 
							Action: runView,
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name:  "include-vendored,vendor",
 | 
									Name:    "include-vendored",
 | 
				
			||||||
 | 
									Aliases: []string{"vendor"},
 | 
				
			||||||
				Usage:   "Include files under public/vendor as well",
 | 
									Usage:   "Include files under public/vendor as well",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	subcmdExtract = cli.Command{
 | 
						subcmdExtract = &cli.Command{
 | 
				
			||||||
		Name:   "extract",
 | 
							Name:   "extract",
 | 
				
			||||||
		Usage:  "Extract resources",
 | 
							Usage:  "Extract resources",
 | 
				
			||||||
		Action: runExtract,
 | 
							Action: runExtract,
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name:  "include-vendored,vendor",
 | 
									Name:    "include-vendored",
 | 
				
			||||||
 | 
									Aliases: []string{"vendor"},
 | 
				
			||||||
				Usage:   "Include files under public/vendor as well",
 | 
									Usage:   "Include files under public/vendor as well",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name:  "overwrite",
 | 
									Name:  "overwrite",
 | 
				
			||||||
				Usage: "Overwrite files if they already exist",
 | 
									Usage: "Overwrite files if they already exist",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name:  "rename",
 | 
									Name:  "rename",
 | 
				
			||||||
				Usage: "Rename files as {name}.bak if they already exist (overwrites previous .bak)",
 | 
									Usage: "Rename files as {name}.bak if they already exist (overwrites previous .bak)",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name:  "custom",
 | 
									Name:  "custom",
 | 
				
			||||||
				Usage: "Extract to the 'custom' directory as per app.ini",
 | 
									Usage: "Extract to the 'custom' directory as per app.ini",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.StringFlag{
 | 
								&cli.StringFlag{
 | 
				
			||||||
				Name:  "destination,dest-dir",
 | 
									Name:    "destination",
 | 
				
			||||||
 | 
									Aliases: []string{"dest-dir"},
 | 
				
			||||||
				Usage:   "Extract to the specified directory",
 | 
									Usage:   "Extract to the specified directory",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -99,7 +103,7 @@ type assetFile struct {
 | 
				
			|||||||
func initEmbeddedExtractor(c *cli.Context) error {
 | 
					func initEmbeddedExtractor(c *cli.Context) error {
 | 
				
			||||||
	setupConsoleLogger(log.ERROR, log.CanColorStderr, os.Stderr)
 | 
						setupConsoleLogger(log.ERROR, log.CanColorStderr, os.Stderr)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	patterns, err := compileCollectPatterns(c.Args())
 | 
						patterns, err := compileCollectPatterns(c.Args().Slice())
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@@ -175,7 +179,7 @@ func runExtractDo(c *cli.Context) error {
 | 
				
			|||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(c.Args()) == 0 {
 | 
						if c.NArg() == 0 {
 | 
				
			||||||
		return fmt.Errorf("a list of pattern of files to extract is mandatory (e.g. '**' for all)")
 | 
							return fmt.Errorf("a list of pattern of files to extract is mandatory (e.g. '**' for all)")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,43 +11,43 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/generate"
 | 
						"code.gitea.io/gitea/modules/generate"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/mattn/go-isatty"
 | 
						"github.com/mattn/go-isatty"
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	// CmdGenerate represents the available generate sub-command.
 | 
						// CmdGenerate represents the available generate sub-command.
 | 
				
			||||||
	CmdGenerate = cli.Command{
 | 
						CmdGenerate = &cli.Command{
 | 
				
			||||||
		Name:  "generate",
 | 
							Name:  "generate",
 | 
				
			||||||
		Usage: "Command line interface for running generators",
 | 
							Usage: "Command line interface for running generators",
 | 
				
			||||||
		Subcommands: []cli.Command{
 | 
							Subcommands: []*cli.Command{
 | 
				
			||||||
			subcmdSecret,
 | 
								subcmdSecret,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	subcmdSecret = cli.Command{
 | 
						subcmdSecret = &cli.Command{
 | 
				
			||||||
		Name:  "secret",
 | 
							Name:  "secret",
 | 
				
			||||||
		Usage: "Generate a secret token",
 | 
							Usage: "Generate a secret token",
 | 
				
			||||||
		Subcommands: []cli.Command{
 | 
							Subcommands: []*cli.Command{
 | 
				
			||||||
			microcmdGenerateInternalToken,
 | 
								microcmdGenerateInternalToken,
 | 
				
			||||||
			microcmdGenerateLfsJwtSecret,
 | 
								microcmdGenerateLfsJwtSecret,
 | 
				
			||||||
			microcmdGenerateSecretKey,
 | 
								microcmdGenerateSecretKey,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	microcmdGenerateInternalToken = cli.Command{
 | 
						microcmdGenerateInternalToken = &cli.Command{
 | 
				
			||||||
		Name:   "INTERNAL_TOKEN",
 | 
							Name:   "INTERNAL_TOKEN",
 | 
				
			||||||
		Usage:  "Generate a new INTERNAL_TOKEN",
 | 
							Usage:  "Generate a new INTERNAL_TOKEN",
 | 
				
			||||||
		Action: runGenerateInternalToken,
 | 
							Action: runGenerateInternalToken,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	microcmdGenerateLfsJwtSecret = cli.Command{
 | 
						microcmdGenerateLfsJwtSecret = &cli.Command{
 | 
				
			||||||
		Name:    "JWT_SECRET",
 | 
							Name:    "JWT_SECRET",
 | 
				
			||||||
		Aliases: []string{"LFS_JWT_SECRET"},
 | 
							Aliases: []string{"LFS_JWT_SECRET"},
 | 
				
			||||||
		Usage:   "Generate a new JWT_SECRET",
 | 
							Usage:   "Generate a new JWT_SECRET",
 | 
				
			||||||
		Action:  runGenerateLfsJwtSecret,
 | 
							Action:  runGenerateLfsJwtSecret,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	microcmdGenerateSecretKey = cli.Command{
 | 
						microcmdGenerateSecretKey = &cli.Command{
 | 
				
			||||||
		Name:   "SECRET_KEY",
 | 
							Name:   "SECRET_KEY",
 | 
				
			||||||
		Usage:  "Generate a new SECRET_KEY",
 | 
							Usage:  "Generate a new SECRET_KEY",
 | 
				
			||||||
		Action: runGenerateSecretKey,
 | 
							Action: runGenerateSecretKey,
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										22
									
								
								cmd/hook.go
									
									
									
									
									
								
							
							
						
						
									
										22
									
								
								cmd/hook.go
									
									
									
									
									
								
							@@ -20,7 +20,7 @@ import (
 | 
				
			|||||||
	repo_module "code.gitea.io/gitea/modules/repository"
 | 
						repo_module "code.gitea.io/gitea/modules/repository"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -29,12 +29,12 @@ const (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	// CmdHook represents the available hooks sub-command.
 | 
						// CmdHook represents the available hooks sub-command.
 | 
				
			||||||
	CmdHook = cli.Command{
 | 
						CmdHook = &cli.Command{
 | 
				
			||||||
		Name:        "hook",
 | 
							Name:        "hook",
 | 
				
			||||||
		Usage:       "Delegate commands to corresponding Git hooks",
 | 
							Usage:       "Delegate commands to corresponding Git hooks",
 | 
				
			||||||
		Description: "This should only be called by Git",
 | 
							Description: "This should only be called by Git",
 | 
				
			||||||
		Before:      PrepareConsoleLoggerLevel(log.FATAL),
 | 
							Before:      PrepareConsoleLoggerLevel(log.FATAL),
 | 
				
			||||||
		Subcommands: []cli.Command{
 | 
							Subcommands: []*cli.Command{
 | 
				
			||||||
			subcmdHookPreReceive,
 | 
								subcmdHookPreReceive,
 | 
				
			||||||
			subcmdHookUpdate,
 | 
								subcmdHookUpdate,
 | 
				
			||||||
			subcmdHookPostReceive,
 | 
								subcmdHookPostReceive,
 | 
				
			||||||
@@ -42,47 +42,47 @@ var (
 | 
				
			|||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	subcmdHookPreReceive = cli.Command{
 | 
						subcmdHookPreReceive = &cli.Command{
 | 
				
			||||||
		Name:        "pre-receive",
 | 
							Name:        "pre-receive",
 | 
				
			||||||
		Usage:       "Delegate pre-receive Git hook",
 | 
							Usage:       "Delegate pre-receive Git hook",
 | 
				
			||||||
		Description: "This command should only be called by Git",
 | 
							Description: "This command should only be called by Git",
 | 
				
			||||||
		Action:      runHookPreReceive,
 | 
							Action:      runHookPreReceive,
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name: "debug",
 | 
									Name: "debug",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	subcmdHookUpdate = cli.Command{
 | 
						subcmdHookUpdate = &cli.Command{
 | 
				
			||||||
		Name:        "update",
 | 
							Name:        "update",
 | 
				
			||||||
		Usage:       "Delegate update Git hook",
 | 
							Usage:       "Delegate update Git hook",
 | 
				
			||||||
		Description: "This command should only be called by Git",
 | 
							Description: "This command should only be called by Git",
 | 
				
			||||||
		Action:      runHookUpdate,
 | 
							Action:      runHookUpdate,
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name: "debug",
 | 
									Name: "debug",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	subcmdHookPostReceive = cli.Command{
 | 
						subcmdHookPostReceive = &cli.Command{
 | 
				
			||||||
		Name:        "post-receive",
 | 
							Name:        "post-receive",
 | 
				
			||||||
		Usage:       "Delegate post-receive Git hook",
 | 
							Usage:       "Delegate post-receive Git hook",
 | 
				
			||||||
		Description: "This command should only be called by Git",
 | 
							Description: "This command should only be called by Git",
 | 
				
			||||||
		Action:      runHookPostReceive,
 | 
							Action:      runHookPostReceive,
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name: "debug",
 | 
									Name: "debug",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	// Note: new hook since git 2.29
 | 
						// Note: new hook since git 2.29
 | 
				
			||||||
	subcmdHookProcReceive = cli.Command{
 | 
						subcmdHookProcReceive = &cli.Command{
 | 
				
			||||||
		Name:        "proc-receive",
 | 
							Name:        "proc-receive",
 | 
				
			||||||
		Usage:       "Delegate proc-receive Git hook",
 | 
							Usage:       "Delegate proc-receive Git hook",
 | 
				
			||||||
		Description: "This command should only be called by Git",
 | 
							Description: "This command should only be called by Git",
 | 
				
			||||||
		Action:      runHookProcReceive,
 | 
							Action:      runHookProcReceive,
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name: "debug",
 | 
									Name: "debug",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										26
									
								
								cmd/keys.go
									
									
									
									
									
								
							
							
						
						
									
										26
									
								
								cmd/keys.go
									
									
									
									
									
								
							@@ -11,33 +11,37 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/private"
 | 
						"code.gitea.io/gitea/modules/private"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CmdKeys represents the available keys sub-command
 | 
					// CmdKeys represents the available keys sub-command
 | 
				
			||||||
var CmdKeys = cli.Command{
 | 
					var CmdKeys = &cli.Command{
 | 
				
			||||||
	Name:   "keys",
 | 
						Name:   "keys",
 | 
				
			||||||
	Usage:  "This command queries the Gitea database to get the authorized command for a given ssh key fingerprint",
 | 
						Usage:  "This command queries the Gitea database to get the authorized command for a given ssh key fingerprint",
 | 
				
			||||||
	Before: PrepareConsoleLoggerLevel(log.FATAL),
 | 
						Before: PrepareConsoleLoggerLevel(log.FATAL),
 | 
				
			||||||
	Action: runKeys,
 | 
						Action: runKeys,
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "expected, e",
 | 
								Name:    "expected",
 | 
				
			||||||
 | 
								Aliases: []string{"e"},
 | 
				
			||||||
			Value:   "git",
 | 
								Value:   "git",
 | 
				
			||||||
			Usage:   "Expected user for whom provide key commands",
 | 
								Usage:   "Expected user for whom provide key commands",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "username, u",
 | 
								Name:    "username",
 | 
				
			||||||
 | 
								Aliases: []string{"u"},
 | 
				
			||||||
			Value:   "",
 | 
								Value:   "",
 | 
				
			||||||
			Usage:   "Username trying to log in by SSH",
 | 
								Usage:   "Username trying to log in by SSH",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "type, t",
 | 
								Name:    "type",
 | 
				
			||||||
 | 
								Aliases: []string{"t"},
 | 
				
			||||||
			Value:   "",
 | 
								Value:   "",
 | 
				
			||||||
			Usage:   "Type of the SSH key provided to the SSH Server (requires content to be provided too)",
 | 
								Usage:   "Type of the SSH key provided to the SSH Server (requires content to be provided too)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "content, k",
 | 
								Name:    "content",
 | 
				
			||||||
 | 
								Aliases: []string{"k"},
 | 
				
			||||||
			Value:   "",
 | 
								Value:   "",
 | 
				
			||||||
			Usage:   "Base64 encoded content of the SSH key provided to the SSH Server (requires type to be provided too)",
 | 
								Usage:   "Base64 encoded content of the SSH key provided to the SSH Server (requires type to be provided too)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -73,6 +77,6 @@ func runKeys(c *cli.Context) error {
 | 
				
			|||||||
	if extra.Error != nil {
 | 
						if extra.Error != nil {
 | 
				
			||||||
		return extra.Error
 | 
							return extra.Error
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	fmt.Println(strings.TrimSpace(authorizedString))
 | 
						_, _ = fmt.Fprintln(c.App.Writer, strings.TrimSpace(authorizedString))
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/private"
 | 
						"code.gitea.io/gitea/modules/private"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func runSendMail(c *cli.Context) error {
 | 
					func runSendMail(c *cli.Context) error {
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										196
									
								
								cmd/main.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										196
									
								
								cmd/main.go
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,196 @@
 | 
				
			|||||||
 | 
					// Copyright 2023 The Gitea Authors. All rights reserved.
 | 
				
			||||||
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"reflect"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// cmdHelp is our own help subcommand with more information
 | 
				
			||||||
 | 
					func cmdHelp() *cli.Command {
 | 
				
			||||||
 | 
						c := &cli.Command{
 | 
				
			||||||
 | 
							Name:      "help",
 | 
				
			||||||
 | 
							Aliases:   []string{"h"},
 | 
				
			||||||
 | 
							Usage:     "Shows a list of commands or help for one command",
 | 
				
			||||||
 | 
							ArgsUsage: "[command]",
 | 
				
			||||||
 | 
							Action: func(c *cli.Context) (err error) {
 | 
				
			||||||
 | 
								args := c.Args()
 | 
				
			||||||
 | 
								if args.Present() {
 | 
				
			||||||
 | 
									err = cli.ShowCommandHelp(c, args.First())
 | 
				
			||||||
 | 
								} else {
 | 
				
			||||||
 | 
									err = cli.ShowAppHelp(c)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								_, _ = fmt.Fprintf(c.App.Writer, `
 | 
				
			||||||
 | 
					DEFAULT CONFIGURATION:
 | 
				
			||||||
 | 
					   AppPath:    %s
 | 
				
			||||||
 | 
					   WorkPath:   %s
 | 
				
			||||||
 | 
					   CustomPath: %s
 | 
				
			||||||
 | 
					   ConfigFile: %s
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					`, setting.AppPath, setting.AppWorkPath, setting.CustomPath, setting.CustomConf)
 | 
				
			||||||
 | 
								return err
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return c
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					var helpFlag = cli.HelpFlag
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func init() {
 | 
				
			||||||
 | 
						// cli.HelpFlag = nil TODO: after https://github.com/urfave/cli/issues/1794 we can use this
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func appGlobalFlags() []cli.Flag {
 | 
				
			||||||
 | 
						return []cli.Flag{
 | 
				
			||||||
 | 
							// make the builtin flags at the top
 | 
				
			||||||
 | 
							helpFlag,
 | 
				
			||||||
 | 
							cli.VersionFlag,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// shared configuration flags, they are for global and for each sub-command at the same time
 | 
				
			||||||
 | 
							// eg: such command is valid: "./gitea --config /tmp/app.ini web --config /tmp/app.ini", while it's discouraged indeed
 | 
				
			||||||
 | 
							// keep in mind that the short flags like "-C", "-c" and "-w" are globally polluted, they can't be used for sub-commands anymore.
 | 
				
			||||||
 | 
							&cli.StringFlag{
 | 
				
			||||||
 | 
								Name:    "custom-path",
 | 
				
			||||||
 | 
								Aliases: []string{"C"},
 | 
				
			||||||
 | 
								Usage:   "Set custom path (defaults to '{WorkPath}/custom')",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							&cli.StringFlag{
 | 
				
			||||||
 | 
								Name:    "config",
 | 
				
			||||||
 | 
								Aliases: []string{"c"},
 | 
				
			||||||
 | 
								Value:   setting.CustomConf,
 | 
				
			||||||
 | 
								Usage:   "Set custom config file (defaults to '{WorkPath}/custom/conf/app.ini')",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							&cli.StringFlag{
 | 
				
			||||||
 | 
								Name:    "work-path",
 | 
				
			||||||
 | 
								Aliases: []string{"w"},
 | 
				
			||||||
 | 
								Usage:   "Set Gitea's working path (defaults to the Gitea's binary directory)",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func prepareSubcommandWithConfig(command *cli.Command, globalFlags []cli.Flag) {
 | 
				
			||||||
 | 
						command.Flags = append(append([]cli.Flag{}, globalFlags...), command.Flags...)
 | 
				
			||||||
 | 
						command.Action = prepareWorkPathAndCustomConf(command.Action)
 | 
				
			||||||
 | 
						command.HideHelp = true
 | 
				
			||||||
 | 
						if command.Name != "help" {
 | 
				
			||||||
 | 
							command.Subcommands = append(command.Subcommands, cmdHelp())
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						for i := range command.Subcommands {
 | 
				
			||||||
 | 
							prepareSubcommandWithConfig(command.Subcommands[i], globalFlags)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// prepareWorkPathAndCustomConf wraps the Action to prepare the work path and custom config
 | 
				
			||||||
 | 
					// It can't use "Before", because each level's sub-command's Before will be called one by one, so the "init" would be done multiple times
 | 
				
			||||||
 | 
					func prepareWorkPathAndCustomConf(action cli.ActionFunc) func(ctx *cli.Context) error {
 | 
				
			||||||
 | 
						return func(ctx *cli.Context) error {
 | 
				
			||||||
 | 
							var args setting.ArgWorkPathAndCustomConf
 | 
				
			||||||
 | 
							ctxLineage := ctx.Lineage()
 | 
				
			||||||
 | 
							for i := len(ctxLineage) - 1; i >= 0; i-- {
 | 
				
			||||||
 | 
								curCtx := ctxLineage[i]
 | 
				
			||||||
 | 
								if curCtx.IsSet("work-path") && args.WorkPath == "" {
 | 
				
			||||||
 | 
									args.WorkPath = curCtx.String("work-path")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if curCtx.IsSet("custom-path") && args.CustomPath == "" {
 | 
				
			||||||
 | 
									args.CustomPath = curCtx.String("custom-path")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								if curCtx.IsSet("config") && args.CustomConf == "" {
 | 
				
			||||||
 | 
									args.CustomConf = curCtx.String("config")
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							setting.InitWorkPathAndCommonConfig(os.Getenv, args)
 | 
				
			||||||
 | 
							if ctx.Bool("help") || action == nil {
 | 
				
			||||||
 | 
								// the default behavior of "urfave/cli": "nil action" means "show help"
 | 
				
			||||||
 | 
								return cmdHelp().Action(ctx)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return action(ctx)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func reflectGet(v any, fieldName string) any {
 | 
				
			||||||
 | 
						e := reflect.ValueOf(v).Elem()
 | 
				
			||||||
 | 
						return e.FieldByName(fieldName).Interface()
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// https://cli.urfave.org/migrate-v1-to-v2/#flag-aliases-are-done-differently
 | 
				
			||||||
 | 
					// Sadly v2 doesn't warn you if a comma is in the name. (https://github.com/urfave/cli/issues/1103)
 | 
				
			||||||
 | 
					func checkCommandFlags(c any) bool {
 | 
				
			||||||
 | 
						var cmds []*cli.Command
 | 
				
			||||||
 | 
						if app, ok := c.(*cli.App); ok {
 | 
				
			||||||
 | 
							cmds = app.Commands
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							cmds = c.(*cli.Command).Subcommands
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						ok := true
 | 
				
			||||||
 | 
						for _, cmd := range cmds {
 | 
				
			||||||
 | 
							for _, flag := range cmd.Flags {
 | 
				
			||||||
 | 
								flagName := reflectGet(flag, "Name").(string)
 | 
				
			||||||
 | 
								if strings.Contains(flagName, ",") {
 | 
				
			||||||
 | 
									ok = false
 | 
				
			||||||
 | 
									log.Error("cli.Flag can't have comma in its Name: %q, use Aliases instead", flagName)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							if !checkCommandFlags(cmd) {
 | 
				
			||||||
 | 
								ok = false
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return ok
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func NewMainApp() *cli.App {
 | 
				
			||||||
 | 
						app := cli.NewApp()
 | 
				
			||||||
 | 
						app.EnableBashCompletion = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// these sub-commands need to use config file
 | 
				
			||||||
 | 
						subCmdWithConfig := []*cli.Command{
 | 
				
			||||||
 | 
							CmdWeb,
 | 
				
			||||||
 | 
							CmdServ,
 | 
				
			||||||
 | 
							CmdHook,
 | 
				
			||||||
 | 
							CmdDump,
 | 
				
			||||||
 | 
							CmdAdmin,
 | 
				
			||||||
 | 
							CmdMigrate,
 | 
				
			||||||
 | 
							CmdKeys,
 | 
				
			||||||
 | 
							CmdConvert,
 | 
				
			||||||
 | 
							CmdDoctor,
 | 
				
			||||||
 | 
							CmdManager,
 | 
				
			||||||
 | 
							CmdEmbedded,
 | 
				
			||||||
 | 
							CmdMigrateStorage,
 | 
				
			||||||
 | 
							CmdDumpRepository,
 | 
				
			||||||
 | 
							CmdRestoreRepository,
 | 
				
			||||||
 | 
							CmdActions,
 | 
				
			||||||
 | 
							cmdHelp(), // the "help" sub-command was used to show the more information for "work path" and "custom config"
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// these sub-commands do not need the config file, and they do not depend on any path or environment variable.
 | 
				
			||||||
 | 
						subCmdStandalone := []*cli.Command{
 | 
				
			||||||
 | 
							CmdCert,
 | 
				
			||||||
 | 
							CmdGenerate,
 | 
				
			||||||
 | 
							CmdDocs,
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						app.DefaultCommand = CmdWeb.Name
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						globalFlags := appGlobalFlags()
 | 
				
			||||||
 | 
						app.Flags = append(app.Flags, globalFlags...)
 | 
				
			||||||
 | 
						app.HideHelp = true // use our own help action to show helps (with more information like default config)
 | 
				
			||||||
 | 
						app.Before = PrepareConsoleLoggerLevel(log.INFO)
 | 
				
			||||||
 | 
						for i := range subCmdWithConfig {
 | 
				
			||||||
 | 
							prepareSubcommandWithConfig(subCmdWithConfig[i], globalFlags)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						app.Commands = append(app.Commands, subCmdWithConfig...)
 | 
				
			||||||
 | 
						app.Commands = append(app.Commands, subCmdStandalone...)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if !checkCommandFlags(app) {
 | 
				
			||||||
 | 
							panic("some flags are incorrect") // this is a runtime check to help developers
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						return app
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										115
									
								
								cmd/main_test.go
									
									
									
									
									
								
							
							
						
						
									
										115
									
								
								cmd/main_test.go
									
									
									
									
									
								
							@@ -4,9 +4,17 @@
 | 
				
			|||||||
package cmd
 | 
					package cmd
 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
 | 
						"fmt"
 | 
				
			||||||
 | 
						"os"
 | 
				
			||||||
 | 
						"path/filepath"
 | 
				
			||||||
 | 
						"strings"
 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/models/unittest"
 | 
						"code.gitea.io/gitea/models/unittest"
 | 
				
			||||||
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestMain(m *testing.M) {
 | 
					func TestMain(m *testing.M) {
 | 
				
			||||||
@@ -14,3 +22,110 @@ func TestMain(m *testing.M) {
 | 
				
			|||||||
		GiteaRootPath: "..",
 | 
							GiteaRootPath: "..",
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func makePathOutput(workPath, customPath, customConf string) string {
 | 
				
			||||||
 | 
						return fmt.Sprintf("WorkPath=%s\nCustomPath=%s\nCustomConf=%s", workPath, customPath, customConf)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func newTestApp() *cli.App {
 | 
				
			||||||
 | 
						app := NewMainApp()
 | 
				
			||||||
 | 
						testCmd := &cli.Command{
 | 
				
			||||||
 | 
							Name: "test-cmd",
 | 
				
			||||||
 | 
							Action: func(ctx *cli.Context) error {
 | 
				
			||||||
 | 
								_, _ = fmt.Fprint(app.Writer, makePathOutput(setting.AppWorkPath, setting.CustomPath, setting.CustomConf))
 | 
				
			||||||
 | 
								return nil
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						prepareSubcommandWithConfig(testCmd, appGlobalFlags())
 | 
				
			||||||
 | 
						app.Commands = append(app.Commands, testCmd)
 | 
				
			||||||
 | 
						app.DefaultCommand = testCmd.Name
 | 
				
			||||||
 | 
						return app
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func TestCliCmd(t *testing.T) {
 | 
				
			||||||
 | 
						defaultWorkPath := filepath.Dir(setting.AppPath)
 | 
				
			||||||
 | 
						defaultCustomPath := filepath.Join(defaultWorkPath, "custom")
 | 
				
			||||||
 | 
						defaultCustomConf := filepath.Join(defaultCustomPath, "conf/app.ini")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cli.CommandHelpTemplate = "(command help template)"
 | 
				
			||||||
 | 
						cli.AppHelpTemplate = "(app help template)"
 | 
				
			||||||
 | 
						cli.SubcommandHelpTemplate = "(subcommand help template)"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						cases := []struct {
 | 
				
			||||||
 | 
							env map[string]string
 | 
				
			||||||
 | 
							cmd string
 | 
				
			||||||
 | 
							exp string
 | 
				
			||||||
 | 
						}{
 | 
				
			||||||
 | 
							// main command help
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								cmd: "./gitea help",
 | 
				
			||||||
 | 
								exp: "DEFAULT CONFIGURATION:",
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
							// parse paths
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								cmd: "./gitea test-cmd",
 | 
				
			||||||
 | 
								exp: makePathOutput(defaultWorkPath, defaultCustomPath, defaultCustomConf),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								cmd: "./gitea -c /tmp/app.ini test-cmd",
 | 
				
			||||||
 | 
								exp: makePathOutput(defaultWorkPath, defaultCustomPath, "/tmp/app.ini"),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								cmd: "./gitea test-cmd -c /tmp/app.ini",
 | 
				
			||||||
 | 
								exp: makePathOutput(defaultWorkPath, defaultCustomPath, "/tmp/app.ini"),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								env: map[string]string{"GITEA_WORK_DIR": "/tmp"},
 | 
				
			||||||
 | 
								cmd: "./gitea test-cmd",
 | 
				
			||||||
 | 
								exp: makePathOutput("/tmp", "/tmp/custom", "/tmp/custom/conf/app.ini"),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								env: map[string]string{"GITEA_WORK_DIR": "/tmp"},
 | 
				
			||||||
 | 
								cmd: "./gitea test-cmd --work-path /tmp/other",
 | 
				
			||||||
 | 
								exp: makePathOutput("/tmp/other", "/tmp/other/custom", "/tmp/other/custom/conf/app.ini"),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
							{
 | 
				
			||||||
 | 
								env: map[string]string{"GITEA_WORK_DIR": "/tmp"},
 | 
				
			||||||
 | 
								cmd: "./gitea test-cmd --config /tmp/app-other.ini",
 | 
				
			||||||
 | 
								exp: makePathOutput("/tmp", "/tmp/custom", "/tmp/app-other.ini"),
 | 
				
			||||||
 | 
							},
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						app := newTestApp()
 | 
				
			||||||
 | 
						var envBackup []string
 | 
				
			||||||
 | 
						for _, s := range os.Environ() {
 | 
				
			||||||
 | 
							if strings.HasPrefix(s, "GITEA_") && strings.Contains(s, "=") {
 | 
				
			||||||
 | 
								envBackup = append(envBackup, s)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						clearGiteaEnv := func() {
 | 
				
			||||||
 | 
							for _, s := range os.Environ() {
 | 
				
			||||||
 | 
								if strings.HasPrefix(s, "GITEA_") {
 | 
				
			||||||
 | 
									_ = os.Unsetenv(s)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						defer func() {
 | 
				
			||||||
 | 
							clearGiteaEnv()
 | 
				
			||||||
 | 
							for _, s := range envBackup {
 | 
				
			||||||
 | 
								k, v, _ := strings.Cut(s, "=")
 | 
				
			||||||
 | 
								_ = os.Setenv(k, v)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						for _, c := range cases {
 | 
				
			||||||
 | 
							clearGiteaEnv()
 | 
				
			||||||
 | 
							for k, v := range c.env {
 | 
				
			||||||
 | 
								_ = os.Setenv(k, v)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							args := strings.Split(c.cmd, " ") // for test only, "split" is good enough
 | 
				
			||||||
 | 
							out := new(strings.Builder)
 | 
				
			||||||
 | 
							app.Writer = out
 | 
				
			||||||
 | 
							err := app.Run(args)
 | 
				
			||||||
 | 
							assert.NoError(t, err, c.cmd)
 | 
				
			||||||
 | 
							assert.NotEmpty(t, c.exp, c.cmd)
 | 
				
			||||||
 | 
							outStr := out.String()
 | 
				
			||||||
 | 
							assert.Contains(t, outStr, c.exp, c.cmd)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,16 +9,16 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/modules/private"
 | 
						"code.gitea.io/gitea/modules/private"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	// CmdManager represents the manager command
 | 
						// CmdManager represents the manager command
 | 
				
			||||||
	CmdManager = cli.Command{
 | 
						CmdManager = &cli.Command{
 | 
				
			||||||
		Name:        "manager",
 | 
							Name:        "manager",
 | 
				
			||||||
		Usage:       "Manage the running gitea process",
 | 
							Usage:       "Manage the running gitea process",
 | 
				
			||||||
		Description: "This is a command for managing the running gitea process",
 | 
							Description: "This is a command for managing the running gitea process",
 | 
				
			||||||
		Subcommands: []cli.Command{
 | 
							Subcommands: []*cli.Command{
 | 
				
			||||||
			subcmdShutdown,
 | 
								subcmdShutdown,
 | 
				
			||||||
			subcmdRestart,
 | 
								subcmdRestart,
 | 
				
			||||||
			subcmdReloadTemplates,
 | 
								subcmdReloadTemplates,
 | 
				
			||||||
@@ -27,80 +27,80 @@ var (
 | 
				
			|||||||
			subCmdProcesses,
 | 
								subCmdProcesses,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	subcmdShutdown = cli.Command{
 | 
						subcmdShutdown = &cli.Command{
 | 
				
			||||||
		Name:  "shutdown",
 | 
							Name:  "shutdown",
 | 
				
			||||||
		Usage: "Gracefully shutdown the running process",
 | 
							Usage: "Gracefully shutdown the running process",
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name: "debug",
 | 
									Name: "debug",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Action: runShutdown,
 | 
							Action: runShutdown,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	subcmdRestart = cli.Command{
 | 
						subcmdRestart = &cli.Command{
 | 
				
			||||||
		Name:  "restart",
 | 
							Name:  "restart",
 | 
				
			||||||
		Usage: "Gracefully restart the running process - (not implemented for windows servers)",
 | 
							Usage: "Gracefully restart the running process - (not implemented for windows servers)",
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name: "debug",
 | 
									Name: "debug",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Action: runRestart,
 | 
							Action: runRestart,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	subcmdReloadTemplates = cli.Command{
 | 
						subcmdReloadTemplates = &cli.Command{
 | 
				
			||||||
		Name:  "reload-templates",
 | 
							Name:  "reload-templates",
 | 
				
			||||||
		Usage: "Reload template files in the running process",
 | 
							Usage: "Reload template files in the running process",
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name: "debug",
 | 
									Name: "debug",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		Action: runReloadTemplates,
 | 
							Action: runReloadTemplates,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	subcmdFlushQueues = cli.Command{
 | 
						subcmdFlushQueues = &cli.Command{
 | 
				
			||||||
		Name:   "flush-queues",
 | 
							Name:   "flush-queues",
 | 
				
			||||||
		Usage:  "Flush queues in the running process",
 | 
							Usage:  "Flush queues in the running process",
 | 
				
			||||||
		Action: runFlushQueues,
 | 
							Action: runFlushQueues,
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.DurationFlag{
 | 
								&cli.DurationFlag{
 | 
				
			||||||
				Name:  "timeout",
 | 
									Name:  "timeout",
 | 
				
			||||||
				Value: 60 * time.Second,
 | 
									Value: 60 * time.Second,
 | 
				
			||||||
				Usage: "Timeout for the flushing process",
 | 
									Usage: "Timeout for the flushing process",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name:  "non-blocking",
 | 
									Name:  "non-blocking",
 | 
				
			||||||
				Usage: "Set to true to not wait for flush to complete before returning",
 | 
									Usage: "Set to true to not wait for flush to complete before returning",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name: "debug",
 | 
									Name: "debug",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	subCmdProcesses = cli.Command{
 | 
						subCmdProcesses = &cli.Command{
 | 
				
			||||||
		Name:   "processes",
 | 
							Name:   "processes",
 | 
				
			||||||
		Usage:  "Display running processes within the current process",
 | 
							Usage:  "Display running processes within the current process",
 | 
				
			||||||
		Action: runProcesses,
 | 
							Action: runProcesses,
 | 
				
			||||||
		Flags: []cli.Flag{
 | 
							Flags: []cli.Flag{
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name: "debug",
 | 
									Name: "debug",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name:  "flat",
 | 
									Name:  "flat",
 | 
				
			||||||
				Usage: "Show processes as flat table rather than as tree",
 | 
									Usage: "Show processes as flat table rather than as tree",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name:  "no-system",
 | 
									Name:  "no-system",
 | 
				
			||||||
				Usage: "Do not show system processes",
 | 
									Usage: "Do not show system processes",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name:  "stacktraces",
 | 
									Name:  "stacktraces",
 | 
				
			||||||
				Usage: "Show stacktraces",
 | 
									Usage: "Show stacktraces",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.BoolFlag{
 | 
								&cli.BoolFlag{
 | 
				
			||||||
				Name:  "json",
 | 
									Name:  "json",
 | 
				
			||||||
				Usage: "Output as json",
 | 
									Usage: "Output as json",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
			cli.StringFlag{
 | 
								&cli.StringFlag{
 | 
				
			||||||
				Name:  "cancel",
 | 
									Name:  "cancel",
 | 
				
			||||||
				Usage: "Process PID to cancel. (Only available for non-system processes.)",
 | 
									Usage: "Process PID to cancel. (Only available for non-system processes.)",
 | 
				
			||||||
			},
 | 
								},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -10,49 +10,61 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/private"
 | 
						"code.gitea.io/gitea/modules/private"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	defaultLoggingFlags = []cli.Flag{
 | 
						defaultLoggingFlags = []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "logger",
 | 
								Name:  "logger",
 | 
				
			||||||
			Usage: `Logger name - will default to "default"`,
 | 
								Usage: `Logger name - will default to "default"`,
 | 
				
			||||||
		}, cli.StringFlag{
 | 
							},
 | 
				
			||||||
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "writer",
 | 
								Name:  "writer",
 | 
				
			||||||
			Usage: "Name of the log writer - will default to mode",
 | 
								Usage: "Name of the log writer - will default to mode",
 | 
				
			||||||
		}, cli.StringFlag{
 | 
							},
 | 
				
			||||||
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "level",
 | 
								Name:  "level",
 | 
				
			||||||
			Usage: "Logging level for the new logger",
 | 
								Usage: "Logging level for the new logger",
 | 
				
			||||||
		}, cli.StringFlag{
 | 
							},
 | 
				
			||||||
			Name:  "stacktrace-level, L",
 | 
							&cli.StringFlag{
 | 
				
			||||||
 | 
								Name:    "stacktrace-level",
 | 
				
			||||||
 | 
								Aliases: []string{"L"},
 | 
				
			||||||
			Usage:   "Stacktrace logging level",
 | 
								Usage:   "Stacktrace logging level",
 | 
				
			||||||
		}, cli.StringFlag{
 | 
							},
 | 
				
			||||||
			Name:  "flags, F",
 | 
							&cli.StringFlag{
 | 
				
			||||||
 | 
								Name:    "flags",
 | 
				
			||||||
 | 
								Aliases: []string{"F"},
 | 
				
			||||||
			Usage:   "Flags for the logger",
 | 
								Usage:   "Flags for the logger",
 | 
				
			||||||
		}, cli.StringFlag{
 | 
							},
 | 
				
			||||||
			Name:  "expression, e",
 | 
							&cli.StringFlag{
 | 
				
			||||||
 | 
								Name:    "expression",
 | 
				
			||||||
 | 
								Aliases: []string{"e"},
 | 
				
			||||||
			Usage:   "Matching expression for the logger",
 | 
								Usage:   "Matching expression for the logger",
 | 
				
			||||||
		}, cli.StringFlag{
 | 
							},
 | 
				
			||||||
			Name:  "prefix, p",
 | 
							&cli.StringFlag{
 | 
				
			||||||
 | 
								Name:    "prefix",
 | 
				
			||||||
 | 
								Aliases: []string{"p"},
 | 
				
			||||||
			Usage:   "Prefix for the logger",
 | 
								Usage:   "Prefix for the logger",
 | 
				
			||||||
		}, cli.BoolFlag{
 | 
							},
 | 
				
			||||||
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "color",
 | 
								Name:  "color",
 | 
				
			||||||
			Usage: "Use color in the logs",
 | 
								Usage: "Use color in the logs",
 | 
				
			||||||
		}, cli.BoolFlag{
 | 
							},
 | 
				
			||||||
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name: "debug",
 | 
								Name: "debug",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	subcmdLogging = cli.Command{
 | 
						subcmdLogging = &cli.Command{
 | 
				
			||||||
		Name:  "logging",
 | 
							Name:  "logging",
 | 
				
			||||||
		Usage: "Adjust logging commands",
 | 
							Usage: "Adjust logging commands",
 | 
				
			||||||
		Subcommands: []cli.Command{
 | 
							Subcommands: []*cli.Command{
 | 
				
			||||||
			{
 | 
								{
 | 
				
			||||||
				Name:  "pause",
 | 
									Name:  "pause",
 | 
				
			||||||
				Usage: "Pause logging (Gitea will buffer logs up to a certain point and will drop them after that point)",
 | 
									Usage: "Pause logging (Gitea will buffer logs up to a certain point and will drop them after that point)",
 | 
				
			||||||
				Flags: []cli.Flag{
 | 
									Flags: []cli.Flag{
 | 
				
			||||||
					cli.BoolFlag{
 | 
										&cli.BoolFlag{
 | 
				
			||||||
						Name: "debug",
 | 
											Name: "debug",
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
@@ -61,7 +73,7 @@ var (
 | 
				
			|||||||
				Name:  "resume",
 | 
									Name:  "resume",
 | 
				
			||||||
				Usage: "Resume logging",
 | 
									Usage: "Resume logging",
 | 
				
			||||||
				Flags: []cli.Flag{
 | 
									Flags: []cli.Flag{
 | 
				
			||||||
					cli.BoolFlag{
 | 
										&cli.BoolFlag{
 | 
				
			||||||
						Name: "debug",
 | 
											Name: "debug",
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
@@ -70,7 +82,7 @@ var (
 | 
				
			|||||||
				Name:  "release-and-reopen",
 | 
									Name:  "release-and-reopen",
 | 
				
			||||||
				Usage: "Cause Gitea to release and re-open files used for logging",
 | 
									Usage: "Cause Gitea to release and re-open files used for logging",
 | 
				
			||||||
				Flags: []cli.Flag{
 | 
									Flags: []cli.Flag{
 | 
				
			||||||
					cli.BoolFlag{
 | 
										&cli.BoolFlag{
 | 
				
			||||||
						Name: "debug",
 | 
											Name: "debug",
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
				},
 | 
									},
 | 
				
			||||||
@@ -80,9 +92,9 @@ var (
 | 
				
			|||||||
				Usage:     "Remove a logger",
 | 
									Usage:     "Remove a logger",
 | 
				
			||||||
				ArgsUsage: "[name] Name of logger to remove",
 | 
									ArgsUsage: "[name] Name of logger to remove",
 | 
				
			||||||
				Flags: []cli.Flag{
 | 
									Flags: []cli.Flag{
 | 
				
			||||||
					cli.BoolFlag{
 | 
										&cli.BoolFlag{
 | 
				
			||||||
						Name: "debug",
 | 
											Name: "debug",
 | 
				
			||||||
					}, cli.StringFlag{
 | 
										}, &cli.StringFlag{
 | 
				
			||||||
						Name:  "logger",
 | 
											Name:  "logger",
 | 
				
			||||||
						Usage: `Logger name - will default to "default"`,
 | 
											Usage: `Logger name - will default to "default"`,
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
@@ -91,31 +103,44 @@ var (
 | 
				
			|||||||
			}, {
 | 
								}, {
 | 
				
			||||||
				Name:  "add",
 | 
									Name:  "add",
 | 
				
			||||||
				Usage: "Add a logger",
 | 
									Usage: "Add a logger",
 | 
				
			||||||
				Subcommands: []cli.Command{
 | 
									Subcommands: []*cli.Command{
 | 
				
			||||||
					{
 | 
										{
 | 
				
			||||||
						Name:  "file",
 | 
											Name:  "file",
 | 
				
			||||||
						Usage: "Add a file logger",
 | 
											Usage: "Add a file logger",
 | 
				
			||||||
						Flags: append(defaultLoggingFlags, []cli.Flag{
 | 
											Flags: append(defaultLoggingFlags, []cli.Flag{
 | 
				
			||||||
							cli.StringFlag{
 | 
												&cli.StringFlag{
 | 
				
			||||||
								Name:  "filename, f",
 | 
													Name:    "filename",
 | 
				
			||||||
 | 
													Aliases: []string{"f"},
 | 
				
			||||||
								Usage:   "Filename for the logger - this must be set.",
 | 
													Usage:   "Filename for the logger - this must be set.",
 | 
				
			||||||
							}, cli.BoolTFlag{
 | 
												},
 | 
				
			||||||
								Name:  "rotate, r",
 | 
												&cli.BoolFlag{
 | 
				
			||||||
 | 
													Name:    "rotate",
 | 
				
			||||||
 | 
													Aliases: []string{"r"},
 | 
				
			||||||
								Usage:   "Rotate logs",
 | 
													Usage:   "Rotate logs",
 | 
				
			||||||
							}, cli.Int64Flag{
 | 
												},
 | 
				
			||||||
								Name:  "max-size, s",
 | 
												&cli.Int64Flag{
 | 
				
			||||||
 | 
													Name:    "max-size",
 | 
				
			||||||
 | 
													Aliases: []string{"s"},
 | 
				
			||||||
								Usage:   "Maximum size in bytes before rotation",
 | 
													Usage:   "Maximum size in bytes before rotation",
 | 
				
			||||||
							}, cli.BoolTFlag{
 | 
												},
 | 
				
			||||||
								Name:  "daily, d",
 | 
												&cli.BoolFlag{
 | 
				
			||||||
 | 
													Name:    "daily",
 | 
				
			||||||
 | 
													Aliases: []string{"d"},
 | 
				
			||||||
								Usage:   "Rotate logs daily",
 | 
													Usage:   "Rotate logs daily",
 | 
				
			||||||
							}, cli.IntFlag{
 | 
												},
 | 
				
			||||||
								Name:  "max-days, D",
 | 
												&cli.IntFlag{
 | 
				
			||||||
 | 
													Name:    "max-days",
 | 
				
			||||||
 | 
													Aliases: []string{"D"},
 | 
				
			||||||
								Usage:   "Maximum number of daily logs to keep",
 | 
													Usage:   "Maximum number of daily logs to keep",
 | 
				
			||||||
							}, cli.BoolTFlag{
 | 
												},
 | 
				
			||||||
								Name:  "compress, z",
 | 
												&cli.BoolFlag{
 | 
				
			||||||
 | 
													Name:    "compress",
 | 
				
			||||||
 | 
													Aliases: []string{"z"},
 | 
				
			||||||
								Usage:   "Compress rotated logs",
 | 
													Usage:   "Compress rotated logs",
 | 
				
			||||||
							}, cli.IntFlag{
 | 
												},
 | 
				
			||||||
								Name:  "compression-level, Z",
 | 
												&cli.IntFlag{
 | 
				
			||||||
 | 
													Name:    "compression-level",
 | 
				
			||||||
 | 
													Aliases: []string{"Z"},
 | 
				
			||||||
								Usage:   "Compression level to use",
 | 
													Usage:   "Compression level to use",
 | 
				
			||||||
							},
 | 
												},
 | 
				
			||||||
						}...),
 | 
											}...),
 | 
				
			||||||
@@ -124,17 +149,24 @@ var (
 | 
				
			|||||||
						Name:  "conn",
 | 
											Name:  "conn",
 | 
				
			||||||
						Usage: "Add a net conn logger",
 | 
											Usage: "Add a net conn logger",
 | 
				
			||||||
						Flags: append(defaultLoggingFlags, []cli.Flag{
 | 
											Flags: append(defaultLoggingFlags, []cli.Flag{
 | 
				
			||||||
							cli.BoolFlag{
 | 
												&cli.BoolFlag{
 | 
				
			||||||
								Name:  "reconnect-on-message, R",
 | 
													Name:    "reconnect-on-message",
 | 
				
			||||||
 | 
													Aliases: []string{"R"},
 | 
				
			||||||
								Usage:   "Reconnect to host for every message",
 | 
													Usage:   "Reconnect to host for every message",
 | 
				
			||||||
							}, cli.BoolFlag{
 | 
												},
 | 
				
			||||||
								Name:  "reconnect, r",
 | 
												&cli.BoolFlag{
 | 
				
			||||||
 | 
													Name:    "reconnect",
 | 
				
			||||||
 | 
													Aliases: []string{"r"},
 | 
				
			||||||
								Usage:   "Reconnect to host when connection is dropped",
 | 
													Usage:   "Reconnect to host when connection is dropped",
 | 
				
			||||||
							}, cli.StringFlag{
 | 
												},
 | 
				
			||||||
								Name:  "protocol, P",
 | 
												&cli.StringFlag{
 | 
				
			||||||
 | 
													Name:    "protocol",
 | 
				
			||||||
 | 
													Aliases: []string{"P"},
 | 
				
			||||||
								Usage:   "Set protocol to use: tcp, unix, or udp (defaults to tcp)",
 | 
													Usage:   "Set protocol to use: tcp, unix, or udp (defaults to tcp)",
 | 
				
			||||||
							}, cli.StringFlag{
 | 
												},
 | 
				
			||||||
								Name:  "address, a",
 | 
												&cli.StringFlag{
 | 
				
			||||||
 | 
													Name:    "address",
 | 
				
			||||||
 | 
													Aliases: []string{"a"},
 | 
				
			||||||
								Usage:   "Host address and port to connect to (defaults to :7020)",
 | 
													Usage:   "Host address and port to connect to (defaults to :7020)",
 | 
				
			||||||
							},
 | 
												},
 | 
				
			||||||
						}...),
 | 
											}...),
 | 
				
			||||||
@@ -145,9 +177,10 @@ var (
 | 
				
			|||||||
				Name:  "log-sql",
 | 
									Name:  "log-sql",
 | 
				
			||||||
				Usage: "Set LogSQL",
 | 
									Usage: "Set LogSQL",
 | 
				
			||||||
				Flags: []cli.Flag{
 | 
									Flags: []cli.Flag{
 | 
				
			||||||
					cli.BoolFlag{
 | 
										&cli.BoolFlag{
 | 
				
			||||||
						Name: "debug",
 | 
											Name: "debug",
 | 
				
			||||||
					}, cli.BoolFlag{
 | 
										},
 | 
				
			||||||
 | 
										&cli.BoolFlag{
 | 
				
			||||||
						Name:  "off",
 | 
											Name:  "off",
 | 
				
			||||||
						Usage: "Switch off SQL logging",
 | 
											Usage: "Switch off SQL logging",
 | 
				
			||||||
					},
 | 
										},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -11,11 +11,11 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CmdMigrate represents the available migrate sub-command.
 | 
					// CmdMigrate represents the available migrate sub-command.
 | 
				
			||||||
var CmdMigrate = cli.Command{
 | 
					var CmdMigrate = &cli.Command{
 | 
				
			||||||
	Name:        "migrate",
 | 
						Name:        "migrate",
 | 
				
			||||||
	Usage:       "Migrate the database",
 | 
						Usage:       "Migrate the database",
 | 
				
			||||||
	Description: "This is a command for migrating the database, so that you can run gitea admin create-user before starting the server.",
 | 
						Description: "This is a command for migrating the database, so that you can run gitea admin create-user before starting the server.",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -20,70 +20,73 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/storage"
 | 
						"code.gitea.io/gitea/modules/storage"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CmdMigrateStorage represents the available migrate storage sub-command.
 | 
					// CmdMigrateStorage represents the available migrate storage sub-command.
 | 
				
			||||||
var CmdMigrateStorage = cli.Command{
 | 
					var CmdMigrateStorage = &cli.Command{
 | 
				
			||||||
	Name:        "migrate-storage",
 | 
						Name:        "migrate-storage",
 | 
				
			||||||
	Usage:       "Migrate the storage",
 | 
						Usage:       "Migrate the storage",
 | 
				
			||||||
	Description: "Copies stored files from storage configured in app.ini to parameter-configured storage",
 | 
						Description: "Copies stored files from storage configured in app.ini to parameter-configured storage",
 | 
				
			||||||
	Action:      runMigrateStorage,
 | 
						Action:      runMigrateStorage,
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "type, t",
 | 
								Name:    "type",
 | 
				
			||||||
 | 
								Aliases: []string{"t"},
 | 
				
			||||||
			Value:   "",
 | 
								Value:   "",
 | 
				
			||||||
			Usage:   "Type of stored files to copy.  Allowed types: 'attachments', 'lfs', 'avatars', 'repo-avatars', 'repo-archivers', 'packages', 'actions-log'",
 | 
								Usage:   "Type of stored files to copy.  Allowed types: 'attachments', 'lfs', 'avatars', 'repo-avatars', 'repo-archivers', 'packages', 'actions-log'",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "storage, s",
 | 
								Name:    "storage",
 | 
				
			||||||
 | 
								Aliases: []string{"s"},
 | 
				
			||||||
			Value:   "",
 | 
								Value:   "",
 | 
				
			||||||
			Usage:   "New storage type: local (default) or minio",
 | 
								Usage:   "New storage type: local (default) or minio",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "path, p",
 | 
								Name:    "path",
 | 
				
			||||||
 | 
								Aliases: []string{"p"},
 | 
				
			||||||
			Value:   "",
 | 
								Value:   "",
 | 
				
			||||||
			Usage:   "New storage placement if store is local (leave blank for default)",
 | 
								Usage:   "New storage placement if store is local (leave blank for default)",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "minio-endpoint",
 | 
								Name:  "minio-endpoint",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Minio storage endpoint",
 | 
								Usage: "Minio storage endpoint",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "minio-access-key-id",
 | 
								Name:  "minio-access-key-id",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Minio storage accessKeyID",
 | 
								Usage: "Minio storage accessKeyID",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "minio-secret-access-key",
 | 
								Name:  "minio-secret-access-key",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Minio storage secretAccessKey",
 | 
								Usage: "Minio storage secretAccessKey",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "minio-bucket",
 | 
								Name:  "minio-bucket",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Minio storage bucket",
 | 
								Usage: "Minio storage bucket",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "minio-location",
 | 
								Name:  "minio-location",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Minio storage location to create bucket",
 | 
								Usage: "Minio storage location to create bucket",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "minio-base-path",
 | 
								Name:  "minio-base-path",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Minio storage base path on the bucket",
 | 
								Usage: "Minio storage base path on the bucket",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "minio-use-ssl",
 | 
								Name:  "minio-use-ssl",
 | 
				
			||||||
			Usage: "Enable SSL for minio",
 | 
								Usage: "Enable SSL for minio",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "minio-insecure-skip-verify",
 | 
								Name:  "minio-insecure-skip-verify",
 | 
				
			||||||
			Usage: "Skip SSL verification",
 | 
								Usage: "Skip SSL verification",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "minio-checksum-algorithm",
 | 
								Name:  "minio-checksum-algorithm",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Minio checksum algorithm (default/md5)",
 | 
								Usage: "Minio checksum algorithm (default/md5)",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,38 +9,39 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/private"
 | 
						"code.gitea.io/gitea/modules/private"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CmdRestoreRepository represents the available restore a repository sub-command.
 | 
					// CmdRestoreRepository represents the available restore a repository sub-command.
 | 
				
			||||||
var CmdRestoreRepository = cli.Command{
 | 
					var CmdRestoreRepository = &cli.Command{
 | 
				
			||||||
	Name:        "restore-repo",
 | 
						Name:        "restore-repo",
 | 
				
			||||||
	Usage:       "Restore the repository from disk",
 | 
						Usage:       "Restore the repository from disk",
 | 
				
			||||||
	Description: "This is a command for restoring the repository data.",
 | 
						Description: "This is a command for restoring the repository data.",
 | 
				
			||||||
	Action:      runRestoreRepository,
 | 
						Action:      runRestoreRepository,
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "repo_dir, r",
 | 
								Name:    "repo_dir",
 | 
				
			||||||
 | 
								Aliases: []string{"r"},
 | 
				
			||||||
			Value:   "./data",
 | 
								Value:   "./data",
 | 
				
			||||||
			Usage:   "Repository dir path to restore from",
 | 
								Usage:   "Repository dir path to restore from",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "owner_name",
 | 
								Name:  "owner_name",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Restore destination owner name",
 | 
								Usage: "Restore destination owner name",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "repo_name",
 | 
								Name:  "repo_name",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Restore destination repository name",
 | 
								Usage: "Restore destination repository name",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "units",
 | 
								Name:  "units",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: `Which items will be restored, one or more units should be separated as comma.
 | 
								Usage: `Which items will be restored, one or more units should be separated as comma.
 | 
				
			||||||
wiki, issues, labels, releases, release_assets, milestones, pull_requests, comments are allowed. Empty means all units.`,
 | 
					wiki, issues, labels, releases, release_assets, milestones, pull_requests, comments are allowed. Empty means all units.`,
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "validation",
 | 
								Name:  "validation",
 | 
				
			||||||
			Usage: "Sanity check the content of the files before trying to load them",
 | 
								Usage: "Sanity check the content of the files before trying to load them",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										20
									
								
								cmd/serv.go
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								cmd/serv.go
									
									
									
									
									
								
							@@ -32,7 +32,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	"github.com/golang-jwt/jwt/v5"
 | 
						"github.com/golang-jwt/jwt/v5"
 | 
				
			||||||
	"github.com/kballard/go-shellquote"
 | 
						"github.com/kballard/go-shellquote"
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const (
 | 
					const (
 | 
				
			||||||
@@ -40,17 +40,17 @@ const (
 | 
				
			|||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CmdServ represents the available serv sub-command.
 | 
					// CmdServ represents the available serv sub-command.
 | 
				
			||||||
var CmdServ = cli.Command{
 | 
					var CmdServ = &cli.Command{
 | 
				
			||||||
	Name:        "serv",
 | 
						Name:        "serv",
 | 
				
			||||||
	Usage:       "This command should only be called by SSH shell",
 | 
						Usage:       "This command should only be called by SSH shell",
 | 
				
			||||||
	Description: "Serv provides access auth for repositories",
 | 
						Description: "Serv provides access auth for repositories",
 | 
				
			||||||
	Before:      PrepareConsoleLoggerLevel(log.FATAL),
 | 
						Before:      PrepareConsoleLoggerLevel(log.FATAL),
 | 
				
			||||||
	Action:      runServ,
 | 
						Action:      runServ,
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name: "enable-pprof",
 | 
								Name: "enable-pprof",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name: "debug",
 | 
								Name: "debug",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
	},
 | 
						},
 | 
				
			||||||
@@ -119,7 +119,7 @@ func fail(ctx context.Context, userMessage, logMsgFmt string, args ...any) error
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		_ = private.SSHLog(ctx, true, logMsg)
 | 
							_ = private.SSHLog(ctx, true, logMsg)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return cli.NewExitError("", 1)
 | 
						return cli.Exit("", 1)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// handleCliResponseExtra handles the extra response from the cli sub-commands
 | 
					// handleCliResponseExtra handles the extra response from the cli sub-commands
 | 
				
			||||||
@@ -130,7 +130,7 @@ func handleCliResponseExtra(extra private.ResponseExtra) error {
 | 
				
			|||||||
		_, _ = fmt.Fprintln(os.Stdout, extra.UserMsg)
 | 
							_, _ = fmt.Fprintln(os.Stdout, extra.UserMsg)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	if extra.HasError() {
 | 
						if extra.HasError() {
 | 
				
			||||||
		return cli.NewExitError(extra.Error, 1)
 | 
							return cli.Exit(extra.Error, 1)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@@ -147,20 +147,20 @@ func runServ(c *cli.Context) error {
 | 
				
			|||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if len(c.Args()) < 1 {
 | 
						if c.NArg() < 1 {
 | 
				
			||||||
		if err := cli.ShowSubcommandHelp(c); err != nil {
 | 
							if err := cli.ShowSubcommandHelp(c); err != nil {
 | 
				
			||||||
			fmt.Printf("error showing subcommand help: %v\n", err)
 | 
								fmt.Printf("error showing subcommand help: %v\n", err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	keys := strings.Split(c.Args()[0], "-")
 | 
						keys := strings.Split(c.Args().First(), "-")
 | 
				
			||||||
	if len(keys) != 2 || keys[0] != "key" {
 | 
						if len(keys) != 2 || keys[0] != "key" {
 | 
				
			||||||
		return fail(ctx, "Key ID format error", "Invalid key argument: %s", c.Args()[0])
 | 
							return fail(ctx, "Key ID format error", "Invalid key argument: %s", c.Args().First())
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	keyID, err := strconv.ParseInt(keys[1], 10, 64)
 | 
						keyID, err := strconv.ParseInt(keys[1], 10, 64)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		return fail(ctx, "Key ID parsing error", "Invalid key argument: %s", c.Args()[1])
 | 
							return fail(ctx, "Key ID parsing error", "Invalid key argument: %s", c.Args().Get(1))
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
 | 
						cmd := os.Getenv("SSH_ORIGINAL_COMMAND")
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										23
									
								
								cmd/web.go
									
									
									
									
									
								
							
							
						
						
									
										23
									
								
								cmd/web.go
									
									
									
									
									
								
							@@ -23,14 +23,14 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/routers/install"
 | 
						"code.gitea.io/gitea/routers/install"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/felixge/fgprof"
 | 
						"github.com/felixge/fgprof"
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// PIDFile could be set from build tag
 | 
					// PIDFile could be set from build tag
 | 
				
			||||||
var PIDFile = "/run/gitea.pid"
 | 
					var PIDFile = "/run/gitea.pid"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// CmdWeb represents the available web sub-command.
 | 
					// CmdWeb represents the available web sub-command.
 | 
				
			||||||
var CmdWeb = cli.Command{
 | 
					var CmdWeb = &cli.Command{
 | 
				
			||||||
	Name:  "web",
 | 
						Name:  "web",
 | 
				
			||||||
	Usage: "Start Gitea web server",
 | 
						Usage: "Start Gitea web server",
 | 
				
			||||||
	Description: `Gitea web server is the only thing you need to run,
 | 
						Description: `Gitea web server is the only thing you need to run,
 | 
				
			||||||
@@ -38,26 +38,29 @@ and it takes care of all the other things for you`,
 | 
				
			|||||||
	Before: PrepareConsoleLoggerLevel(log.INFO),
 | 
						Before: PrepareConsoleLoggerLevel(log.INFO),
 | 
				
			||||||
	Action: runWeb,
 | 
						Action: runWeb,
 | 
				
			||||||
	Flags: []cli.Flag{
 | 
						Flags: []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "port, p",
 | 
								Name:    "port",
 | 
				
			||||||
 | 
								Aliases: []string{"p"},
 | 
				
			||||||
			Value:   "3000",
 | 
								Value:   "3000",
 | 
				
			||||||
			Usage:   "Temporary port number to prevent conflict",
 | 
								Usage:   "Temporary port number to prevent conflict",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "install-port",
 | 
								Name:  "install-port",
 | 
				
			||||||
			Value: "3000",
 | 
								Value: "3000",
 | 
				
			||||||
			Usage: "Temporary port number to run the install page on to prevent conflict",
 | 
								Usage: "Temporary port number to run the install page on to prevent conflict",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "pid, P",
 | 
								Name:    "pid",
 | 
				
			||||||
 | 
								Aliases: []string{"P"},
 | 
				
			||||||
			Value:   PIDFile,
 | 
								Value:   PIDFile,
 | 
				
			||||||
			Usage:   "Custom pid file path",
 | 
								Usage:   "Custom pid file path",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "quiet, q",
 | 
								Name:    "quiet",
 | 
				
			||||||
 | 
								Aliases: []string{"q"},
 | 
				
			||||||
			Usage:   "Only display Fatal logging errors until logging is set-up",
 | 
								Usage:   "Only display Fatal logging errors until logging is set-up",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "verbose",
 | 
								Name:  "verbose",
 | 
				
			||||||
			Usage: "Set initial logging to TRACE level until logging is properly set-up",
 | 
								Usage: "Set initial logging to TRACE level until logging is properly set-up",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -18,7 +18,7 @@ import (
 | 
				
			|||||||
	"syscall"
 | 
						"syscall"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/google/go-github/v53/github"
 | 
						"github.com/google/go-github/v53/github"
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
	"gopkg.in/yaml.v3"
 | 
						"gopkg.in/yaml.v3"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -32,55 +32,55 @@ func main() {
 | 
				
			|||||||
	app.ArgsUsage = "<PR-to-backport>"
 | 
						app.ArgsUsage = "<PR-to-backport>"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	app.Flags = []cli.Flag{
 | 
						app.Flags = []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "version",
 | 
								Name:  "version",
 | 
				
			||||||
			Usage: "Version branch to backport on to",
 | 
								Usage: "Version branch to backport on to",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "upstream",
 | 
								Name:  "upstream",
 | 
				
			||||||
			Value: "origin",
 | 
								Value: "origin",
 | 
				
			||||||
			Usage: "Upstream remote for the Gitea upstream",
 | 
								Usage: "Upstream remote for the Gitea upstream",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "release-branch",
 | 
								Name:  "release-branch",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Release branch to backport on. Will default to release/<version>",
 | 
								Usage: "Release branch to backport on. Will default to release/<version>",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "cherry-pick",
 | 
								Name:  "cherry-pick",
 | 
				
			||||||
			Usage: "SHA to cherry-pick as backport",
 | 
								Usage: "SHA to cherry-pick as backport",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "backport-branch",
 | 
								Name:  "backport-branch",
 | 
				
			||||||
			Usage: "Backport branch to backport on to (default: backport-<pr>-<version>",
 | 
								Usage: "Backport branch to backport on to (default: backport-<pr>-<version>",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "remote",
 | 
								Name:  "remote",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Remote for your fork of the Gitea upstream",
 | 
								Usage: "Remote for your fork of the Gitea upstream",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "fork-user",
 | 
								Name:  "fork-user",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Forked user name on Github",
 | 
								Usage: "Forked user name on Github",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "no-fetch",
 | 
								Name:  "no-fetch",
 | 
				
			||||||
			Usage: "Set this flag to prevent fetch of remote branches",
 | 
								Usage: "Set this flag to prevent fetch of remote branches",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "no-amend-message",
 | 
								Name:  "no-amend-message",
 | 
				
			||||||
			Usage: "Set this flag to prevent automatic amendment of the commit message",
 | 
								Usage: "Set this flag to prevent automatic amendment of the commit message",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "no-push",
 | 
								Name:  "no-push",
 | 
				
			||||||
			Usage: "Set this flag to prevent pushing the backport up to your fork",
 | 
								Usage: "Set this flag to prevent pushing the backport up to your fork",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "no-xdg-open",
 | 
								Name:  "no-xdg-open",
 | 
				
			||||||
			Usage: "Set this flag to not use xdg-open to open the PR URL",
 | 
								Usage: "Set this flag to not use xdg-open to open the PR URL",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.BoolFlag{
 | 
							&cli.BoolFlag{
 | 
				
			||||||
			Name:  "continue",
 | 
								Name:  "continue",
 | 
				
			||||||
			Usage: "Set this flag to continue from a git cherry-pick that has broken",
 | 
								Usage: "Set this flag to continue from a git cherry-pick that has broken",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
@@ -151,7 +151,7 @@ func runBackport(c *cli.Context) error {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	localReleaseBranch := path.Join(upstream, upstreamReleaseBranch)
 | 
						localReleaseBranch := path.Join(upstream, upstreamReleaseBranch)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	args := c.Args()
 | 
						args := c.Args().Slice()
 | 
				
			||||||
	if len(args) == 0 && pr == "" {
 | 
						if len(args) == 0 && pr == "" {
 | 
				
			||||||
		return fmt.Errorf("no PR number provided\nProvide a PR number to backport")
 | 
							return fmt.Errorf("no PR number provided\nProvide a PR number to backport")
 | 
				
			||||||
	} else if len(args) != 1 && pr == "" {
 | 
						} else if len(args) != 1 && pr == "" {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -9,7 +9,7 @@ import (
 | 
				
			|||||||
	"code.gitea.io/gitea/modules/log"
 | 
						"code.gitea.io/gitea/modules/log"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
@@ -46,22 +46,22 @@ func main() {
 | 
				
			|||||||
	and "GITEA__LOG_0x2E_CONSOLE__STDERR=false". Other examples can be found
 | 
						and "GITEA__LOG_0x2E_CONSOLE__STDERR=false". Other examples can be found
 | 
				
			||||||
	on the configuration cheat sheet.`
 | 
						on the configuration cheat sheet.`
 | 
				
			||||||
	app.Flags = []cli.Flag{
 | 
						app.Flags = []cli.Flag{
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "custom-path, C",
 | 
								Name:  "custom-path, C",
 | 
				
			||||||
			Value: setting.CustomPath,
 | 
								Value: setting.CustomPath,
 | 
				
			||||||
			Usage: "Custom path file path",
 | 
								Usage: "Custom path file path",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "config, c",
 | 
								Name:  "config, c",
 | 
				
			||||||
			Value: setting.CustomConf,
 | 
								Value: setting.CustomConf,
 | 
				
			||||||
			Usage: "Custom configuration file path",
 | 
								Usage: "Custom configuration file path",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "work-path, w",
 | 
								Name:  "work-path, w",
 | 
				
			||||||
			Value: setting.AppWorkPath,
 | 
								Value: setting.AppWorkPath,
 | 
				
			||||||
			Usage: "Set the gitea working path",
 | 
								Usage: "Set the gitea working path",
 | 
				
			||||||
		},
 | 
							},
 | 
				
			||||||
		cli.StringFlag{
 | 
							&cli.StringFlag{
 | 
				
			||||||
			Name:  "out, o",
 | 
								Name:  "out, o",
 | 
				
			||||||
			Value: "",
 | 
								Value: "",
 | 
				
			||||||
			Usage: "Destination file to write to",
 | 
								Usage: "Destination file to write to",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -12,7 +12,7 @@
 | 
				
			|||||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
					;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
				
			||||||
;;
 | 
					;;
 | 
				
			||||||
;; These values are environment-dependent but form the basis of a lot of values. They will be
 | 
					;; These values are environment-dependent but form the basis of a lot of values. They will be
 | 
				
			||||||
;; reported as part of the default configuration when running `gitea --help` or on start-up. The order they are emitted there is slightly different but we will list them here in the order they are set-up.
 | 
					;; reported as part of the default configuration when running `gitea help` or on start-up. The order they are emitted there is slightly different but we will list them here in the order they are set-up.
 | 
				
			||||||
;;
 | 
					;;
 | 
				
			||||||
;; - _`AppPath`_: This is the absolute path of the running gitea binary.
 | 
					;; - _`AppPath`_: This is the absolute path of the running gitea binary.
 | 
				
			||||||
;; - _`AppWorkPath`_: This refers to "working path" of the `gitea` binary. It is determined by using the first set thing in the following hierarchy:
 | 
					;; - _`AppWorkPath`_: This refers to "working path" of the `gitea` binary. It is determined by using the first set thing in the following hierarchy:
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -40,7 +40,7 @@ Values containing `#` or `;` must be quoted using `` ` `` or `"""`.
 | 
				
			|||||||
## Default Configuration (non-`app.ini` configuration)
 | 
					## Default Configuration (non-`app.ini` configuration)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
These values are environment-dependent but form the basis of a lot of values. They will be
 | 
					These values are environment-dependent but form the basis of a lot of values. They will be
 | 
				
			||||||
reported as part of the default configuration when running `gitea --help` or on start-up. The order they are emitted there is slightly different but we will list them here in the order they are set-up.
 | 
					reported as part of the default configuration when running `gitea help` or on start-up. The order they are emitted there is slightly different but we will list them here in the order they are set-up.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
- _`AppPath`_: This is the absolute path of the running gitea binary.
 | 
					- _`AppPath`_: This is the absolute path of the running gitea binary.
 | 
				
			||||||
- _`AppWorkPath`_: This refers to "working path" of the `gitea` binary. It is determined by using the first set thing in the following hierarchy:
 | 
					- _`AppWorkPath`_: This refers to "working path" of the `gitea` binary. It is determined by using the first set thing in the following hierarchy:
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										3
									
								
								go.mod
									
									
									
									
									
								
							
							
						
						
									
										3
									
								
								go.mod
									
									
									
									
									
								
							@@ -98,7 +98,7 @@ require (
 | 
				
			|||||||
	github.com/syndtr/goleveldb v1.0.0
 | 
						github.com/syndtr/goleveldb v1.0.0
 | 
				
			||||||
	github.com/tstranex/u2f v1.0.0
 | 
						github.com/tstranex/u2f v1.0.0
 | 
				
			||||||
	github.com/ulikunitz/xz v0.5.11
 | 
						github.com/ulikunitz/xz v0.5.11
 | 
				
			||||||
	github.com/urfave/cli v1.22.14
 | 
						github.com/urfave/cli/v2 v2.25.7
 | 
				
			||||||
	github.com/xanzy/go-gitlab v0.86.0
 | 
						github.com/xanzy/go-gitlab v0.86.0
 | 
				
			||||||
	github.com/xeipuuv/gojsonschema v1.2.0
 | 
						github.com/xeipuuv/gojsonschema v1.2.0
 | 
				
			||||||
	github.com/yohcop/openid-go v1.0.1
 | 
						github.com/yohcop/openid-go v1.0.1
 | 
				
			||||||
@@ -278,6 +278,7 @@ require (
 | 
				
			|||||||
	github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
 | 
						github.com/xeipuuv/gojsonpointer v0.0.0-20190905194746-02993c407bfb // indirect
 | 
				
			||||||
	github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
 | 
						github.com/xeipuuv/gojsonreference v0.0.0-20180127040603-bd5ef7bd5415 // indirect
 | 
				
			||||||
	github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
 | 
						github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 // indirect
 | 
				
			||||||
 | 
						github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
 | 
				
			||||||
	github.com/zeebo/blake3 v0.2.3 // indirect
 | 
						github.com/zeebo/blake3 v0.2.3 // indirect
 | 
				
			||||||
	go.etcd.io/bbolt v1.3.7 // indirect
 | 
						go.etcd.io/bbolt v1.3.7 // indirect
 | 
				
			||||||
	go.mongodb.org/mongo-driver v1.12.0 // indirect
 | 
						go.mongodb.org/mongo-driver v1.12.0 // indirect
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										7
									
								
								go.sum
									
									
									
									
									
								
							
							
						
						
									
										7
									
								
								go.sum
									
									
									
									
									
								
							@@ -80,7 +80,6 @@ github.com/Azure/azure-sdk-for-go/sdk/internal v0.7.0/go.mod h1:yqy467j36fJxcRV2
 | 
				
			|||||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=
 | 
					github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358 h1:mFRzDkZVAjdal+s7s0MwaRv9igoPqLRdzOLzw/8Xvq8=
 | 
				
			||||||
github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
 | 
					github.com/Azure/go-ntlmssp v0.0.0-20221128193559-754e69321358/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU=
 | 
				
			||||||
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 | 
					github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
 | 
				
			||||||
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
 | 
					 | 
				
			||||||
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 | 
					github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
 | 
				
			||||||
github.com/ClickHouse/ch-go v0.57.0 h1:X/QmUmFhpUvLgPSQb7fWOSi1wvqGn6tJ7w2a59c4xsg=
 | 
					github.com/ClickHouse/ch-go v0.57.0 h1:X/QmUmFhpUvLgPSQb7fWOSi1wvqGn6tJ7w2a59c4xsg=
 | 
				
			||||||
github.com/ClickHouse/ch-go v0.57.0/go.mod h1:DR3iBn7OrrDj+KeUp1LbdxLEUDbW+5Qwdl/qkc+PQ+Y=
 | 
					github.com/ClickHouse/ch-go v0.57.0/go.mod h1:DR3iBn7OrrDj+KeUp1LbdxLEUDbW+5Qwdl/qkc+PQ+Y=
 | 
				
			||||||
@@ -1162,8 +1161,8 @@ github.com/unknwon/com v1.0.1 h1:3d1LTxD+Lnf3soQiD4Cp/0BRB+Rsa/+RTvz8GMMzIXs=
 | 
				
			|||||||
github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
 | 
					github.com/unknwon/com v1.0.1/go.mod h1:tOOxU81rwgoCLoOVVPHb6T/wt8HZygqH5id+GNnlCXM=
 | 
				
			||||||
github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 | 
					github.com/urfave/cli v1.20.0/go.mod h1:70zkFmudgCuE/ngEzBv17Jvp/497gISqfk5gWijbERA=
 | 
				
			||||||
github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 | 
					github.com/urfave/cli v1.22.1/go.mod h1:Gos4lmkARVdJ6EkW0WaNv/tZAAMe9V7XWyB60NtXRu0=
 | 
				
			||||||
github.com/urfave/cli v1.22.14 h1:ebbhrRiGK2i4naQJr+1Xj92HXZCrK7MsyTS/ob3HnAk=
 | 
					github.com/urfave/cli/v2 v2.25.7 h1:VAzn5oq403l5pHjc4OhD54+XGO9cdKVL/7lDjF+iKUs=
 | 
				
			||||||
github.com/urfave/cli v1.22.14/go.mod h1:X0eDS6pD6Exaclxm99NJ3FiCDRED7vIHpx2mDOHLvkA=
 | 
					github.com/urfave/cli/v2 v2.25.7/go.mod h1:8qnjx1vcq5s2/wpsqoZFndg2CE5tNFyrTvS6SinrnYQ=
 | 
				
			||||||
github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 | 
					github.com/valyala/bytebufferpool v1.0.0 h1:GqA5TC/0021Y/b9FG4Oi9Mr3q7XYx6KllzawFIhcdPw=
 | 
				
			||||||
github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
 | 
					github.com/valyala/bytebufferpool v1.0.0/go.mod h1:6bBcMArwyJ5K/AmCkWv1jt77kVWyCJ6HpOuEn7z0Csc=
 | 
				
			||||||
github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
 | 
					github.com/valyala/fasthttp v1.37.1-0.20220607072126-8a320890c08d/go.mod h1:t/G+3rLek+CyY9bnIE+YlMRddxVAAGjhxndDB4i4C0I=
 | 
				
			||||||
@@ -1198,6 +1197,8 @@ github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8 h1:nIPpBwaJSVYIxUFsDv3M8ofm
 | 
				
			|||||||
github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
 | 
					github.com/xi2/xz v0.0.0-20171230120015-48954b6210f8/go.mod h1:HUYIGzjTL3rfEspMxjDjgmT5uz5wzYJKVo23qUhYTos=
 | 
				
			||||||
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 | 
					github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
 | 
				
			||||||
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
 | 
					github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
 | 
				
			||||||
 | 
					github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
 | 
				
			||||||
 | 
					github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673/go.mod h1:N3UwUGtsrSj3ccvlPHLoLsHnpR27oXr4ZE984MbSER8=
 | 
				
			||||||
github.com/yohcop/openid-go v1.0.1 h1:DPRd3iPO5F6O5zX2e62XpVAbPT6wV51cuucH0z9g3js=
 | 
					github.com/yohcop/openid-go v1.0.1 h1:DPRd3iPO5F6O5zX2e62XpVAbPT6wV51cuucH0z9g3js=
 | 
				
			||||||
github.com/yohcop/openid-go v1.0.1/go.mod h1:b/AvD03P0KHj4yuihb+VtLD6bYYgsy0zqBzPCRjkCNs=
 | 
					github.com/yohcop/openid-go v1.0.1/go.mod h1:b/AvD03P0KHj4yuihb+VtLD6bYYgsy0zqBzPCRjkCNs=
 | 
				
			||||||
github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
 | 
					github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										154
									
								
								main.go
									
									
									
									
									
								
							
							
						
						
									
										154
									
								
								main.go
									
									
									
									
									
								
							@@ -2,8 +2,7 @@
 | 
				
			|||||||
// Copyright 2016 The Gitea Authors. All rights reserved.
 | 
					// Copyright 2016 The Gitea Authors. All rights reserved.
 | 
				
			||||||
// SPDX-License-Identifier: MIT
 | 
					// SPDX-License-Identifier: MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// Gitea (git with a cup of tea) is a painless self-hosted Git Service.
 | 
					package main
 | 
				
			||||||
package main // import "code.gitea.io/gitea"
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
@@ -22,17 +21,13 @@ import (
 | 
				
			|||||||
	_ "code.gitea.io/gitea/modules/markup/csv"
 | 
						_ "code.gitea.io/gitea/modules/markup/csv"
 | 
				
			||||||
	_ "code.gitea.io/gitea/modules/markup/markdown"
 | 
						_ "code.gitea.io/gitea/modules/markup/markdown"
 | 
				
			||||||
	_ "code.gitea.io/gitea/modules/markup/orgmode"
 | 
						_ "code.gitea.io/gitea/modules/markup/orgmode"
 | 
				
			||||||
 | 
					 | 
				
			||||||
	"github.com/urfave/cli"
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// these flags will be set by the build flags
 | 
				
			||||||
var (
 | 
					var (
 | 
				
			||||||
	// Version holds the current Gitea version
 | 
						Version     = "development" // program version for this build
 | 
				
			||||||
	Version = "development"
 | 
						Tags        = ""            // the Golang build tags
 | 
				
			||||||
	// Tags holds the build tags used
 | 
						MakeVersion = ""            // "make" program version if built with make
 | 
				
			||||||
	Tags = ""
 | 
					 | 
				
			||||||
	// MakeVersion holds the current Make version if built with make
 | 
					 | 
				
			||||||
	MakeVersion = ""
 | 
					 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func init() {
 | 
					func init() {
 | 
				
			||||||
@@ -41,110 +36,12 @@ func init() {
 | 
				
			|||||||
	setting.AppStartTime = time.Now().UTC()
 | 
						setting.AppStartTime = time.Now().UTC()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// cmdHelp is our own help subcommand with more information
 | 
					 | 
				
			||||||
// test cases:
 | 
					 | 
				
			||||||
// ./gitea help
 | 
					 | 
				
			||||||
// ./gitea -h
 | 
					 | 
				
			||||||
// ./gitea web help
 | 
					 | 
				
			||||||
// ./gitea web -h (due to cli lib limitation, this won't call our cmdHelp, so no extra info)
 | 
					 | 
				
			||||||
// ./gitea admin
 | 
					 | 
				
			||||||
// ./gitea admin help
 | 
					 | 
				
			||||||
// ./gitea admin auth help
 | 
					 | 
				
			||||||
// ./gitea -c /tmp/app.ini -h
 | 
					 | 
				
			||||||
// ./gitea -c /tmp/app.ini help
 | 
					 | 
				
			||||||
// ./gitea help -c /tmp/app.ini
 | 
					 | 
				
			||||||
// GITEA_WORK_DIR=/tmp ./gitea help
 | 
					 | 
				
			||||||
// GITEA_WORK_DIR=/tmp ./gitea help --work-path /tmp/other
 | 
					 | 
				
			||||||
// GITEA_WORK_DIR=/tmp ./gitea help --config /tmp/app-other.ini
 | 
					 | 
				
			||||||
var cmdHelp = cli.Command{
 | 
					 | 
				
			||||||
	Name:      "help",
 | 
					 | 
				
			||||||
	Aliases:   []string{"h"},
 | 
					 | 
				
			||||||
	Usage:     "Shows a list of commands or help for one command",
 | 
					 | 
				
			||||||
	ArgsUsage: "[command]",
 | 
					 | 
				
			||||||
	Action: func(c *cli.Context) (err error) {
 | 
					 | 
				
			||||||
		args := c.Args()
 | 
					 | 
				
			||||||
		if args.Present() {
 | 
					 | 
				
			||||||
			err = cli.ShowCommandHelp(c, args.First())
 | 
					 | 
				
			||||||
		} else {
 | 
					 | 
				
			||||||
			err = cli.ShowAppHelp(c)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		_, _ = fmt.Fprintf(c.App.Writer, `
 | 
					 | 
				
			||||||
DEFAULT CONFIGURATION:
 | 
					 | 
				
			||||||
   AppPath:    %s
 | 
					 | 
				
			||||||
   WorkPath:   %s
 | 
					 | 
				
			||||||
   CustomPath: %s
 | 
					 | 
				
			||||||
   ConfigFile: %s
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
`, setting.AppPath, setting.AppWorkPath, setting.CustomPath, setting.CustomConf)
 | 
					 | 
				
			||||||
		return err
 | 
					 | 
				
			||||||
	},
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	app := cli.NewApp()
 | 
						app := cmd.NewMainApp()
 | 
				
			||||||
	app.Name = "Gitea"
 | 
						app.Name = "Gitea"
 | 
				
			||||||
	app.Usage = "A painless self-hosted Git service"
 | 
						app.Usage = "A painless self-hosted Git service"
 | 
				
			||||||
	app.Description = `By default, Gitea will start serving using the web-server with no argument, which can alternatively be run by running the subcommand "web".`
 | 
						app.Description = `By default, Gitea will start serving using the web-server with no argument, which can alternatively be run by running the subcommand "web".`
 | 
				
			||||||
	app.Version = Version + formatBuiltWith()
 | 
						app.Version = Version + formatBuiltWith()
 | 
				
			||||||
	app.EnableBashCompletion = true
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// these sub-commands need to use config file
 | 
					 | 
				
			||||||
	subCmdWithIni := []cli.Command{
 | 
					 | 
				
			||||||
		cmd.CmdWeb,
 | 
					 | 
				
			||||||
		cmd.CmdServ,
 | 
					 | 
				
			||||||
		cmd.CmdHook,
 | 
					 | 
				
			||||||
		cmd.CmdDump,
 | 
					 | 
				
			||||||
		cmd.CmdAdmin,
 | 
					 | 
				
			||||||
		cmd.CmdMigrate,
 | 
					 | 
				
			||||||
		cmd.CmdKeys,
 | 
					 | 
				
			||||||
		cmd.CmdConvert,
 | 
					 | 
				
			||||||
		cmd.CmdDoctor,
 | 
					 | 
				
			||||||
		cmd.CmdManager,
 | 
					 | 
				
			||||||
		cmd.CmdEmbedded,
 | 
					 | 
				
			||||||
		cmd.CmdMigrateStorage,
 | 
					 | 
				
			||||||
		cmd.CmdDumpRepository,
 | 
					 | 
				
			||||||
		cmd.CmdRestoreRepository,
 | 
					 | 
				
			||||||
		cmd.CmdActions,
 | 
					 | 
				
			||||||
		cmdHelp, // TODO: the "help" sub-command was used to show the more information for "work path" and "custom config", in the future, it should avoid doing so
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	// these sub-commands do not need the config file, and they do not depend on any path or environment variable.
 | 
					 | 
				
			||||||
	subCmdStandalone := []cli.Command{
 | 
					 | 
				
			||||||
		cmd.CmdCert,
 | 
					 | 
				
			||||||
		cmd.CmdGenerate,
 | 
					 | 
				
			||||||
		cmd.CmdDocs,
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// shared configuration flags, they are for global and for each sub-command at the same time
 | 
					 | 
				
			||||||
	// eg: such command is valid: "./gitea --config /tmp/app.ini web --config /tmp/app.ini", while it's discouraged indeed
 | 
					 | 
				
			||||||
	// keep in mind that the short flags like "-C", "-c" and "-w" are globally polluted, they can't be used for sub-commands anymore.
 | 
					 | 
				
			||||||
	globalFlags := []cli.Flag{
 | 
					 | 
				
			||||||
		cli.HelpFlag,
 | 
					 | 
				
			||||||
		cli.StringFlag{
 | 
					 | 
				
			||||||
			Name:  "custom-path, C",
 | 
					 | 
				
			||||||
			Usage: "Set custom path (defaults to '{WorkPath}/custom')",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		cli.StringFlag{
 | 
					 | 
				
			||||||
			Name:  "config, c",
 | 
					 | 
				
			||||||
			Value: setting.CustomConf,
 | 
					 | 
				
			||||||
			Usage: "Set custom config file (defaults to '{WorkPath}/custom/conf/app.ini')",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
		cli.StringFlag{
 | 
					 | 
				
			||||||
			Name:  "work-path, w",
 | 
					 | 
				
			||||||
			Usage: "Set Gitea's working path (defaults to the Gitea's binary directory)",
 | 
					 | 
				
			||||||
		},
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	// Set the default to be equivalent to cmdWeb and add the default flags
 | 
					 | 
				
			||||||
	app.Flags = append(app.Flags, globalFlags...)
 | 
					 | 
				
			||||||
	app.Flags = append(app.Flags, cmd.CmdWeb.Flags...) // TODO: the web flags polluted the global flags, they are not really global flags
 | 
					 | 
				
			||||||
	app.Action = prepareWorkPathAndCustomConf(cmd.CmdWeb.Action)
 | 
					 | 
				
			||||||
	app.HideHelp = true // use our own help action to show helps (with more information like default config)
 | 
					 | 
				
			||||||
	app.Before = cmd.PrepareConsoleLoggerLevel(log.INFO)
 | 
					 | 
				
			||||||
	for i := range subCmdWithIni {
 | 
					 | 
				
			||||||
		prepareSubcommands(&subCmdWithIni[i], globalFlags)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	app.Commands = append(app.Commands, subCmdWithIni...)
 | 
					 | 
				
			||||||
	app.Commands = append(app.Commands, subCmdStandalone...)
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
	err := app.Run(os.Args)
 | 
						err := app.Run(os.Args)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
@@ -154,45 +51,6 @@ func main() {
 | 
				
			|||||||
	log.GetManager().Close()
 | 
						log.GetManager().Close()
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func prepareSubcommands(command *cli.Command, defaultFlags []cli.Flag) {
 | 
					 | 
				
			||||||
	command.Flags = append(command.Flags, defaultFlags...)
 | 
					 | 
				
			||||||
	command.Action = prepareWorkPathAndCustomConf(command.Action)
 | 
					 | 
				
			||||||
	command.HideHelp = true
 | 
					 | 
				
			||||||
	if command.Name != "help" {
 | 
					 | 
				
			||||||
		command.Subcommands = append(command.Subcommands, cmdHelp)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
	for i := range command.Subcommands {
 | 
					 | 
				
			||||||
		prepareSubcommands(&command.Subcommands[i], defaultFlags)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
// prepareWorkPathAndCustomConf wraps the Action to prepare the work path and custom config
 | 
					 | 
				
			||||||
// It can't use "Before", because each level's sub-command's Before will be called one by one, so the "init" would be done multiple times
 | 
					 | 
				
			||||||
func prepareWorkPathAndCustomConf(action any) func(ctx *cli.Context) error {
 | 
					 | 
				
			||||||
	return func(ctx *cli.Context) error {
 | 
					 | 
				
			||||||
		var args setting.ArgWorkPathAndCustomConf
 | 
					 | 
				
			||||||
		curCtx := ctx
 | 
					 | 
				
			||||||
		for curCtx != nil {
 | 
					 | 
				
			||||||
			if curCtx.IsSet("work-path") && args.WorkPath == "" {
 | 
					 | 
				
			||||||
				args.WorkPath = curCtx.String("work-path")
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if curCtx.IsSet("custom-path") && args.CustomPath == "" {
 | 
					 | 
				
			||||||
				args.CustomPath = curCtx.String("custom-path")
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			if curCtx.IsSet("config") && args.CustomConf == "" {
 | 
					 | 
				
			||||||
				args.CustomConf = curCtx.String("config")
 | 
					 | 
				
			||||||
			}
 | 
					 | 
				
			||||||
			curCtx = curCtx.Parent()
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		setting.InitWorkPathAndCommonConfig(os.Getenv, args)
 | 
					 | 
				
			||||||
		if ctx.Bool("help") || action == nil {
 | 
					 | 
				
			||||||
			// the default behavior of "urfave/cli": "nil action" means "show help"
 | 
					 | 
				
			||||||
			return cmdHelp.Action.(func(ctx *cli.Context) error)(ctx)
 | 
					 | 
				
			||||||
		}
 | 
					 | 
				
			||||||
		return action.(func(*cli.Context) error)(ctx)
 | 
					 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
func formatBuiltWith() string {
 | 
					func formatBuiltWith() string {
 | 
				
			||||||
	version := runtime.Version()
 | 
						version := runtime.Version()
 | 
				
			||||||
	if len(MakeVersion) > 0 {
 | 
						if len(MakeVersion) > 0 {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -5,17 +5,15 @@ package integration
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"bytes"
 | 
						"bytes"
 | 
				
			||||||
	"flag"
 | 
					 | 
				
			||||||
	"io"
 | 
					 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"os"
 | 
					 | 
				
			||||||
	"testing"
 | 
						"testing"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"code.gitea.io/gitea/cmd"
 | 
						"code.gitea.io/gitea/cmd"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/setting"
 | 
						"code.gitea.io/gitea/modules/setting"
 | 
				
			||||||
	"code.gitea.io/gitea/modules/util"
 | 
						"code.gitea.io/gitea/modules/util"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/urfave/cli"
 | 
						"github.com/stretchr/testify/assert"
 | 
				
			||||||
 | 
						"github.com/urfave/cli/v2"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func Test_CmdKeys(t *testing.T) {
 | 
					func Test_CmdKeys(t *testing.T) {
 | 
				
			||||||
@@ -38,26 +36,18 @@ func Test_CmdKeys(t *testing.T) {
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
		for _, tt := range tests {
 | 
							for _, tt := range tests {
 | 
				
			||||||
			t.Run(tt.name, func(t *testing.T) {
 | 
								t.Run(tt.name, func(t *testing.T) {
 | 
				
			||||||
				realStdout := os.Stdout // Backup Stdout
 | 
									out := new(bytes.Buffer)
 | 
				
			||||||
				r, w, _ := os.Pipe()
 | 
									app := cli.NewApp()
 | 
				
			||||||
				os.Stdout = w
 | 
									app.Writer = out
 | 
				
			||||||
 | 
									app.Commands = []*cli.Command{cmd.CmdKeys}
 | 
				
			||||||
				set := flag.NewFlagSet("keys", 0)
 | 
									cmd.CmdKeys.HideHelp = true
 | 
				
			||||||
				_ = set.Parse(tt.args)
 | 
									err := app.Run(append([]string{"prog"}, tt.args...))
 | 
				
			||||||
				context := cli.NewContext(&cli.App{Writer: os.Stdout}, set, nil)
 | 
									if tt.wantErr {
 | 
				
			||||||
				err := cmd.CmdKeys.Run(context)
 | 
										assert.Error(t, err)
 | 
				
			||||||
				if (err != nil) != tt.wantErr {
 | 
									} else {
 | 
				
			||||||
					t.Errorf("CmdKeys.Run() error = %v, wantErr %v", err, tt.wantErr)
 | 
										assert.NoError(t, err)
 | 
				
			||||||
				}
 | 
									}
 | 
				
			||||||
				w.Close()
 | 
									assert.Equal(t, tt.expectedOutput, out.String())
 | 
				
			||||||
				var buf bytes.Buffer
 | 
					 | 
				
			||||||
				io.Copy(&buf, r)
 | 
					 | 
				
			||||||
				commandOutput := buf.String()
 | 
					 | 
				
			||||||
				if tt.expectedOutput != commandOutput {
 | 
					 | 
				
			||||||
					t.Errorf("expectedOutput: %#v, commandOutput: %#v", tt.expectedOutput, commandOutput)
 | 
					 | 
				
			||||||
				}
 | 
					 | 
				
			||||||
				// Restore stdout
 | 
					 | 
				
			||||||
				os.Stdout = realStdout
 | 
					 | 
				
			||||||
			})
 | 
								})
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
	})
 | 
						})
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user