go.tools/cover: validate flags with appropriate error messages

Fixes golang/go#6444.

R=golang-dev, r
CC=golang-dev
https://golang.org/cl/13956043
This commit is contained in:
Nathan John Youngman 2013-09-26 18:11:03 +10:00 committed by Rob Pike
parent 785cfaa938
commit cb07517a77
1 changed files with 54 additions and 33 deletions

View File

@ -67,7 +67,7 @@ var (
funcOut = flag.String("func", "", "output coverage profile information for each function") funcOut = flag.String("func", "", "output coverage profile information for each function")
) )
var profile string // The profile to read; the value of -html but stored separately for future flexibility. var profile string // The profile to read; the value of -html or -func
var counterStmt func(*File, ast.Expr) ast.Stmt var counterStmt func(*File, ast.Expr) ast.Stmt
@ -80,52 +80,73 @@ func main() {
flag.Usage = usage flag.Usage = usage
flag.Parse() flag.Parse()
// Usage information when no arguments.
if flag.NFlag() == 0 && flag.NArg() == 0 {
flag.Usage()
}
err := parseFlags()
if err != nil {
fmt.Fprintln(os.Stderr, err)
fmt.Fprintln(os.Stderr, `For usage information, run "go tool cover -help"`)
os.Exit(2)
}
// Generate coverage-annotated source.
if *mode != "" {
cover(flag.Arg(0))
return
}
// Output HTML or function coverage information.
if *htmlOut != "" {
err = htmlOutput(profile, *output)
} else {
err = funcOutput(profile, *output)
}
if err != nil {
fmt.Fprintf(os.Stderr, "cover: %v\n", err)
os.Exit(2)
}
}
// parseFlags sets the profile and counterStmt globals and performs validations.
func parseFlags() error {
profile = *htmlOut profile = *htmlOut
if *funcOut != "" { if *funcOut != "" {
if profile != "" { if profile != "" {
flag.Usage() return fmt.Errorf("too many options")
} }
profile = *funcOut profile = *funcOut
} }
// Must either display a profile or rewrite Go source. // Must either display a profile or rewrite Go source.
if (profile == "") == (*mode == "") { if (profile == "") == (*mode == "") {
flag.Usage() return fmt.Errorf("too many options")
} }
// Generate HTML or function coverage information. if *mode != "" {
if profile != "" { switch *mode {
if flag.NArg() != 0 { case "set":
flag.Usage() counterStmt = setCounterStmt
case "count":
counterStmt = incCounterStmt
case "atomic":
counterStmt = atomicCounterStmt
default:
return fmt.Errorf("unknown -mode %v", *mode)
} }
var err error
if *htmlOut != "" {
err = htmlOutput(profile, *output)
} else {
err = funcOutput(profile, *output)
}
if err != nil {
fmt.Fprintf(os.Stderr, "cover: %v\n", err)
os.Exit(2)
}
return
}
// Generate coverage-annotated source. if flag.NArg() == 0 {
switch *mode { return fmt.Errorf("missing source file")
case "set": } else if flag.NArg() == 1 {
counterStmt = setCounterStmt return nil
case "count": }
counterStmt = incCounterStmt } else if flag.NArg() == 0 {
case "atomic": return nil
counterStmt = atomicCounterStmt
default:
flag.Usage()
} }
if flag.NArg() != 1 { return fmt.Errorf("too many arguments")
flag.Usage()
}
cover(flag.Arg(0))
} }
// Block represents the information about a basic block to be recorded in the analysis. // Block represents the information about a basic block to be recorded in the analysis.