github.com/bir3/gocompiler@v0.3.205/src/cmd/gocmd/internal/vet/vet.go (about)

     1  // Copyright 2011 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 vet implements the “go vet” command.
     6  package vet
     7  
     8  import (
     9  	"context"
    10  	"fmt"
    11  	"path/filepath"
    12  
    13  	"github.com/bir3/gocompiler/src/cmd/gocmd/internal/base"
    14  	"github.com/bir3/gocompiler/src/cmd/gocmd/internal/cfg"
    15  	"github.com/bir3/gocompiler/src/cmd/gocmd/internal/load"
    16  	"github.com/bir3/gocompiler/src/cmd/gocmd/internal/modload"
    17  	"github.com/bir3/gocompiler/src/cmd/gocmd/internal/trace"
    18  	"github.com/bir3/gocompiler/src/cmd/gocmd/internal/work"
    19  )
    20  
    21  // Break init loop.
    22  func init() {
    23  	CmdVet.Run = runVet
    24  }
    25  
    26  var CmdVet = &base.Command{
    27  	CustomFlags: true,
    28  	UsageLine:   "go vet [-C dir] [-n] [-x] [-vettool prog] [build flags] [vet flags] [packages]",
    29  	Short:       "report likely mistakes in packages",
    30  	Long: `
    31  Vet runs the Go vet command on the packages named by the import paths.
    32  
    33  For more about vet and its flags, see 'go doc cmd/vet'.
    34  For more about specifying packages, see 'go help packages'.
    35  For a list of checkers and their flags, see 'go tool vet help'.
    36  For details of a specific checker such as 'printf', see 'go tool vet help printf'.
    37  
    38  The -C flag changes to dir before running the 'go vet' command.
    39  The -n flag prints commands that would be executed.
    40  The -x flag prints commands as they are executed.
    41  
    42  The -vettool=prog flag selects a different analysis tool with alternative
    43  or additional checks.
    44  For example, the 'shadow' analyzer can be built and run using these commands:
    45  
    46    go install golang.org/x/tools/go/analysis/passes/shadow/cmd/shadow@latest
    47    go vet -vettool=$(which shadow)
    48  
    49  The build flags supported by go vet are those that control package resolution
    50  and execution, such as -n, -x, -v, -tags, and -toolexec.
    51  For more about these flags, see 'go help build'.
    52  
    53  See also: go fmt, go fix.
    54  	`,
    55  }
    56  
    57  func runVet(ctx context.Context, cmd *base.Command, args []string) {
    58  	vetFlags, pkgArgs := vetFlags(args)
    59  	modload.InitWorkfile() // The vet command does custom flag processing; initialize workspaces after that.
    60  
    61  	if cfg.DebugTrace != "" {
    62  		var close func() error
    63  		var err error
    64  		ctx, close, err = trace.Start(ctx, cfg.DebugTrace)
    65  		if err != nil {
    66  			base.Fatalf("failed to start trace: %v", err)
    67  		}
    68  		defer func() {
    69  			if err := close(); err != nil {
    70  				base.Fatalf("failed to stop trace: %v", err)
    71  			}
    72  		}()
    73  	}
    74  
    75  	ctx, span := trace.StartSpan(ctx, fmt.Sprint("Running ", cmd.Name(), " command"))
    76  	defer span.Done()
    77  
    78  	work.BuildInit()
    79  	work.VetFlags = vetFlags
    80  	if len(vetFlags) > 0 {
    81  		work.VetExplicit = true
    82  	}
    83  	if vetTool != "" {
    84  		var err error
    85  		work.VetTool, err = filepath.Abs(vetTool)
    86  		if err != nil {
    87  			base.Fatalf("%v", err)
    88  		}
    89  	}
    90  
    91  	pkgOpts := load.PackageOpts{ModResolveTests: true}
    92  	pkgs := load.PackagesAndErrors(ctx, pkgOpts, pkgArgs)
    93  	load.CheckPackageErrors(pkgs)
    94  	if len(pkgs) == 0 {
    95  		base.Fatalf("no packages to vet")
    96  	}
    97  
    98  	b := work.NewBuilder("")
    99  	defer func() {
   100  		if err := b.Close(); err != nil {
   101  			base.Fatalf("go: %v", err)
   102  		}
   103  	}()
   104  
   105  	root := &work.Action{Mode: "go vet"}
   106  	for _, p := range pkgs {
   107  		_, ptest, pxtest, err := load.TestPackagesFor(ctx, pkgOpts, p, nil)
   108  		if err != nil {
   109  			base.Errorf("%v", err)
   110  			continue
   111  		}
   112  		if len(ptest.GoFiles) == 0 && len(ptest.CgoFiles) == 0 && pxtest == nil {
   113  			base.Errorf("go: can't vet %s: no Go files in %s", p.ImportPath, p.Dir)
   114  			continue
   115  		}
   116  		if len(ptest.GoFiles) > 0 || len(ptest.CgoFiles) > 0 {
   117  			root.Deps = append(root.Deps, b.VetAction(work.ModeBuild, work.ModeBuild, ptest))
   118  		}
   119  		if pxtest != nil {
   120  			root.Deps = append(root.Deps, b.VetAction(work.ModeBuild, work.ModeBuild, pxtest))
   121  		}
   122  	}
   123  	b.Do(ctx, root)
   124  }