Introduction

In most scenarios, we manage single or multiple commands using the Command command line object, and the default command line parsing rules (without explicitly using the Parser parser) are sufficient. The Command object is defined as follows:

For detailed information, refer to the interface documentation: https://pkg.go.dev/github.com/gogf/gf/v2/os/gcmd@master#Command

  1. // Command holds the info about an argument that can handle custom logic.
  2. type Command struct {
  3. Name string // Command name(case-sensitive).
  4. Usage string // A brief line description about its usage, eg: gf build main.go [OPTION]
  5. Brief string // A brief info that describes what this command will do.
  6. Description string // A detailed description.
  7. Arguments []Argument // Argument array, configuring how this command act.
  8. Func Function // Custom function.
  9. FuncWithValue FuncWithValue // Custom function with output parameters that can interact with command caller.
  10. HelpFunc Function // Custom help function
  11. Examples string // Usage examples.
  12. Additional string // Additional info about this command, which will be appended to the end of help info.
  13. Strict bool // Strict parsing options, which means it returns error if invalid option given.
  14. Config string // Config node name, which also retrieves the values from config component along with command line.
  15. parent *Command // Parent command for internal usage.
  16. commands []*Command // Sub commands of this command.
  17. }

As each object has detailed comments, we will not elaborate further here.

Callback Methods

The Command object supports 3 callback methods:

  • Func: We usually customize this callback method to implement the command execution operation.
  • FuncWithValue: Method similar to Func, but supports return values, often used in scenarios where command lines call each other. Typically not needed in general projects.
  • HelpFunc: Custom help information. Generally unnecessary, as the Command object can automatically generate help information.

We focus mainly on the Func callback method. Other methods can be explored if interested.

Func Callback

Method definition:

  1. // Function is a custom command callback function that is bound to a certain argument.
  2. type Function func(ctx context.Context, parser *Parser) (err error)

As seen, within the callback method, we use the parser object to obtain parsing parameters and options and return error to inform the upper-level calling method whether the execution was successful.

Example usage:

  1. package main
  2. import (
  3. "context"
  4. "github.com/gogf/gf/v2/frame/g"
  5. "github.com/gogf/gf/v2/net/ghttp"
  6. "github.com/gogf/gf/v2/os/gcmd"
  7. "github.com/gogf/gf/v2/os/gctx"
  8. )
  9. var (
  10. Main = &gcmd.Command{
  11. Name: "main",
  12. Brief: "start http server",
  13. Description: "this is the command entry for starting your http server",
  14. Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
  15. s := g.Server()
  16. s.BindHandler("/", func(r *ghttp.Request) {
  17. r.Response.Write("Hello world")
  18. })
  19. s.SetPort(8199)
  20. s.Run()
  21. return
  22. },
  23. }
  24. )
  25. func main() {
  26. Main.Run(gctx.New())
  27. }

This is what most projects’ command line objects for starting up would look like. Most projects have only one entry point and only one callback method implementation.

Help Information Generation

Although the Command object can customize the HelpFunc help callback method, the Command object can automatically generate Help usage help information. In most scenarios, customization is unnecessary. Moreover, the gcmd component has built-in support for h/help options by default, so programs using the gcmd component can automatically generate Help help information using these two options.

Let’s look at an example. We first build the previous example into a binary main file using go build main.go, and then take a quick look at the automatically generated help information when there is only one command:

  1. $ ./main -h
  2. USAGE
  3. main [OPTION]
  4. DESCRIPTION
  5. this is the command entry for starting your http server

Hierarchical Command Management

Parent Commands and Subcommands

A Command command can add subcommands. When a Command has subcommands, it becomes a parent command. Subcommands can also add their own subcommands, forming a hierarchical command relationship. Both parent commands and subcommands can have their own callback methods, but in most scenarios, once a Command becomes a parent command, callback methods often become unnecessary. We typically add subcommands to a Command using the AddCommand method:

  1. // AddCommand adds one or more sub-commands to current command.
  2. func (c *Command) AddCommand(commands ...*Command) error

Hierarchical Command Usage Example

Let us demonstrate an example of multi-command management. We will improve the previous example by adding two subcommands.

  1. package main
  2. import (
  3. "context"
  4. "fmt"
  5. "github.com/gogf/gf/v2/os/gcmd"
  6. "github.com/gogf/gf/v2/os/gctx"
  7. )
  8. var (
  9. Main = &gcmd.Command{
  10. Name: "main",
  11. Brief: "start http server",
  12. Description: "this is the command entry for starting your process",
  13. }
  14. Http = &gcmd.Command{
  15. Name: "http",
  16. Brief: "start http server",
  17. Description: "this is the command entry for starting your http server",
  18. Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
  19. fmt.Println("start http server")
  20. return
  21. },
  22. }
  23. Grpc = &gcmd.Command{
  24. Name: "grpc",
  25. Brief: "start grpc server",
  26. Description: "this is the command entry for starting your grpc server",
  27. Func: func(ctx context.Context, parser *gcmd.Parser) (err error) {
  28. fmt.Println("start grpc server")
  29. return
  30. },
  31. }
  32. )
  33. func main() {
  34. err := Main.AddCommand(Http, Grpc)
  35. if err != nil {
  36. panic(err)
  37. }
  38. Main.Run(gctx.New())
  39. }

As seen, we use the AddCommand command to add two subcommands http/grpc to the main command, used respectively for starting http/grpc services. When subcommands exist, parent command often has no need for a Func callback definition, so we removed the Func definition of the main command here.

After compilation, let us execute to see the effect:

  1. $ main
  2. USAGE
  3. main COMMAND [OPTION]
  4. COMMAND
  5. http start http server
  6. grpc start grpc server
  7. DESCRIPTION
  8. this is the command entry for starting your process

Using the http command:

  1. $ main http
  2. start http server

Using the grpc command:

  1. $ main grpc
  2. start grpc server