github.com/segakazzz/buffalo@v0.16.22-0.20210119082501-1f52048d3feb/buffalo/cmd/build.go (about) 1 package cmd 2 3 import ( 4 "bytes" 5 "context" 6 "log" 7 "os" 8 "os/exec" 9 "strings" 10 "time" 11 12 "github.com/gobuffalo/buffalo/genny/build" 13 "github.com/gobuffalo/genny/v2" 14 "github.com/gobuffalo/logger" 15 "github.com/gobuffalo/meta" 16 "github.com/markbates/sigtx" 17 "github.com/spf13/cobra" 18 ) 19 20 var buildOptions = struct { 21 *build.Options 22 SkipAssets bool 23 SkipBuildDeps bool 24 Debug bool 25 Tags string 26 SkipTemplateValidation bool 27 DryRun bool 28 Verbose bool 29 bin string 30 }{ 31 Options: &build.Options{ 32 BuildTime: time.Now(), 33 }, 34 } 35 36 var xbuildCmd = &cobra.Command{ 37 Use: "build", 38 Aliases: []string{"b", "bill", "install"}, 39 Short: "Build the application binary, including bundling of assets (packr & webpack)", 40 RunE: func(cmd *cobra.Command, args []string) error { 41 ctx, cancel := sigtx.WithCancel(context.Background(), os.Interrupt) 42 defer cancel() 43 44 pwd, err := os.Getwd() 45 if err != nil { 46 return err 47 } 48 49 buildOptions.App = meta.New(pwd) 50 if len(buildOptions.bin) > 0 { 51 buildOptions.App.Bin = buildOptions.bin 52 } 53 54 buildOptions.Options.WithAssets = !buildOptions.SkipAssets 55 buildOptions.Options.WithBuildDeps = !buildOptions.SkipBuildDeps 56 57 run := genny.WetRunner(ctx) 58 if buildOptions.DryRun { 59 run = genny.DryRunner(ctx) 60 } 61 62 if buildOptions.Verbose || buildOptions.Debug { 63 lg := logger.New(logger.DebugLevel) 64 run.Logger = lg 65 // plog.Logger = lg 66 buildOptions.BuildFlags = append(buildOptions.BuildFlags, "-v") 67 } 68 69 opts := buildOptions.Options 70 opts.BuildVersion = buildVersion(opts.BuildTime.Format(time.RFC3339)) 71 72 if buildOptions.Tags != "" { 73 opts.Tags = append(opts.Tags, buildOptions.Tags) 74 } 75 76 if !buildOptions.SkipTemplateValidation { 77 opts.TemplateValidators = append(opts.TemplateValidators, build.PlushValidator, build.GoTemplateValidator) 78 } 79 80 if cmd.CalledAs() == "install" { 81 opts.GoCommand = "install" 82 } 83 clean := build.Cleanup(opts) 84 // defer clean(run) 85 defer func() { 86 if err := clean(run); err != nil { 87 log.Fatal("build:clean", err) 88 } 89 }() 90 if err := run.WithNew(build.New(opts)); err != nil { 91 return err 92 } 93 return run.Run() 94 }, 95 } 96 97 func init() { 98 RootCmd.AddCommand(xbuildCmd) 99 100 xbuildCmd.Flags().StringVarP(&buildOptions.bin, "output", "o", buildOptions.Bin, "set the name of the binary") 101 xbuildCmd.Flags().StringVarP(&buildOptions.Tags, "tags", "t", "", "compile with specific build tags") 102 xbuildCmd.Flags().BoolVarP(&buildOptions.ExtractAssets, "extract-assets", "e", false, "extract the assets and put them in a distinct archive") 103 xbuildCmd.Flags().BoolVarP(&buildOptions.SkipAssets, "skip-assets", "k", false, "skip running webpack and building assets") 104 xbuildCmd.Flags().BoolVarP(&buildOptions.SkipBuildDeps, "skip-build-deps", "", false, "skip building dependencies") 105 xbuildCmd.Flags().BoolVarP(&buildOptions.Static, "static", "s", false, "build a static binary using --ldflags '-linkmode external -extldflags \"-static\"'") 106 xbuildCmd.Flags().StringVar(&buildOptions.LDFlags, "ldflags", "", "set any ldflags to be passed to the go build") 107 xbuildCmd.Flags().BoolVarP(&buildOptions.Verbose, "verbose", "v", false, "print debugging information") 108 xbuildCmd.Flags().BoolVar(&buildOptions.DryRun, "dry-run", false, "runs the build 'dry'") 109 xbuildCmd.Flags().BoolVar(&buildOptions.SkipTemplateValidation, "skip-template-validation", false, "skip validating templates") 110 xbuildCmd.Flags().BoolVar(&buildOptions.CleanAssets, "clean-assets", false, "will delete public/assets before calling webpack") 111 xbuildCmd.Flags().StringVarP(&buildOptions.Environment, "environment", "", "development", "set the environment for the binary") 112 xbuildCmd.Flags().StringVar(&buildOptions.Mod, "mod", "", "-mod flag for go build") 113 } 114 115 func buildVersion(version string) string { 116 vcs := buildOptions.VCS 117 118 if len(vcs) == 0 { 119 return version 120 } 121 122 ctx := context.Background() 123 run := genny.WetRunner(ctx) 124 if buildOptions.DryRun { 125 run = genny.DryRunner(ctx) 126 } 127 128 _, err := exec.LookPath(vcs) 129 if err != nil { 130 run.Logger.Warnf("could not find %s; defaulting to version %s", vcs, version) 131 return vcs 132 } 133 134 var cmd *exec.Cmd 135 switch vcs { 136 case "git": 137 // If .git folder does not exist return default version 138 if stat, err := os.Stat(".git"); err != nil || !stat.IsDir() { 139 run.Logger.Warnf("could not find .git folder; defaulting to version %s", version) 140 return version 141 } 142 143 cmd = exec.Command("git", "rev-parse", "--short", "HEAD") 144 case "bzr": 145 cmd = exec.Command("bzr", "revno") 146 default: 147 run.Logger.Warnf("could not find %s; defaulting to version %s", vcs, version) 148 return vcs 149 } 150 151 out := &bytes.Buffer{} 152 cmd.Stdout = out 153 run.WithRun(func(r *genny.Runner) error { 154 return r.Exec(cmd) 155 }) 156 157 if err := run.Run(); err != nil { 158 run.Logger.Error(err) 159 return version 160 } 161 162 if out.String() != "" { 163 return strings.TrimSpace(out.String()) 164 } 165 166 return version 167 }