github.com/JarrahG/buffalocli@v0.0.0-20230801092127-b85bfd5d395a/internal/genny/fix/npm.go (about) 1 package fix 2 3 import ( 4 "bytes" 5 "encoding/json" 6 "fmt" 7 "html/template" 8 "os/exec" 9 10 "github.com/JarrahG/buffalocli/internal/genny/assets/webpack" 11 "github.com/gobuffalo/genny/v2" 12 "github.com/gobuffalo/meta" 13 ) 14 15 // default scripts for package.json 16 var defaultScripts = map[string]string{ 17 "dev": "webpack --watch", 18 "build": "webpack -p --progress", 19 } 20 21 // AddPackageJSONScripts rewrites the package.json file 22 // to add dev and build scripts if there are missing. 23 func AddPackageJSONScripts(opts *Options) genny.RunFn { 24 return func(r *genny.Runner) error { 25 if !opts.App.WithWebpack { 26 return nil 27 } 28 29 fmt.Println("~~~ Patching package.json to add dev and build scripts ~~~") 30 f, err := r.FindFile("package.json") 31 if err != nil { 32 return err 33 } 34 35 needRewrite := false 36 packageJSON := map[string]interface{}{} 37 if err := json.NewDecoder(f).Decode(&packageJSON); err != nil { 38 return fmt.Errorf("could not rewrite package.json: %s", err.Error()) 39 } 40 41 if _, ok := packageJSON["scripts"]; !ok { 42 needRewrite = true 43 packageJSON["scripts"] = defaultScripts 44 } else { 45 scripts, ok := packageJSON["scripts"].(map[string]interface{}) 46 if !ok { 47 return fmt.Errorf("could not rewrite package.json: invalid scripts section") 48 } 49 50 // Add missing scripts 51 for k, v := range defaultScripts { 52 if _, ok := scripts[k]; !ok { 53 scripts[k] = v 54 needRewrite = true 55 } 56 } 57 packageJSON["scripts"] = scripts 58 } 59 60 if !needRewrite { 61 fmt.Println("~~~ package.json doesn't need to be patched, skipping. ~~~") 62 return nil 63 } 64 65 enc := json.NewEncoder(f) 66 enc.SetIndent("", " ") 67 if err := enc.Encode(packageJSON); err != nil { 68 return fmt.Errorf("could not rewrite package.json: %w", err) 69 } 70 71 return r.File(f) 72 } 73 } 74 75 // PackageJSONCheck will compare the current default Buffalo 76 // package.json against the applications package.json. If they are 77 // different you have the option to overwrite the existing package.json 78 // file with the new one. 79 func PackageJSONCheck(opts *Options) genny.RunFn { 80 return func(r *genny.Runner) error { 81 if !opts.App.WithWebpack { 82 return nil 83 } 84 85 fmt.Println("~~~ Checking package.json ~~~") 86 bb, err := defaultPackageJson(opts.App) 87 if err != nil { 88 return err 89 } 90 91 f, err := r.FindFile("package.json") 92 if err != nil { 93 return err 94 } 95 96 if f.String() == bb.String() { 97 return nil 98 } 99 100 if !opts.YesToAll && !ask("Your package.json file is different from the latest Buffalo template.\nWould you like to REPLACE yours with the latest template?") { 101 fmt.Println("\tskipping package.json") 102 return nil 103 } 104 105 if _, err := f.Write(bb.Bytes()); err != nil { 106 return err 107 } 108 109 if err := r.File(f); err != nil { 110 return err 111 } 112 113 if err := r.Delete("node_modules"); err != nil { 114 return err 115 } 116 117 if opts.App.WithYarn { 118 return r.Exec(exec.Command("yarn", "install")) 119 } 120 121 return r.Exec(exec.Command("npm", "install")) 122 } 123 } 124 125 func defaultPackageJson(app meta.App) (*bytes.Buffer, error) { 126 templates, err := webpack.Templates() 127 if err != nil { 128 return nil, err 129 } 130 131 tmpl, err := template.New("package.json").ParseFS(templates, "package.json.tmpl") 132 if err != nil { 133 return nil, err 134 } 135 136 bb := &bytes.Buffer{} 137 err = tmpl.ExecuteTemplate(bb, "package.json.tmpl", map[string]interface{}{ 138 "opts": &webpack.Options{ 139 App: app, 140 }, 141 }) 142 return bb, err 143 }