github.com/sotirispl/buffalo@v0.11.1/generators/newapp/generator.go (about)

     1  package newapp
     2  
     3  import (
     4  	"fmt"
     5  	"os"
     6  	"path/filepath"
     7  	"regexp"
     8  	"strings"
     9  
    10  	"github.com/gobuffalo/buffalo/meta"
    11  	"github.com/gobuffalo/envy"
    12  	"github.com/gobuffalo/pop"
    13  	"github.com/markbates/inflect"
    14  	"github.com/pkg/errors"
    15  )
    16  
    17  // ErrNotInGoPath can be asserted against
    18  var ErrNotInGoPath = errors.New("currently not in a $GOPATH")
    19  
    20  // Generator is the representation of a new Buffalo application
    21  type Generator struct {
    22  	meta.App
    23  	Version     string `json:"version"`
    24  	Force       bool   `json:"force"`
    25  	Verbose     bool   `json:"verbose"`
    26  	DBType      string `json:"db_type"`
    27  	CIProvider  string `json:"ci_provider"`
    28  	AsWeb       bool   `json:"as_web"`
    29  	AsAPI       bool   `json:"as_api"`
    30  	Docker      string `json:"docker"`
    31  	SkipPop     bool   `json:"skip_pop"`
    32  	SkipWebpack bool   `json:"skip_webpack"`
    33  	SkipYarn    bool   `json:"skip_yarn"`
    34  	Bootstrap   int    `json:"bootstrap"`
    35  }
    36  
    37  // New app generator
    38  func New(name string) (Generator, error) {
    39  	g := Generator{
    40  		App:        meta.New("."),
    41  		DBType:     "postgres",
    42  		CIProvider: "none",
    43  		AsWeb:      true,
    44  		Docker:     "multi",
    45  	}
    46  	g.Name = inflect.Name(name)
    47  
    48  	if g.Name == "." {
    49  		g.Name = inflect.Name(filepath.Base(g.Root))
    50  	} else {
    51  		g.Root = filepath.Join(g.Root, g.Name.File())
    52  	}
    53  
    54  	return g, g.Validate()
    55  }
    56  
    57  // Validate that the app generator is good
    58  func (g Generator) Validate() error {
    59  	if g.Name == "" {
    60  		return errors.New("you must enter a name for your new application")
    61  	}
    62  
    63  	var found bool
    64  	for _, d := range pop.AvailableDialects {
    65  		if d == g.DBType {
    66  			found = true
    67  			break
    68  		}
    69  	}
    70  	if !found {
    71  		return fmt.Errorf("Unknown db-type %s expecting one of %s", g.DBType, strings.Join(pop.AvailableDialects, ", "))
    72  	}
    73  
    74  	for _, n := range forbiddenAppNames {
    75  		if n == g.Name.Lower() {
    76  			return fmt.Errorf("name %s is not allowed, try a different application name", g.Name)
    77  		}
    78  	}
    79  
    80  	if !nameRX.MatchString(string(g.Name)) {
    81  		return fmt.Errorf("name %s is not allowed, application name can only be contain [a-Z0-9-_]", g.Name)
    82  	}
    83  
    84  	if s, _ := os.Stat(g.Root); s != nil {
    85  		if !g.Force {
    86  			return fmt.Errorf("%s already exists! Either delete it or use the -f flag to force", g.Name)
    87  		}
    88  	}
    89  
    90  	return g.validateInGoPath()
    91  }
    92  
    93  func (g Generator) validateInGoPath() error {
    94  	gpMultiple := envy.GoPaths()
    95  
    96  	larp := strings.ToLower(g.Root)
    97  	for i := 0; i < len(gpMultiple); i++ {
    98  		lgpm := strings.ToLower(filepath.Join(gpMultiple[i], "src"))
    99  		if strings.HasPrefix(larp, lgpm) {
   100  			return nil
   101  		}
   102  	}
   103  
   104  	return ErrNotInGoPath
   105  }
   106  
   107  var forbiddenAppNames = []string{"buffalo"}
   108  var nameRX = regexp.MustCompile("^[\\w-]+$")