github.com/JarrahG/buffalocli@v0.0.0-20230801092127-b85bfd5d395a/internal/genny/build/archived_assets.go (about) 1 package build 2 3 import ( 4 "archive/zip" 5 "bytes" 6 "fmt" 7 "io" 8 "io/fs" 9 "path/filepath" 10 "strings" 11 12 "github.com/gobuffalo/genny/v2" 13 "github.com/gobuffalo/genny/v2/gogen/goimports" 14 ) 15 16 func archivedAssets(opts *Options) (*genny.Generator, error) { 17 g := genny.New() 18 19 if err := opts.Validate(); err != nil { 20 return g, err 21 } 22 23 target := filepath.Join(filepath.Dir(opts.App.Bin), "assets.zip") 24 source := filepath.Join(opts.App.Root, "public", "assets") 25 26 g.RunFn(func(r *genny.Runner) error { 27 bb := &bytes.Buffer{} 28 archive := zip.NewWriter(bb) 29 defer archive.Close() 30 31 for _, f := range r.Disk.Files() { 32 rel, err := filepath.Rel(source, f.Name()) 33 if err != nil { 34 continue 35 } 36 37 if strings.HasPrefix(rel, "..") { 38 continue 39 } 40 41 file, ok := f.(fs.File) 42 if !ok { 43 return fmt.Errorf("cannot process file %s: cast failed", f.Name()) 44 } 45 46 info, err := file.Stat() 47 if err != nil { 48 return err 49 } 50 51 header, err := zip.FileInfoHeader(info) 52 if err != nil { 53 return err 54 } 55 header.Name = rel 56 header.Method = zip.Deflate 57 58 writer, err := archive.CreateHeader(header) 59 if err != nil { 60 return err 61 } 62 63 _, err = io.Copy(writer, file) 64 if err != nil { 65 return err 66 } 67 } 68 // We need to close the archive before passing the buffer to genny, otherwise the zip 69 // will be corrupted. 70 archive.Close() 71 if err := r.File(genny.NewFile(target, bb)); err != nil { 72 return err 73 } 74 opts.keep.Store(target, struct{}{}) 75 return nil 76 }) 77 78 g.RunFn(func(r *genny.Runner) error { 79 f, err := r.FindFile("actions/app.go") 80 if err != nil { 81 return err 82 } 83 84 opts.rollback.Store(f.Name(), f.String()) 85 body := strings.Replace(f.String(), `app.ServeFiles("/assets"`, `// app.ServeFiles("/assets"`, 1) 86 body = strings.Replace(body, `app.ServeFiles("/"`, `// app.ServeFiles("/"`, 1) 87 f = genny.NewFileS(f.Name(), body) 88 89 // run goimports after to ensure we remove unneeded imports 90 // from actions/app.go 91 content := bytes.NewBufferString("") 92 gi := goimports.NewFromFiles(goimports.File{ 93 Name: f.Name(), 94 In: f, 95 Out: content, 96 }) 97 98 if err := gi.Run(); err != nil { 99 return err 100 } 101 102 return r.File(genny.NewFile(f.Name(), content)) 103 }) 104 105 return g, nil 106 }