github.com/google/capslock@v0.2.3-0.20240517042941-dac19fc347c0/cmd/capslock/capslock.go (about)

     1  // Copyright 2023 Google LLC
     2  //
     3  // Use of this source code is governed by a BSD-style
     4  // license that can be found in the LICENSE file or at
     5  // https://developers.google.com/open-source/licenses/bsd
     6  
     7  // Program capslock loads packages specified in command line arguments,
     8  // and for each function in those packages that has interesting capabilities,
     9  // outputs a string describing this to stdout.
    10  package main
    11  
    12  import (
    13  	"flag"
    14  	"log"
    15  	"os"
    16  	"strings"
    17  
    18  	"github.com/google/capslock/analyzer"
    19  	"github.com/google/capslock/interesting"
    20  	"golang.org/x/tools/go/packages"
    21  )
    22  
    23  var (
    24  	packageList    = flag.String("packages", "", "target patterns to be analysed; allows wildcarding")
    25  	output         = flag.String("output", "", "output mode to use; non-default options are json, m, v, graph, and compare")
    26  	verbose        = flag.Int("v", 0, "verbosity level")
    27  	noiseFlag      = flag.Bool("noisy", false, "include output on unanalyzed function calls (can be noisy)")
    28  	customMap      = flag.String("capability_map", "", "use a custom capability map file")
    29  	disableBuiltin = flag.Bool("disable_builtin", false, "when using a custom capability map, disable the builtin capability mappings")
    30  	buildTags      = flag.String("buildtags", "", "command-separated list of build tags to use when loading packages")
    31  	goos           = flag.String("goos", "", "GOOS value to use when loading packages")
    32  	goarch         = flag.String("goarch", "", "GOARCH value to use when loading packages")
    33  )
    34  
    35  func main() {
    36  	flag.Parse()
    37  	packageNames := strings.Split(*packageList, ",")
    38  	if *disableBuiltin && *customMap == "" {
    39  		log.Fatal("Error: --disable_builtin only makes sense with a --capability_map file specified")
    40  	}
    41  	var classifier *interesting.Classifier
    42  	if *customMap != "" {
    43  		f, err := os.Open(*customMap)
    44  		if err != nil {
    45  			log.Fatal(err)
    46  		}
    47  		classifier, err = interesting.LoadClassifier(*customMap, f, *disableBuiltin)
    48  		if err != nil {
    49  			log.Fatal(err)
    50  		}
    51  		if *noiseFlag {
    52  			classifier = interesting.ClassifierExcludingUnanalyzed(classifier)
    53  		}
    54  		log.Printf("Using custom capability map %q", *customMap)
    55  	} else {
    56  		classifier = analyzer.GetClassifier(*noiseFlag)
    57  	}
    58  
    59  	pkgs, err := analyzer.LoadPackages(packageNames,
    60  		analyzer.LoadConfig{
    61  			BuildTags: *buildTags,
    62  			GOOS:      *goos,
    63  			GOARCH:    *goarch,
    64  		})
    65  	if err != nil {
    66  		log.Fatalf("Error loading packages: %v", err)
    67  	}
    68  	if len(pkgs) == 0 {
    69  		log.Fatalf("No packages matching %v", packageNames)
    70  	}
    71  
    72  	queriedPackages := analyzer.GetQueriedPackages(pkgs)
    73  	if *verbose > 0 {
    74  		for _, p := range pkgs {
    75  			log.Printf("Loaded package %q\n", p.Name)
    76  		}
    77  	}
    78  	if packages.PrintErrors(pkgs) > 0 {
    79  		log.Fatal("Some packages had errors. Aborting analysis.")
    80  	}
    81  	err = analyzer.RunCapslock(flag.Args(), *output, pkgs, queriedPackages, &analyzer.Config{
    82  		Classifier:     classifier,
    83  		DisableBuiltin: *disableBuiltin,
    84  	})
    85  	if err != nil {
    86  		log.Fatal(err)
    87  	}
    88  }