Skip to content

add generated completions for shells #34973

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 13 commits into
base: main
Choose a base branch
from
Open
1 change: 1 addition & 0 deletions cmd/hook.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ var (
CmdHook = &cli.Command{
Name: "hook",
Usage: "(internal) Should only be called by Git",
Hidden: true, // internal commands shouldn't be visible
Description: "Delegate commands to corresponding Git hooks",
Before: PrepareConsoleLoggerLevel(log.FATAL),
Commands: []*cli.Command{
Expand Down
1 change: 1 addition & 0 deletions cmd/keys.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ import (
var CmdKeys = &cli.Command{
Name: "keys",
Usage: "(internal) Should only be called by SSH server",
Hidden: true, // internal commands shouldn't not be visible
Description: "Queries the Gitea database to get the authorized command for a given ssh key fingerprint",
Before: PrepareConsoleLoggerLevel(log.FATAL),
Action: runKeys,
Expand Down
112 changes: 44 additions & 68 deletions cmd/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,92 +24,51 @@ func cmdHelp() *cli.Command {
Usage: "Shows a list of commands or help for one command",
ArgsUsage: "[command]",
Action: func(ctx context.Context, c *cli.Command) (err error) {
lineage := c.Lineage() // The order is from child to parent: help, doctor, Gitea
targetCmdIdx := 0
if c.Name == "help" {
targetCmdIdx = 1
}
if lineage[targetCmdIdx] != lineage[targetCmdIdx].Root() {
err = cli.ShowCommandHelp(ctx, lineage[targetCmdIdx+1] /* parent cmd */, lineage[targetCmdIdx].Name /* sub cmd */)
if !c.Args().Present() {
err = cli.ShowAppHelp(c.Root())
} else {
err = cli.ShowAppHelp(c)
err = cli.ShowCommandHelp(ctx, c.Root(), c.Args().First())
}
_, _ = fmt.Fprintf(c.Root().Writer, `
if err == nil {
_, _ = fmt.Fprintf(c.Root().Writer, `
DEFAULT CONFIGURATION:
AppPath: %s
WorkPath: %s
CustomPath: %s
ConfigFile: %s

`, setting.AppPath, setting.AppWorkPath, setting.CustomPath, setting.CustomConf)
}
return err
},
}
return c
}

func appGlobalFlags() []cli.Flag {
return []cli.Flag{
// make the builtin flags at the top
cli.HelpFlag,

// 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 prepareSubcommandWithGlobalFlags(command *cli.Command) {
command.Flags = append(append([]cli.Flag{}, appGlobalFlags()...), command.Flags...)
command.Action = prepareWorkPathAndCustomConf(command.Action)
command.HideHelp = true
if command.Name != "help" {
command.Commands = append(command.Commands, cmdHelp())
}
for i := range command.Commands {
prepareSubcommandWithGlobalFlags(command.Commands[i])
}
command.Before = prepareWorkPathAndCustomConf(command.Before)
}

// 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(context.Context, *cli.Command) error {
return func(ctx context.Context, cmd *cli.Command) error {
func prepareWorkPathAndCustomConf(original cli.BeforeFunc) cli.BeforeFunc {
if original == nil {
original = func(ctx context.Context, c *cli.Command) (context.Context, error) {
return ctx, nil
}
}
return func(ctx context.Context, cmd *cli.Command) (context.Context, error) {
var args setting.ArgWorkPathAndCustomConf
// from children to parent, check the global flags
for _, curCtx := range cmd.Lineage() {
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")
}
if cmd.IsSet("work-path") {
args.WorkPath = cmd.String("work-path")
}
setting.InitWorkPathAndCommonConfig(os.Getenv, args)
if cmd.Bool("help") || action == nil {
// the default behavior of "urfave/cli": "nil action" means "show help"
return cmdHelp().Action(ctx, cmd)
if cmd.IsSet("custom-path") {
args.CustomPath = cmd.String("custom-path")
}
if cmd.IsSet("config") {
args.CustomConf = cmd.String("config")
}
return action(ctx, cmd)
setting.InitWorkPathAndCommonConfig(os.Getenv, args)
return original(ctx, cmd)
}
}

Expand All @@ -125,7 +84,27 @@ func NewMainApp(appVer AppVersion) *cli.Command {
app.Description = `Gitea program contains "web" and other subcommands. If no subcommand is given, it starts the web server by default. Use "web" subcommand for more web server arguments, use other subcommands for other purposes.`
app.Version = appVer.Version + appVer.Extra
app.EnableShellCompletion = true

app.Flags = []cli.Flag{
&cli.StringFlag{
Name: "custom-path",
Aliases: []string{"C"},
TakesFile: true,
Usage: "Set custom path (defaults to '{WorkPath}/custom')",
},
&cli.StringFlag{
Name: "config",
Aliases: []string{"c"},
TakesFile: true,
Value: setting.CustomConf,
Usage: "Set custom config file (defaults to '{WorkPath}/custom/conf/app.ini')",
},
&cli.StringFlag{
Name: "work-path",
Aliases: []string{"w"},
TakesFile: true,
Usage: "Set Gitea's working path (defaults to the Gitea's binary directory)",
},
}
// these sub-commands need to use config file
subCmdWithConfig := []*cli.Command{
cmdHelp(), // the "help" sub-command was used to show the more information for "work path" and "custom config"
Expand Down Expand Up @@ -156,9 +135,6 @@ func NewMainApp(appVer AppVersion) *cli.Command {
// but not sure whether it would break Windows users who used to double-click the EXE to run.
app.DefaultCommand = CmdWeb.Name

app.Flags = append(app.Flags, cli.VersionFlag)
app.Flags = append(app.Flags, appGlobalFlags()...)
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 {
prepareSubcommandWithGlobalFlags(subCmdWithConfig[i])
Expand Down
1 change: 1 addition & 0 deletions cmd/serv.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ var CmdServ = &cli.Command{
Name: "serv",
Usage: "(internal) Should only be called by SSH shell",
Description: "Serv provides access auth for repositories",
Hidden: true, // Internal commands shouldn't be visible in help
Before: PrepareConsoleLoggerLevel(log.FATAL),
Action: runServ,
Flags: []cli.Flag{
Expand Down
17 changes: 0 additions & 17 deletions contrib/autocompletion/README

This file was deleted.

30 changes: 0 additions & 30 deletions contrib/autocompletion/bash_autocomplete

This file was deleted.

30 changes: 0 additions & 30 deletions contrib/autocompletion/zsh_autocomplete

This file was deleted.