github.com/JarrahG/buffalocli@v0.0.0-20230801092127-b85bfd5d395a/internal/genny/build/build.go (about) 1 package build 2 3 import ( 4 "embed" 5 "io/fs" 6 "os" 7 "path/filepath" 8 "strings" 9 "time" 10 11 "github.com/JarrahG/buffalocli/internal/runtime" 12 "github.com/gobuffalo/events" 13 "github.com/gobuffalo/genny/v2" 14 "github.com/gobuffalo/genny/v2/plushgen" 15 "github.com/gobuffalo/plush/v4" 16 ) 17 18 //go:embed templates/* 19 var templates embed.FS 20 21 // New generator for building a Buffalo application 22 // This powers the `buffalo build` command and can be 23 // used to programatically build/compile Buffalo 24 // applications. 25 func New(opts *Options) (*genny.Generator, error) { 26 g := genny.New() 27 28 if err := opts.Validate(); err != nil { 29 return g, err 30 } 31 g.ErrorFn = func(err error) { 32 events.EmitError(EvtBuildStopErr, err, events.Payload{"opts": opts}) 33 } 34 35 g.RunFn(func(r *genny.Runner) error { 36 events.EmitPayload(EvtBuildStart, events.Payload{"opts": opts}) 37 return nil 38 }) 39 40 g.Transformer(genny.Dot()) 41 // TODO: workaround for 1.16, remove when we upgrade to 1.17 and rename "dot-*" files back to "-dot-*" 42 g.Transformer(genny.NewTransformer("*", func(f genny.File) (genny.File, error) { 43 name := f.Name() 44 if strings.HasPrefix(name, "dot-") { 45 name = strings.TrimPrefix(name, "dot-") 46 name = "." + name 47 } 48 return genny.NewFile(name, f), nil 49 })) 50 g.Transformer(genny.Replace("/dot-", "/.")) 51 52 // validate templates 53 templatesPath := filepath.Join(opts.App.Root, "/templates") 54 if _, err := os.Stat(templatesPath); err == nil { 55 g.RunFn(ValidateTemplates(os.DirFS(templatesPath), opts.TemplateValidators)) 56 } 57 58 // rename main() to originalMain() 59 g.RunFn(transformMain(opts)) 60 61 // add any necessary templates for the build 62 sub, err := fs.Sub(templates, "templates") 63 if err != nil { 64 return g, err 65 } 66 67 if err := g.FS(sub); err != nil { 68 return g, err 69 } 70 71 // configure plush 72 ctx := plush.NewContext() 73 ctx.Set("opts", opts) 74 ctx.Set("buildTime", opts.BuildTime.Format(time.RFC3339)) 75 ctx.Set("buildVersion", opts.BuildVersion) 76 ctx.Set("buffaloVersion", runtime.Version) 77 g.Transformer(plushgen.Transformer(ctx)) 78 79 // create the ./a pkg 80 ag, err := apkg(opts) 81 if err != nil { 82 return g, err 83 } 84 g.Merge(ag) 85 86 if opts.WithAssets { 87 // mount the assets generator 88 ag, err := assets(opts) 89 if err != nil { 90 return g, err 91 } 92 g.Merge(ag) 93 } 94 95 if opts.WithBuildDeps { 96 // mount the build time dependency generator 97 dg, err := buildDeps(opts) 98 if err != nil { 99 return g, err 100 } 101 g.Merge(dg) 102 } 103 104 // create the final go build command 105 c, err := buildCmd(opts) 106 if err != nil { 107 return g, err 108 } 109 110 g.Command(c) 111 g.RunFn(func(r *genny.Runner) error { 112 events.EmitPayload(EvtBuildStop, events.Payload{"opts": opts}) 113 return nil 114 }) 115 116 g.RunFn(Cleanup(opts)) 117 return g, nil 118 }