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 }