github.com/dkishere/pop@v4.13.1+incompatible/soda/cmd/generate/model_cmd.go (about)

     1  package generate
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  
     7  	"github.com/gobuffalo/attrs"
     8  	"github.com/gobuffalo/fizz"
     9  	"github.com/gobuffalo/genny"
    10  	"github.com/gobuffalo/logger"
    11  	"github.com/gobuffalo/pop"
    12  	"github.com/gobuffalo/pop/genny/fizz/ctable"
    13  	gmodel "github.com/gobuffalo/pop/genny/model"
    14  	"github.com/gobuffalo/pop/internal/oncer"
    15  	"github.com/spf13/cobra"
    16  )
    17  
    18  var modelCmdConfig struct {
    19  	SkipMigration bool
    20  	StructTag     string
    21  	MigrationType string
    22  	ModelPath     string
    23  }
    24  
    25  func init() {
    26  	ModelCmd.Flags().StringVarP(&modelCmdConfig.StructTag, "struct-tag", "", "json", "sets the struct tags for model (xml/json/jsonapi)")
    27  	ModelCmd.Flags().StringVarP(&modelCmdConfig.MigrationType, "migration-type", "", "fizz", "sets the type of migration files for model (sql or fizz)")
    28  	ModelCmd.Flags().BoolVarP(&modelCmdConfig.SkipMigration, "skip-migration", "s", false, "Skip creating a new fizz migration for this model.")
    29  	ModelCmd.Flags().StringVarP(&modelCmdConfig.ModelPath, "models-path", "", "models", "the path the model will be created in")
    30  }
    31  
    32  // ModelCmd is the cmd to generate a model
    33  var ModelCmd = &cobra.Command{
    34  	Use:     "model [name]",
    35  	Aliases: []string{"m"},
    36  	Short:   "Generates a model for your database",
    37  	RunE: func(cmd *cobra.Command, args []string) error {
    38  		name := ""
    39  		if len(args) > 0 {
    40  			name = args[0]
    41  		}
    42  
    43  		var (
    44  			atts attrs.Attrs
    45  			err  error
    46  		)
    47  		if len(args) > 1 {
    48  			atts, err = attrs.ParseArgs(args[1:]...)
    49  			if err != nil {
    50  				return err
    51  			}
    52  		}
    53  
    54  		run := genny.WetRunner(context.Background())
    55  
    56  		// Ensure the generator is as verbose as the old one.
    57  		lg := logger.New(logger.DebugLevel)
    58  		run.Logger = lg
    59  
    60  		// Mount models generator
    61  		g, err := gmodel.New(&gmodel.Options{
    62  			Name:                   name,
    63  			Attrs:                  atts,
    64  			Path:                   modelCmdConfig.ModelPath,
    65  			Encoding:               modelCmdConfig.StructTag,
    66  			ForceDefaultID:         true,
    67  			ForceDefaultTimestamps: true,
    68  		})
    69  		if err != nil {
    70  			return err
    71  		}
    72  
    73  		run.With(g)
    74  
    75  		// Mount migrations generator
    76  		if !modelCmdConfig.SkipMigration {
    77  			p := cmd.Flag("path")
    78  			path := ""
    79  			if p != nil {
    80  				path = p.Value.String()
    81  			}
    82  			e := cmd.Flag("env")
    83  			var translator fizz.Translator
    84  			if modelCmdConfig.MigrationType == "sql" {
    85  				db, err := pop.Connect(e.Value.String())
    86  				if err != nil {
    87  					return err
    88  				}
    89  				translator = db.Dialect.FizzTranslator()
    90  			}
    91  
    92  			g, err = ctable.New(&ctable.Options{
    93  				TableName:              name,
    94  				Attrs:                  atts,
    95  				Path:                   path,
    96  				Type:                   modelCmdConfig.MigrationType,
    97  				Translator:             translator,
    98  				ForceDefaultID:         true,
    99  				ForceDefaultTimestamps: true,
   100  			})
   101  			if err != nil {
   102  				return err
   103  			}
   104  			run.With(g)
   105  		}
   106  
   107  		return run.Run()
   108  	},
   109  }
   110  
   111  // Model generates new model files to work with pop.
   112  func Model(name string, opts map[string]interface{}, attributes []string) error {
   113  	oncer.Deprecate(0, "generate.Model", "Use github.com/gobuffalo/pop/genny/model instead.")
   114  
   115  	mt, found := opts["marshalType"].(string)
   116  	if !found {
   117  		return errors.New("marshalType option is required")
   118  	}
   119  
   120  	pp, found := opts["modelPath"].(string)
   121  	if !found {
   122  		return errors.New("modelPath option is required")
   123  	}
   124  
   125  	atts, err := attrs.ParseArgs(attributes...)
   126  	if err != nil {
   127  		return err
   128  	}
   129  
   130  	run := genny.WetRunner(context.Background())
   131  
   132  	// Mount models generator
   133  	g, err := gmodel.New(&gmodel.Options{
   134  		Name:                   name,
   135  		Attrs:                  atts,
   136  		Path:                   pp,
   137  		Encoding:               mt,
   138  		ForceDefaultID:         true,
   139  		ForceDefaultTimestamps: true,
   140  	})
   141  	if err != nil {
   142  		return err
   143  	}
   144  	run.With(g)
   145  
   146  	sm, found := opts["skipMigration"].(bool)
   147  	// Mount migrations generator
   148  	if found && sm {
   149  		p, found := opts["path"].(string)
   150  		if !found {
   151  			return errors.New("path option is required")
   152  		}
   153  		migrationT, found := opts["migrationType"].(string)
   154  		if !found {
   155  			return errors.New("migrationType option is required")
   156  		}
   157  		var translator fizz.Translator
   158  		if migrationT == "sql" {
   159  			env, found := opts["env"].(string)
   160  			if !found {
   161  				return errors.New("env option is required")
   162  			}
   163  			db, err := pop.Connect(env)
   164  			if err != nil {
   165  				return err
   166  			}
   167  			translator = db.Dialect.FizzTranslator()
   168  		}
   169  
   170  		g, err = ctable.New(&ctable.Options{
   171  			TableName:  name,
   172  			Attrs:      atts,
   173  			Path:       p,
   174  			Type:       migrationT,
   175  			Translator: translator,
   176  		})
   177  		if err != nil {
   178  			return err
   179  		}
   180  		run.With(g)
   181  	}
   182  	return run.Run()
   183  }