diff options
author | wxiaoguang <wxiaoguang@gmail.com> | 2023-07-21 11:28:19 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-07-21 11:28:19 +0200 |
commit | d0dbe52e76f3038777c3b50066e3636105387ca3 (patch) | |
tree | 4c159ed98a365300b6145bde03a06c29dcd21794 /main.go | |
parent | Remove commit status running and warning to align GitHub (#25839) (diff) | |
download | forgejo-d0dbe52e76f3038777c3b50066e3636105387ca3.tar.xz forgejo-d0dbe52e76f3038777c3b50066e3636105387ca3.zip |
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
Diffstat (limited to 'main.go')
-rw-r--r-- | main.go | 154 |
1 files changed, 6 insertions, 148 deletions
@@ -2,8 +2,7 @@ // Copyright 2016 The Gitea Authors. All rights reserved. // SPDX-License-Identifier: MIT -// Gitea (git with a cup of tea) is a painless self-hosted Git Service. -package main // import "code.gitea.io/gitea" +package main import ( "fmt" @@ -22,17 +21,13 @@ import ( _ "code.gitea.io/gitea/modules/markup/csv" _ "code.gitea.io/gitea/modules/markup/markdown" _ "code.gitea.io/gitea/modules/markup/orgmode" - - "github.com/urfave/cli" ) +// these flags will be set by the build flags var ( - // Version holds the current Gitea version - Version = "development" - // Tags holds the build tags used - Tags = "" - // MakeVersion holds the current Make version if built with make - MakeVersion = "" + Version = "development" // program version for this build + Tags = "" // the Golang build tags + MakeVersion = "" // "make" program version if built with make ) func init() { @@ -41,110 +36,12 @@ func init() { 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() { - app := cli.NewApp() + app := cmd.NewMainApp() app.Name = "Gitea" 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.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) if err != nil { @@ -154,45 +51,6 @@ func main() { 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 { version := runtime.Version() if len(MakeVersion) > 0 { |