Читать книгу Practical Go - Amit Saha - Страница 32
Listing 1.1: A greeter application
Оглавление// chap1/manual-parse/main.go package main import ( "bufio" "errors" "fmt" "io" "os" "strconv" ) type config struct { numTimes int printUsage bool } var usageString = fmt.Sprintf(`Usage: %s <integer> [-h|--help] A greeter application which prints the name you entered <integer> number of times. `, os.Args[0]) func printUsage(w io.Writer) { fmt.Fprintf(w, usageString) } func validateArgs(c config) error { if !(c.numTimes> 0) { return errors.New("Must specify a number greater than 0") } return nil } // TODO – Insert definition of parseArgs() as earlier // TODO – Insert definition of getName() as earlier // TODO – Insert definition of greetUser() as earlier // TODO – Insert definition of runCmd() as earlier func main() { c, err := parseArgs(os.Args[1:]) if err != nil { fmt.Fprintln(os.Stdout, err) printUsage(os.Stdout) os.Exit(1) } err = validateArgs(c) if err != nil { fmt.Fprintln(os.Stdout, err) printUsage(os.Stdout) os.Exit(1) } err = runCmd(os.Stdin, os.Stdout, c) if err != nil { fmt.Fprintln(os.Stdout, err) os.Exit(1) } }
The main()
function first calls the parseArgs()
function with the slice of the command-line arguments, starting from the second argument. We get back two values from the function: c
, a config object, and err
, an error value. If a non- nil
error is returned, the following steps are performed:
1 Print the error.
2 Print a usage message by calling the printUsage() function, passing in os.Stdout as the writer.
3 Terminate the program execution with exit code 1 by calling the Exit() function from the os package.
If the arguments have been parsed correctly, the validateArgs()
function is called with the config object, c
, that is returned by parseArgs()
.
Finally, if the validateArgs()
function returned a nil
error value, the runCmd()
function is called, passing it a reader, os.Stdin
; a writer, os.Stdout
; and the config object, c
.
Create a new directory, chap1/manual-parse/
, and initialize a module inside it:
$ mkdir -p chap1/manual-parse $ cd chap1/manual-parse $ go mod init github.com/username/manual-parse
Next, save Listing 1.1 to a file called main.go
, and build it:
$ go build -o application
Run the command without specifying any arguments. You will see an error and the following usage message:
$ ./application Invalid number of arguments Usage: ./application <integer> [-h|--help] A greeter application which prints the name you entered <integer> number of times.
In addition, you will also see that the exit code of the program is 1
.
$ echo $? 1
If you are using PowerShell on Windows, you can use echo $LastExitCode
to see the exit code.
This is another notable behavior of command-line applications that you should look to preserve. Any non-successful execution should result in a non-zero exit code upon termination using the Exit()
function defined in the os
package.
Specifying -h
or -help
will print a usage message:
$ ./application -help Usage: ./application <integer> [-h|-help] A greeter application which prints the name you entered <integer> number of times.
Finally, let's see what a successful execution of the program looks like:
$ ./application 5 Your name please? Press the Enter key when done. Joe Cool Nice to meet you Joe Cool Nice to meet you Joe Cool Nice to meet you Joe Cool Nice to meet you Joe Cool Nice to meet you Joe Cool
You have manually tested that your application behaves as expected under three different input scenarios:
1 No command-line argument specified.
2 -h or -help is specified as a command-line argument.
3 A greeting is displayed to the user a specified number of times.
Manual testing is error prone and cumbersome, however. Next, you will learn to write automated tests for your application.