Source file src/cmd/vendor/golang.org/x/tools/go/analysis/internal/analysisflags/help.go

     1  // Copyright 2018 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package analysisflags
     6  
     7  import (
     8  	"flag"
     9  	"fmt"
    10  	"log"
    11  	"os"
    12  	"sort"
    13  	"strings"
    14  
    15  	"golang.org/x/tools/go/analysis"
    16  )
    17  
    18  const help = `PROGNAME is a tool for static analysis of Go programs.
    19  
    20  PROGNAME examines Go source code and reports suspicious constructs,
    21  such as Printf calls whose arguments do not align with the format
    22  string. It uses heuristics that do not guarantee all reports are
    23  genuine problems, but it can find errors not caught by the compilers.
    24  `
    25  
    26  // Help implements the help subcommand for a multichecker or unitchecker
    27  // style command. The optional args specify the analyzers to describe.
    28  // Help calls log.Fatal if no such analyzer exists.
    29  func Help(progname string, analyzers []*analysis.Analyzer, args []string) {
    30  	// No args: show summary of all analyzers.
    31  	if len(args) == 0 {
    32  		fmt.Println(strings.Replace(help, "PROGNAME", progname, -1))
    33  		fmt.Println("Registered analyzers:")
    34  		fmt.Println()
    35  		sort.Slice(analyzers, func(i, j int) bool {
    36  			return analyzers[i].Name < analyzers[j].Name
    37  		})
    38  		for _, a := range analyzers {
    39  			title := strings.Split(a.Doc, "\n\n")[0]
    40  			fmt.Printf("    %-12s %s\n", a.Name, title)
    41  		}
    42  		fmt.Println("\nBy default all analyzers are run.")
    43  		fmt.Println("To select specific analyzers, use the -NAME flag for each one,")
    44  		fmt.Println(" or -NAME=false to run all analyzers not explicitly disabled.")
    45  
    46  		// Show only the core command-line flags.
    47  		fmt.Println("\nCore flags:")
    48  		fmt.Println()
    49  		fs := flag.NewFlagSet("", flag.ExitOnError)
    50  		flag.VisitAll(func(f *flag.Flag) {
    51  			if !strings.Contains(f.Name, ".") {
    52  				fs.Var(f.Value, f.Name, f.Usage)
    53  			}
    54  		})
    55  		fs.SetOutput(os.Stdout)
    56  		fs.PrintDefaults()
    57  
    58  		fmt.Printf("\nTo see details and flags of a specific analyzer, run '%s help name'.\n", progname)
    59  
    60  		return
    61  	}
    62  
    63  	// Show help on specific analyzer(s).
    64  outer:
    65  	for _, arg := range args {
    66  		for _, a := range analyzers {
    67  			if a.Name == arg {
    68  				paras := strings.Split(a.Doc, "\n\n")
    69  				title := paras[0]
    70  				fmt.Printf("%s: %s\n", a.Name, title)
    71  
    72  				// Show only the flags relating to this analysis,
    73  				// properly prefixed.
    74  				first := true
    75  				fs := flag.NewFlagSet(a.Name, flag.ExitOnError)
    76  				a.Flags.VisitAll(func(f *flag.Flag) {
    77  					if first {
    78  						first = false
    79  						fmt.Println("\nAnalyzer flags:")
    80  						fmt.Println()
    81  					}
    82  					fs.Var(f.Value, a.Name+"."+f.Name, f.Usage)
    83  				})
    84  				fs.SetOutput(os.Stdout)
    85  				fs.PrintDefaults()
    86  
    87  				if len(paras) > 1 {
    88  					fmt.Printf("\n%s\n", strings.Join(paras[1:], "\n\n"))
    89  				}
    90  
    91  				continue outer
    92  			}
    93  		}
    94  		log.Fatalf("Analyzer %q not registered", arg)
    95  	}
    96  }
    97  

View as plain text