github.com/wawandco/ox@v0.13.6-0.20230809142027-913b3d837f2a/plugins/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/ox/internal/info" 10 "github.com/wawandco/ox/plugins/core" 11 ) 12 13 var ( 14 // These are the interfaces we know that this 15 // plugin must satisfy for its correct functionality 16 _ core.Plugin = (*Builder)(nil) 17 _ core.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.Usage = func() {} 51 b.flags.StringVarP(&b.output, "output", "o", "", "the path the binary will be generated at") 52 b.flags.StringSliceVarP(&b.buildTags, "tags", "", []string{}, "tags to pass the go build command") 53 b.flags.BoolVar(&b.static, "static", true, `build a static binary using --ldflags '-linkmode external -extldflags "-static"'`) 54 b.flags.Parse(args) //nolint:errcheck,we don't care hence the flag 55 } 56 57 // ParseFlags 58 func (b *Builder) Flags() *pflag.FlagSet { 59 return b.flags 60 } 61 62 func (g *Builder) composeBuildArgs() ([]string, error) { 63 name, err := info.BuildName() 64 if err != nil { 65 return []string{}, err 66 } 67 68 buildArgs := []string{ 69 "build", 70 } 71 72 //static 73 static := []string{ 74 "--ldflags", 75 "-linkmode external", 76 "--ldflags", 77 `-extldflags "-static"`, 78 } 79 80 if g.static { 81 buildArgs = append(buildArgs, static...) 82 } 83 84 // output 85 o := []string{ 86 "-o", 87 g.binaryOutput(name), 88 } 89 buildArgs = append(buildArgs, o...) 90 91 // add the build tags 92 if len(g.buildTags) != 0 { 93 buildArgs = append(buildArgs, "-tags") 94 buildArgs = append(buildArgs, g.buildTags...) 95 } 96 97 buildArgs = append(buildArgs, "./cmd/"+name) 98 99 return buildArgs, nil 100 } 101 102 // binaryOutput considers the output passed to 103 // use it or default to bin/name. 104 func (g *Builder) binaryOutput(name string) string { 105 output := "bin/" + name 106 if g.output != "" { 107 output = g.output 108 } 109 110 return output 111 }