github.com/lenfree/buffalo@v0.7.3-0.20170207163156-891616ea4064/buffalo/cmd/new.go (about)

     1  package cmd
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"os"
     7  	"os/user"
     8  	"path/filepath"
     9  	"runtime"
    10  	"strings"
    11  
    12  	"github.com/gobuffalo/envy"
    13  	"github.com/gobuffalo/velvet"
    14  	"github.com/markbates/inflect"
    15  	"github.com/spf13/cobra"
    16  )
    17  
    18  var rootPath string
    19  var force bool
    20  var verbose bool
    21  var skipPop bool
    22  var skipWebpack bool
    23  var dbType = "postgres"
    24  var ciProvider = "none"
    25  
    26  var newCmd = &cobra.Command{
    27  	Use:   "new [name]",
    28  	Short: "Creates a new Buffalo application",
    29  	RunE: func(cmd *cobra.Command, args []string) error {
    30  		if !validDbType() {
    31  			return fmt.Errorf("Unknown db-type %s expecting one of postgres, mysql or sqlite3", dbType)
    32  		}
    33  
    34  		if len(args) == 0 {
    35  			return errors.New("you must enter a name for your new application")
    36  		}
    37  
    38  		name := args[0]
    39  
    40  		if name == "." {
    41  			name = filepath.Base(rootPath)
    42  		} else {
    43  			rootPath = filepath.Join(rootPath, name)
    44  		}
    45  
    46  		err := validateInGoPath(name)
    47  		if err != nil {
    48  			return err
    49  		}
    50  
    51  		s, _ := os.Stat(rootPath)
    52  		if s != nil {
    53  			if force {
    54  				os.RemoveAll(rootPath)
    55  			} else {
    56  				return fmt.Errorf("%s already exists! Either delete it or use the -f flag to force", name)
    57  			}
    58  		}
    59  
    60  		err = genNewFiles(name, rootPath)
    61  		if err != nil {
    62  			return err
    63  		}
    64  
    65  		fmt.Printf("Congratulations! Your application, %s, has been successfully built!\n\n", name)
    66  		fmt.Println("You can find your new application at:")
    67  		fmt.Println(rootPath)
    68  		fmt.Println("\nPlease read the README.md file in your new application for next steps on running your application.")
    69  
    70  		return nil
    71  	},
    72  }
    73  
    74  func validDbType() bool {
    75  	return dbType == "postgres" || dbType == "mysql" || dbType == "sqlite3"
    76  }
    77  
    78  func validateInGoPath(name string) error {
    79  	gp, err := envy.MustGet("GOPATH")
    80  	if err != nil {
    81  		fmt.Println(noGoPath)
    82  		os.Exit(-1)
    83  	}
    84  
    85  	var gpMultiple []string
    86  
    87  	if runtime.GOOS == "windows" {
    88  		gpMultiple = strings.Split(gp, ";") // Windows uses a different separator
    89  	} else {
    90  		gpMultiple = strings.Split(gp, ":")
    91  	}
    92  	gpMultipleLen := len(gpMultiple)
    93  	foundInPath := false
    94  
    95  	for i := 0; i < gpMultipleLen; i++ {
    96  		if strings.HasPrefix(rootPath, filepath.Join(gpMultiple[i], "src")) {
    97  			foundInPath = true
    98  			break
    99  		}
   100  	}
   101  
   102  	if !foundInPath {
   103  		u, err := user.Current()
   104  		if err != nil {
   105  			return err
   106  		}
   107  		t, err := velvet.Render(notInGoWorkspace, velvet.NewContextWith(map[string]interface{}{
   108  			"name":     name,
   109  			"gopath":   gp,
   110  			"current":  rootPath,
   111  			"username": u.Username,
   112  		}))
   113  		if err != nil {
   114  			return err
   115  		}
   116  		fmt.Println(t)
   117  		os.Exit(-1)
   118  	}
   119  	return nil
   120  }
   121  
   122  func goPath(root string) string {
   123  	var gpMultiple []string
   124  	gp := os.Getenv("GOPATH")
   125  
   126  	if runtime.GOOS == "windows" {
   127  		gpMultiple = strings.Split(gp, ";") // Windows uses a different separator
   128  	} else {
   129  		gpMultiple = strings.Split(gp, ":")
   130  	}
   131  	gpMultipleLen := len(gpMultiple)
   132  	path := ""
   133  
   134  	for i := 0; i < gpMultipleLen; i++ {
   135  		if strings.HasPrefix(root, filepath.Join(gpMultiple[i], "src")) {
   136  			path = gpMultiple[i]
   137  			break
   138  		}
   139  	}
   140  	return path
   141  }
   142  
   143  func packagePath(rootPath string) string {
   144  	gosrcpath := strings.Replace(filepath.Join(goPath(rootPath), "src"), "\\", "/", -1)
   145  	rootPath = strings.Replace(rootPath, "\\", "/", -1)
   146  	return strings.Replace(rootPath, gosrcpath+"/", "", 2)
   147  }
   148  
   149  func genNewFiles(name, rootPath string) error {
   150  	packagePath := packagePath(rootPath)
   151  
   152  	data := map[string]interface{}{
   153  		"name":        name,
   154  		"titleName":   inflect.Titleize(name),
   155  		"packagePath": packagePath,
   156  		"actionsPath": packagePath + "/actions",
   157  		"modelsPath":  packagePath + "/models",
   158  		"withPop":     !skipPop,
   159  		"withWebpack": !skipWebpack,
   160  		"dbType":      dbType,
   161  		"version":     Version,
   162  		"ciProvider":  ciProvider,
   163  	}
   164  
   165  	g := newAppGenerator(data)
   166  	return g.Run(rootPath, data)
   167  }
   168  
   169  func init() {
   170  	pwd, _ := os.Getwd()
   171  	rootPath = pwd
   172  
   173  	RootCmd.AddCommand(newCmd)
   174  	newCmd.Flags().BoolVarP(&force, "force", "f", false, "delete and remake if the app already exists")
   175  	newCmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "verbosely print out the go get/install commands")
   176  	newCmd.Flags().BoolVar(&skipPop, "skip-pop", false, "skips adding pop/soda to your app")
   177  	newCmd.Flags().BoolVar(&skipWebpack, "skip-webpack", false, "skips adding Webpack to your app")
   178  	newCmd.Flags().StringVar(&dbType, "db-type", "postgres", "specify the type of database you want to use [postgres, mysql, sqlite3]")
   179  	newCmd.Flags().StringVar(&ciProvider, "ci-provider", "none", "specify the type of ci file you would like buffalo to generate [none, travis]")
   180  }
   181  
   182  const notInGoWorkspace = `Oops! It would appear that you are not in your Go Workspace.
   183  
   184  Your $GOPATH is set to "{{gopath}}".
   185  
   186  You are currently in "{{current}}".
   187  
   188  The standard location for putting Go projects is something along the lines of "$GOPATH/src/github.com/{{username}}/{{name}}" (adjust accordingly).
   189  
   190  We recommend you go to "$GOPATH/src/github.com/{{username}}/" and try "buffalo new {{name}}" again.`
   191  
   192  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.
   193  
   194  We recommend reading this tutorial on setting everything up: https://www.goinggo.net/2016/05/installing-go-and-your-workspace.html
   195  
   196  When you're ready come back and try again. Don't worry, Buffalo will be right here waiting for you. :)`