Amit Saha

Practical Go


Скачать книгу

its own package.

      At the top, we are importing the cmd package, which is a sub-package containing the implementation of the sub-commands. Since we will initialize a module for the application, we specify the absolute import path for the cmd package. The main() function calls the handleCommand() function with all of the arguments specified starting from the second argument:

      err := handleCommand(os.Args[1:])

      If the handleCommand() function finds that it has received an empty slice, implying that no command-line arguments were specified, it returns a custom error value:

      if len(args) < 1 { err = errInvalidSubCommand }

      If command-line arguments were specified, a switch..case construct is defined to call the appropriate command handler function based on the first element of the slice, args :

      1 If this element is http or grpc, the appropriate handler function is called.

      2 If the first element is -h or -help, it calls the printUsage() function.

      3 If it matches none of the conditions above, the printUsage() function is called and a custom error value is returned.

      Create a new directory, chap2/sub-cmd-arch, and initialize a module inside it:

      $ mkdir -p chap2/sub-cmd-arch $ cd chap2/sub-cmd-arch $ go mod init github.com/username/chap2/sub-cmd-arch/

      Save Listing 2.2 as main.go in the above directory.

      The HandleHttp() function creates a FlagSet object and configures it with an option, a custom usage, and other error handling.

      Create a new subdirectory, cmd, inside the directory that you created earlier, and save Listing 2.3 as httpCmd.go .

      Save Listing 2.4 as grpcCmd.go in the cmd subdirectory.

      // chap2/sub-cmd-arch/cmd/errors.gopackage cmd import "errors" var ErrNoServerSpecified = errors.New("You have to specify the remote server.")

      In the cmd subdirectory, save Listing 2.5 as errors.go. You will end up with a source tree structure that looks like the following:

      . |____cmd | |____grpcCmd.go | |____httpCmd.go | |____errors.go |____go.mod |____main.go

      From the root directory of the module, build the application:

      $ go build -o application

      Try running the build application with different arguments, starting with -help or -h :

      Before we move on, let's make sure that we have unit tests for the functionality implemented by the main and cmd packages.

      Testing the Main Package

      First, let's write the unit test for the main package. The handleCommand() is the key function that also calls the other functions in the package. It is declared as follows:

      err := handleCommand(w io.Writer, args []string)

      In the test, we will call the