github.com/cheikhshift/buffalo@v0.9.5/buffalo/cmd/generate/resource.go (about)

     1  package generate
     2  
     3  import (
     4  	"errors"
     5  	"os"
     6  	"path/filepath"
     7  	"strings"
     8  
     9  	"github.com/gobuffalo/buffalo/generators/resource"
    10  	"github.com/gobuffalo/envy"
    11  	"github.com/gobuffalo/makr"
    12  	"github.com/markbates/inflect"
    13  	"github.com/spf13/cobra"
    14  )
    15  
    16  const resourceExamples = `$ buffalo g resource users
    17  Generates:
    18  
    19  - actions/users.go
    20  - actions/users_test.go
    21  - models/user.go
    22  - models/user_test.go
    23  - migrations/2016020216301234_create_users.up.fizz
    24  - migrations/2016020216301234_create_users.down.fizz
    25  
    26  $ buffalo g resource users --skip-migration
    27  Generates:
    28  
    29  - actions/users.go
    30  - actions/users_test.go
    31  - models/user.go
    32  - models/user_test.go
    33  
    34  $ buffalo g resource users --skip-model
    35  Generates:
    36  
    37  - actions/users.go
    38  - actions/users_test.go
    39  
    40  $ buffalo g resource users --use-model users
    41  Generates:
    42  
    43  - actions/users.go
    44  - actions/users_test.go`
    45  
    46  // SkipResourceMigration allows to generate a resource without the migration.
    47  var SkipResourceMigration = false
    48  
    49  // SkipResourceModel allows to generate a resource without the model and Migration.
    50  var SkipResourceModel = false
    51  
    52  // UseResourceModel allows to generate a resource with a working model.
    53  var UseResourceModel = ""
    54  
    55  // ResourceMimeType allows to generate a typed resource (HTML by default, JSON...).
    56  var ResourceMimeType = "html"
    57  
    58  // ModelName allows to specify a different model name for the resource.
    59  var ModelName = ""
    60  
    61  // ResourceCmd generates a new actions/resource file and a stub test.
    62  var ResourceCmd = &cobra.Command{
    63  	Use:     "resource [name]",
    64  	Example: resourceExamples,
    65  	Aliases: []string{"r"},
    66  	Short:   "Generates a new actions/resource file",
    67  	RunE: func(cmd *cobra.Command, args []string) error {
    68  		var name, modelName, resourceName, filesPath, actionsPath string
    69  
    70  		//Check for a valid mime type
    71  		if ResourceMimeType != "html" && ResourceMimeType != "json" && ResourceMimeType != "xml" {
    72  			return errors.New("invalid resource type, you need to choose between \"html\", \"xml\" and \"json\"")
    73  		}
    74  
    75  		if len(args) == 0 && UseResourceModel == "" {
    76  			return errors.New("you must specify a resource name")
    77  		}
    78  
    79  		name = inflect.Pluralize(args[0])
    80  		modelName = name
    81  		filesPath = name
    82  		actionsPath = name
    83  		resourceName = name
    84  
    85  		if strings.Contains(name, "/") {
    86  			parts := strings.Split(name, "/")
    87  			name = parts[len(parts)-1]
    88  			modelName = name
    89  
    90  			resourceName = strings.Join(parts, "_")
    91  			actionsPath = resourceName
    92  		}
    93  
    94  		// Allow overwriting modelName with the --use-model flag
    95  		// buffalo generate resource users --use-model people
    96  		if UseResourceModel != "" {
    97  			modelName = inflect.Pluralize(UseResourceModel)
    98  			name = UseResourceModel
    99  		}
   100  
   101  		if ModelName != "" {
   102  			modelName = inflect.Pluralize(ModelName)
   103  			name = ModelName
   104  		}
   105  
   106  		modelProps := modelPropertiesFromArgs(args)
   107  
   108  		data := makr.Data{
   109  			"name":     name,
   110  			"singular": inflect.Singularize(name),
   111  			"camel":    inflect.Camelize(name),
   112  			"under":    inflect.Underscore(name),
   113  
   114  			"renderFunction": strings.ToUpper(ResourceMimeType),
   115  			"actions":        []string{"List", "Show", "New", "Create", "Edit", "Update", "Destroy"},
   116  			"args":           args,
   117  
   118  			"filesPath":   filesPath,
   119  			"actionsPath": actionsPath,
   120  
   121  			"model":              inflect.Singularize(inflect.Camelize(name)),
   122  			"modelPlural":        inflect.Pluralize(inflect.Camelize(name)),
   123  			"modelPluralUnder":   inflect.Underscore(modelName),
   124  			"modelFilename":      inflect.Underscore(inflect.Camelize(name)),
   125  			"modelTable":         inflect.Underscore(inflect.Pluralize(name)),
   126  			"modelSingularUnder": inflect.Underscore(inflect.Singularize(name)),
   127  			"modelProps":         modelProps,
   128  			"modelsPath":         packagePath() + "/models",
   129  
   130  			"resourceName":          inflect.Camelize(resourceName),
   131  			"resourcePlural":        inflect.Pluralize(inflect.Camelize(resourceName)),
   132  			"resourceURL":           inflect.Pluralize(inflect.Underscore(filesPath)),
   133  			"resourceSingularUnder": inflect.Underscore(inflect.Singularize(resourceName)),
   134  
   135  			"routeName":              inflect.Camelize(resourceName),
   136  			"routeNameSingular":      inflect.Camelize(inflect.Singularize(resourceName)),
   137  			"routeFirstDown":         inflect.CamelizeDownFirst(resourceName),
   138  			"routeFirstDownSingular": inflect.CamelizeDownFirst(inflect.Singularize(resourceName)),
   139  
   140  			"varPlural":   inflect.CamelizeDownFirst(modelName),
   141  			"varSingular": inflect.Singularize(inflect.CamelizeDownFirst(modelName)),
   142  
   143  			// Flags
   144  			"skipMigration": SkipResourceMigration,
   145  			"skipModel":     SkipResourceModel,
   146  			"useModel":      UseResourceModel,
   147  			"mimeType":      ResourceMimeType,
   148  		}
   149  
   150  		g, err := resource.New(data)
   151  		if err != nil {
   152  			return err
   153  		}
   154  		return g.Run(".", data)
   155  	},
   156  }
   157  
   158  type modelProp struct {
   159  	Name string
   160  	Type string
   161  }
   162  
   163  func (m modelProp) String() string {
   164  	return m.Name
   165  }
   166  
   167  func modelPropertiesFromArgs(args []string) []modelProp {
   168  	var mProps []modelProp
   169  	if len(args) == 0 {
   170  		return mProps
   171  	}
   172  	for _, a := range args[1:] {
   173  		ax := strings.Split(a, ":")
   174  		p := modelProp{
   175  			Name: inflect.ForeignKeyToAttribute(ax[0]),
   176  			Type: "string",
   177  		}
   178  		if len(ax) > 1 {
   179  			p.Type = strings.ToLower(strings.TrimPrefix(ax[1], "nulls."))
   180  		}
   181  		mProps = append(mProps, p)
   182  	}
   183  	return mProps
   184  }
   185  
   186  func goPath(root string) string {
   187  	gpMultiple := envy.GoPaths()
   188  	path := ""
   189  
   190  	for i := 0; i < len(gpMultiple); i++ {
   191  		if strings.HasPrefix(root, filepath.Join(gpMultiple[i], "src")) {
   192  			path = gpMultiple[i]
   193  			break
   194  		}
   195  	}
   196  	return path
   197  }
   198  
   199  func packagePath() string {
   200  	rootPath, _ := os.Getwd()
   201  	gosrcpath := strings.Replace(filepath.Join(goPath(rootPath), "src"), "\\", "/", -1)
   202  	rootPath = strings.Replace(rootPath, "\\", "/", -1)
   203  	return strings.Replace(rootPath, gosrcpath+"/", "", 2)
   204  }