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