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

err) os.Exit(1) } err = validateArgs(c) if err != nil { fmt.Fprintln(os.Stdout, err) os.Exit(1) } err = runCmd(os.Stdin, os.Stdout, c) if err != nil { fmt.Fprintln(os.Stdout, err) os.Exit(1) } }

      The config struct type is modified so that it doesn't have the printUsage field since the parseArgs() function now automatically handles the -h or -help argument. Create a new directory, chap1/flag-parse/, and initialize a module inside it:

      Next, save Listing 1.5 to a file called main.go and build it:

      $ go build -o application

      Run the command without specifying any arguments. You will see the following error message:

      $ ./application Must specify a number greater than 0

      Now run the command specifying the -h option:

      $ ./application -h Usage of greeter: -n int Number of times to greet flag: help requested

      The flag parsing logic recognized the -h option and displayed a default usage message consisting of the name that was specified when calling the NewFlagSet() function and the options along with their name, type, and description. The last line of the above output is seen here because when we haven't explicitly defined an -h option, the Parse() function returns an error, which is displayed as part of the error handling logic in main(). In the next section, you will see how we can improve this behavior.

      Next, let's invoke the program specifying a non-integral value for the -n option:

      $ ./application -n abc invalid value "abc" for flag -n: parse error Usage of greeter: -n int Number of times to greet invalid value "abc" for flag -n: parse error

      Note how we automatically get the type validation error since we tried specifying a non-integral value. In addition, note here again that we get the error twice. We will fix this later in the chapter.

      Finally, let's run the program with a valid value for the -n option:

      Testing the Parsing Logic

      The primary change in our greeter program, as compared to the first version, is in how we are parsing the command-line arguments using the flag package. You will notice that you have already written the greeter program, specifically the parseArgs() function, in a unit testing friendly fashion:

      1 A new FlagSet object is created in the function.

      2 Using the Output() method of the FlagSet object , you made sure that any messages from the FlagSet methods were written to the specified io.Writer object, w.

      3 The arguments to parse were being passed as a parameter, args .

      Save Listing 1.6 into the directory in which you saved Listing 1.5. Name the file parse_args_test.go .

      The unit test for the runCmd() function remains the same as that seen in Listing 1.4, except for the absence of the first test, which was used to test the behavior of runCmd() when printUsage was set to true. The test cases we want to test are as follows:

      You can find the complete test in the run_cmd_test.go file in the flag-parse subdirectory of the book's code.

      The test for the validateArgs() function is the same as the one used in Listing 1.3. You can find it in the validate_args_test.go file in the flag-parse subdirectory of the book's code. Now, run all of the tests:

      $ go test -v === RUN TestSetupFlagSet --- PASS: TestSetupFlagSet (0.00s) === RUN TestRunCmd --- PASS: TestRunCmd (0.00s) === RUN TestValidateArgs --- PASS: TestValidateArgs (0.00s) PASS ok github.com/practicalgo/code/chap1/flag-parse 0.610s

      Great. Now you have rewritten the parsing logic of the greeter application to use the flag package and then updated the unit tests so that they test the new behavior. Next, you are going to work on improving the user interface of the application in a few ways. Before doing that, however, let's complete Exercise 1.2.

       EXERCISE 1.2: HTML GREETER PAGE CREATOR In this exercise, you will update the greeter program to create an HTML page, which will serve as the home page for the user. Add a new option, -o , to the application, which will accept the filesystem path as a value. If the -o is specified, the greeter program will create an HTML page at the path specified with the following contents: <h1>Hello Jane Clancy</h1> , where Jane Clancy is the name entered. You may choose to use the html/template package for this exercise.

      In the following sections, you are going to improve the user interface of the greeter application in three ways:

       Remove the duplicate error messages

       Customize the help usage message

       Allow the user to enter their name via a positional argument

      Removing