github.com/jacobsoderblom/buffalo@v0.11.0/buffalo/cmd/setup.go (about) 1 package cmd 2 3 import ( 4 "bytes" 5 "context" 6 "os" 7 "os/exec" 8 "strings" 9 10 "golang.org/x/sync/errgroup" 11 12 "github.com/gobuffalo/buffalo/meta" 13 "github.com/gobuffalo/envy" 14 "github.com/markbates/deplist" 15 "github.com/pkg/errors" 16 "github.com/sirupsen/logrus" 17 "github.com/spf13/cobra" 18 ) 19 20 var setupOptions = struct { 21 verbose bool 22 updateGoDeps bool 23 dropDatabases bool 24 }{} 25 26 type setupCheck func(meta.App) error 27 28 var setupCmd = &cobra.Command{ 29 Use: "setup", 30 Short: "Setups a newly created, or recently checked out application.", 31 Long: `Setup runs through checklist to make sure dependencies are setup correcly. 32 33 Dependencies (if used): 34 * Runs "dep ensure" to install required Go dependencies. 35 36 Asset Pipeline (if used): 37 * Runs "npm install" or "yarn install" to install asset dependencies. 38 39 Database (if used): 40 * Runs "buffalo db create -a" to create databases. 41 * Runs "buffalo db migrate" to run database migrations. 42 * Runs "buffalo task db:seed" to seed the database (if the task exists). 43 44 Tests: 45 * Runs "buffalo test" to confirm the application's tests are running properly. 46 `, 47 RunE: func(cmd *cobra.Command, args []string) error { 48 app := meta.New(".") 49 for _, check := range []setupCheck{assetCheck, updateGoDepsCheck, databaseCheck, testCheck} { 50 err := check(app) 51 if err != nil { 52 return errors.WithStack(err) 53 } 54 } 55 return nil 56 }, 57 } 58 59 func updateGoDepsCheck(app meta.App) error { 60 deps, _ := deplist.List() 61 if app.WithDep { 62 // use github.com/golang/dep 63 args := []string{"ensure"} 64 if setupOptions.verbose { 65 args = append(args, "-v") 66 } 67 if setupOptions.updateGoDeps { 68 args = append(args, "--update") 69 } 70 err := run(exec.Command("dep", args...)) 71 if err != nil { 72 return errors.WithStack(err) 73 } 74 return nil 75 } 76 77 // go old school with the installation 78 ctx, cancel := context.WithCancel(context.Background()) 79 defer cancel() 80 wg, _ := errgroup.WithContext(ctx) 81 deps, err := deplist.List() 82 if err != nil { 83 return errors.WithStack(err) 84 } 85 86 deps["github.com/gobuffalo/suite"] = "github.com/gobuffalo/suite" 87 88 for dep := range deps { 89 args := []string{"get"} 90 if setupOptions.verbose { 91 args = append(args, "-v") 92 } 93 if setupOptions.updateGoDeps { 94 args = append(args, "-u") 95 } 96 args = append(args, dep) 97 c := exec.Command(envy.Get("GO_BIN", "go"), args...) 98 f := func() error { 99 return run(c) 100 } 101 wg.Go(f) 102 } 103 err = wg.Wait() 104 if err != nil { 105 return errors.Errorf("We encountered the following error trying to install and update the dependencies for this application:\n%s", err) 106 } 107 return nil 108 } 109 110 func testCheck(meta.App) error { 111 err := run(exec.Command("buffalo", "test")) 112 if err != nil { 113 return errors.Errorf("We encountered the following error when trying to run your applications tests:\n%s", err) 114 } 115 return nil 116 } 117 118 func databaseCheck(app meta.App) error { 119 if !app.WithPop { 120 return nil 121 } 122 for _, check := range []setupCheck{dbCreateCheck, dbMigrateCheck, dbSeedCheck} { 123 err := check(app) 124 if err != nil { 125 return err 126 } 127 } 128 return nil 129 } 130 131 func dbCreateCheck(meta.App) error { 132 if setupOptions.dropDatabases { 133 err := run(exec.Command("buffalo", "db", "drop", "-a")) 134 if err != nil { 135 return errors.Errorf("We encountered an error when trying to drop your application's databases. Please check to make sure that your database server is running and that the username and passwords found in the database.yml are properly configured and set up on your database server.\n %s", err) 136 } 137 } 138 err := run(exec.Command("buffalo", "db", "create", "-a")) 139 if err != nil { 140 return errors.Errorf("We encountered an error when trying to create your application's databases. Please check to make sure that your database server is running and that the username and passwords found in the database.yml are properly configured and set up on your database server.\n %s", err) 141 } 142 return nil 143 } 144 145 func dbMigrateCheck(meta.App) error { 146 err := run(exec.Command("buffalo", "db", "migrate")) 147 if err != nil { 148 return errors.Errorf("We encountered the following error when trying to migrate your database:\n%s", err) 149 } 150 return nil 151 } 152 153 func dbSeedCheck(meta.App) error { 154 cmd := exec.Command("buffalo", "t", "list") 155 out, err := cmd.Output() 156 if err != nil { 157 // no tasks configured, so return 158 return nil 159 } 160 if bytes.Contains(out, []byte("db:seed")) { 161 err := run(exec.Command("buffalo", "task", "db:seed")) 162 if err != nil { 163 return errors.Errorf("We encountered the following error when trying to seed your database:\n%s", err) 164 } 165 } 166 return nil 167 } 168 169 func assetCheck(app meta.App) error { 170 if !app.WithWebpack { 171 return nil 172 } 173 if app.WithYarn { 174 return yarnCheck(app) 175 } 176 return npmCheck(app) 177 } 178 179 func npmCheck(app meta.App) error { 180 err := nodeCheck(app) 181 if err != nil { 182 return errors.WithStack(err) 183 } 184 err = run(exec.Command("npm", "install", "--no-progress")) 185 if err != nil { 186 return errors.Errorf("We encountered the following error when trying to install your asset dependencies using npm:\n%s", err) 187 } 188 return nil 189 } 190 191 func yarnCheck(app meta.App) error { 192 err := nodeCheck(app) 193 if err != nil { 194 return errors.WithStack(err) 195 } 196 if _, err := exec.LookPath("yarn"); err != nil { 197 err := run(exec.Command("npm", "install", "-g", "yarn")) 198 if err != nil { 199 return errors.Errorf("This application require yarn, and we could not find it installed on your system. We tried to install it for you, but ran into the following error:\n%s", err) 200 } 201 } 202 err = run(exec.Command("yarn", "install", "--no-progress")) 203 if err != nil { 204 return errors.Errorf("We encountered the following error when trying to install your asset dependencies using yarn:\n%s", err) 205 } 206 return nil 207 } 208 209 func nodeCheck(meta.App) error { 210 if _, err := exec.LookPath("node"); err != nil { 211 return errors.New("this application requires node, and we could not find it installed on your system please install node and try again") 212 } 213 if _, err := exec.LookPath("npm"); err != nil { 214 return errors.New("this application requires npm, and we could not find it installed on your system please install npm and try again") 215 } 216 return nil 217 } 218 219 func run(cmd *exec.Cmd) error { 220 logrus.Infof("--> %s\n", strings.Join(cmd.Args, " ")) 221 cmd.Stdin = os.Stdin 222 cmd.Stderr = os.Stderr 223 cmd.Stdout = os.Stdout 224 return cmd.Run() 225 } 226 227 func init() { 228 setupCmd.Flags().BoolVarP(&setupOptions.verbose, "verbose", "v", false, "run with verbose output") 229 setupCmd.Flags().BoolVarP(&setupOptions.updateGoDeps, "update", "u", false, "run go get -u against the application's Go dependencies") 230 setupCmd.Flags().BoolVarP(&setupOptions.dropDatabases, "drop", "d", false, "drop existing databases") 231 232 decorate("setup", setupCmd) 233 RootCmd.AddCommand(setupCmd) 234 }