github.com/wawandco/oxpecker@v1.5.7-0.20210910201653-5958d4afdd89/tools/standard/build.go (about) 1 package standard 2 3 import ( 4 "context" 5 "os" 6 "os/exec" 7 8 "github.com/spf13/pflag" 9 "github.com/wawandco/oxpecker/internal/info" 10 "github.com/wawandco/oxpecker/plugins" 11 ) 12 13 var ( 14 // These are the interfaces we know that this 15 // plugin must satisfy for its correct functionality 16 _ plugins.Plugin = (*Builder)(nil) 17 _ plugins.FlagParser = (*Builder)(nil) 18 ) 19 20 type Builder struct { 21 output string 22 buildTags []string 23 static bool 24 flags *pflag.FlagSet 25 } 26 27 func (b Builder) Name() string { 28 return "standard/builder" 29 } 30 31 // Build runs the Go compiler to generate the desired binary. Assuming the 32 // Go executable installed and can be invoked with `go`. 33 func (g *Builder) Build(ctx context.Context, root string, args []string) error { 34 buildArgs, err := g.composeBuildArgs() 35 if err != nil { 36 return err 37 } 38 39 cmd := exec.CommandContext(ctx, "go", buildArgs...) 40 cmd.Stderr = os.Stderr 41 cmd.Stdout = os.Stdout 42 cmd.Stdin = os.Stdin 43 44 return cmd.Run() 45 } 46 47 // ParseFlags 48 func (b *Builder) ParseFlags(args []string) { 49 b.flags = pflag.NewFlagSet(b.Name(), pflag.ContinueOnError) 50 b.flags.StringVarP(&b.output, "output", "o", "", "the path the binary will be generated at") 51 b.flags.StringSliceVarP(&b.buildTags, "tags", "", []string{}, "tags to pass the go build command") 52 b.flags.BoolVar(&b.static, "static", true, `build a static binary using --ldflags '-linkmode external -extldflags "-static"'`) 53 b.flags.Parse(args) //nolint:errcheck,we don't care hence the flag 54 } 55 56 // ParseFlags 57 func (b *Builder) Flags() *pflag.FlagSet { 58 return b.flags 59 } 60 61 func (g *Builder) composeBuildArgs() ([]string, error) { 62 name, err := info.BuildName() 63 if err != nil { 64 return []string{}, err 65 } 66 67 buildArgs := []string{ 68 "build", 69 } 70 71 //static 72 static := []string{ 73 "--ldflags", 74 "-linkmode external", 75 "--ldflags", 76 `-extldflags "-static"`, 77 } 78 79 if g.static { 80 buildArgs = append(buildArgs, static...) 81 } 82 83 // output 84 o := []string{ 85 "-o", 86 g.binaryOutput(name), 87 } 88 buildArgs = append(buildArgs, o...) 89 90 // add the build tags 91 if len(g.buildTags) != 0 { 92 buildArgs = append(buildArgs, "-tags") 93 buildArgs = append(buildArgs, g.buildTags...) 94 } 95 96 buildArgs = append(buildArgs, "./cmd/"+name) 97 98 return buildArgs, nil 99 } 100 101 // binaryOutput considers the output passed to 102 // use it or default to bin/name. 103 func (g *Builder) binaryOutput(name string) string { 104 output := "bin/" + name 105 if g.output != "" { 106 output = g.output 107 } 108 109 return output 110 }