mvdan.cc/goreduce@v0.0.0-20240319135341-50b0d7f2497f/main.go (about)

     1  // Copyright (c) 2017, Daniel Martí <mvdan@mvdan.cc>
     2  // See LICENSE for licensing information
     3  
     4  package main
     5  
     6  import (
     7  	"flag"
     8  	"fmt"
     9  	"os"
    10  )
    11  
    12  var (
    13  	matchStr = flag.String("match", "", "regexp to match the output")
    14  	shellStr = flag.String("run", "", "shell command to test reductions")
    15  	verbose  = flag.Bool("v", false, "log applied changes to stderr")
    16  
    17  	shellStrBuild = `go build -ldflags "-w -s"`
    18  	shellStrRun   = `go build -ldflags "-w -s" -o out && ./out`
    19  )
    20  
    21  func init() {
    22  	flag.Usage = func() {
    23  		fmt.Fprintf(os.Stderr,
    24  			"Usage: goreduce -match=re [-run=cmd] dir\n")
    25  		flag.PrintDefaults()
    26  		fmt.Fprintf(os.Stderr, `
    27  If -run=cmd is omitted, the default for non-main packages is:
    28  
    29    `+shellStrBuild+`
    30  
    31  And for main packages:
    32  
    33    `+shellStrRun+`
    34  
    35  The shell code is run in a Bash-compatible shell interpreter. The
    36  package being reduced will be in its current directory.
    37  
    38  To catch a run-time error/crash entering main:
    39  
    40    goreduce -match 'index out of range' .
    41  
    42  To catch a build error/crash with custom build flags:
    43  
    44    goreduce -match 'internal compiler error' -run 'go build -gcflags "-c=2"' .
    45  
    46  Note that you may also call a script or any other program.
    47  `)
    48  	}
    49  }
    50  
    51  func main() {
    52  	flag.Parse()
    53  	args := flag.Args()
    54  	if len(args) != 1 || *matchStr == "" {
    55  		flag.Usage()
    56  		os.Exit(2)
    57  	}
    58  	if err := reduce(args[0], *matchStr, os.Stderr, *shellStr); err != nil {
    59  		fmt.Fprintln(os.Stderr, err)
    60  		os.Exit(1)
    61  	}
    62  }