github.com/mayra-cabrera/buffalo@v0.9.4-0.20170814145312-66d2e7772f11/buffalo/cmd/new.go (about) 1 package cmd 2 3 import ( 4 "errors" 5 "fmt" 6 "os" 7 "os/user" 8 "path/filepath" 9 "regexp" 10 "strings" 11 12 "github.com/gobuffalo/buffalo/generators/newapp" 13 "github.com/gobuffalo/envy" 14 "github.com/gobuffalo/plush" 15 "github.com/markbates/inflect" 16 "github.com/spf13/cobra" 17 ) 18 19 var rootPath string 20 var app = &newapp.App{} 21 22 var newCmd = &cobra.Command{ 23 Use: "new [name]", 24 Short: "Creates a new Buffalo application", 25 RunE: func(cmd *cobra.Command, args []string) error { 26 if !validDbType() { 27 return fmt.Errorf("Unknown db-type %s expecting one of postgres, mysql or sqlite3", app.DBType) 28 } 29 30 if len(args) == 0 { 31 return errors.New("you must enter a name for your new application") 32 } 33 34 app.Name = args[0] 35 36 if forbiddenName() { 37 return fmt.Errorf("name %s is not allowed, try a different application name", app.Name) 38 } 39 40 if nameHasIllegalCharacter(app.Name) { 41 return fmt.Errorf("name %s is not allowed, application name can only be contain [a-Z0-9-_]", app.Name) 42 } 43 44 if app.Name == "." { 45 app.Name = filepath.Base(app.RootPath) 46 } else { 47 app.RootPath = filepath.Join(app.RootPath, app.Name) 48 } 49 50 err := validateInGoPath() 51 if err != nil { 52 return err 53 } 54 55 s, _ := os.Stat(app.RootPath) 56 if s != nil { 57 if app.Force { 58 os.RemoveAll(app.RootPath) 59 } else { 60 return fmt.Errorf("%s already exists! Either delete it or use the -f flag to force", app.Name) 61 } 62 } 63 64 err = genNewFiles() 65 if err != nil { 66 return err 67 } 68 69 fmt.Printf("Congratulations! Your application, %s, has been successfully built!\n\n", app.Name) 70 fmt.Println("You can find your new application at:") 71 fmt.Println(app.RootPath) 72 fmt.Println("\nPlease read the README.md file in your new application for next steps on running your application.") 73 74 return nil 75 }, 76 } 77 78 func validDbType() bool { 79 return app.DBType == "postgres" || app.DBType == "mysql" || app.DBType == "sqlite3" 80 } 81 82 func forbiddenName() bool { 83 return contains(forbiddenAppNames, strings.ToLower(app.Name)) 84 } 85 86 var nameRX = regexp.MustCompile("^[\\w-]+$") 87 88 func nameHasIllegalCharacter(name string) bool { 89 return !nameRX.MatchString(name) 90 } 91 92 func validateInGoPath() error { 93 gpMultiple := envy.GoPaths() 94 95 var gp string 96 larp := strings.ToLower(app.RootPath) 97 for i := 0; i < len(gpMultiple); i++ { 98 lgpm := strings.ToLower(filepath.Join(gpMultiple[i], "src")) 99 if strings.HasPrefix(larp, lgpm) { 100 gp = gpMultiple[i] 101 break 102 } 103 } 104 105 if gp == "" { 106 u, err := user.Current() 107 if err != nil { 108 return err 109 } 110 t, err := plush.Render(notInGoWorkspace, plush.NewContextWith(map[string]interface{}{ 111 "name": app.Name, 112 "gopath": envy.GoPath(), 113 "current": app.RootPath, 114 "username": u.Username, 115 })) 116 if err != nil { 117 return err 118 } 119 fmt.Println(t) 120 os.Exit(-1) 121 } 122 return nil 123 } 124 125 func goPath(root string) string { 126 gpMultiple := envy.GoPaths() 127 path := "" 128 129 for i := 0; i < len(gpMultiple); i++ { 130 if strings.HasPrefix(root, filepath.Join(gpMultiple[i], "src")) { 131 path = gpMultiple[i] 132 break 133 } 134 } 135 return path 136 } 137 138 func packagePath(rootPath string) string { 139 gosrcpath := strings.Replace(filepath.Join(goPath(rootPath), "src"), "\\", "/", -1) 140 rootPath = strings.Replace(rootPath, "\\", "/", -1) 141 return strings.Replace(rootPath, gosrcpath+"/", "", 2) 142 } 143 144 func genNewFiles() error { 145 packagePath := packagePath(app.RootPath) 146 147 data := map[string]interface{}{ 148 "name": app.Name, 149 "titleName": inflect.Titleize(app.Name), 150 "packagePath": packagePath, 151 "actionsPath": packagePath + "/actions", 152 "modelsPath": packagePath + "/models", 153 "withPop": !app.SkipPop, 154 "withDep": app.WithDep, 155 "withWebpack": !app.SkipWebpack && !app.API, 156 "skipYarn": app.SkipYarn, 157 "withYarn": !app.SkipYarn, 158 "dbType": app.DBType, 159 "version": Version, 160 "ciProvider": app.CIProvider, 161 "asAPI": app.API, 162 "asWeb": !app.API, 163 "docker": app.Docker, 164 } 165 166 g, err := app.Generator(data) 167 if err != nil { 168 return err 169 } 170 return g.Run(app.RootPath, data) 171 } 172 173 func init() { 174 pwd, _ := os.Getwd() 175 176 rootPath = pwd 177 app.RootPath = pwd 178 179 decorate("new", newCmd) 180 RootCmd.AddCommand(newCmd) 181 newCmd.Flags().BoolVar(&app.API, "api", false, "skip all front-end code and configure for an API server") 182 newCmd.Flags().BoolVarP(&app.Force, "force", "f", false, "delete and remake if the app already exists") 183 newCmd.Flags().BoolVarP(&app.Verbose, "verbose", "v", false, "verbosely print out the go get/install commands") 184 newCmd.Flags().BoolVar(&app.SkipPop, "skip-pop", false, "skips adding pop/soda to your app") 185 newCmd.Flags().BoolVar(&app.WithDep, "with-dep", false, "adds github.com/golang/dep to your app") 186 newCmd.Flags().BoolVar(&app.SkipWebpack, "skip-webpack", false, "skips adding Webpack to your app") 187 newCmd.Flags().BoolVar(&app.SkipYarn, "skip-yarn", false, "skip to use npm as the asset package manager") 188 newCmd.Flags().StringVar(&app.DBType, "db-type", "postgres", "specify the type of database you want to use [postgres, mysql, sqlite3]") 189 newCmd.Flags().StringVar(&app.Docker, "docker", "multi", "specify the type of Docker file to generate [none, multi, standard]") 190 newCmd.Flags().StringVar(&app.CIProvider, "ci-provider", "none", "specify the type of ci file you would like buffalo to generate [none, travis, gitlab-ci]") 191 } 192 193 func contains(s []string, e string) bool { 194 for _, a := range s { 195 if a == e { 196 return true 197 } 198 } 199 return false 200 } 201 202 var forbiddenAppNames = []string{"buffalo"} 203 204 const notInGoWorkspace = `Oops! It would appear that you are not in your Go Workspace. 205 206 Your $GOPATH is set to "<%= gopath %>". 207 208 You are currently in "<%= current %>". 209 210 The standard location for putting Go projects is something along the lines of "$GOPATH/src/github.com/<%= username %>/<%= name %>" (adjust accordingly). 211 212 We recommend you go to "$GOPATH/src/github.com/<%= username %>/" and try "buffalo new <%= name %>" again.` 213 214 const noGoPath = `You do not have a $GOPATH set. In order to work with Go, you must set up your $GOPATH and your Go Workspace. 215 216 We recommend reading this tutorial on setting everything up: https://www.goinggo.net/2016/05/installing-go-and-your-workspace.html 217 218 When you're ready come back and try again. Don't worry, Buffalo will be right here waiting for you. :)`