github.com/gobuffalo/buffalo-cli/v2@v2.0.0-alpha.15.0.20200919213536-a7350c8e6799/cli/cmds/resource/generator.go (about) 1 package resource 2 3 import ( 4 "context" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 10 "github.com/gobuffalo/buffalo-cli/v2/cli/cmds/generate" 11 "github.com/gobuffalo/flect/name" 12 "github.com/gobuffalo/genny/v2" 13 "github.com/gobuffalo/genny/v2/gogen" 14 "github.com/gobuffalo/plugins" 15 "github.com/gobuffalo/plugins/plugcmd" 16 "github.com/gobuffalo/plugins/plugio" 17 "github.com/gobuffalo/plugins/plugprint" 18 "github.com/spf13/pflag" 19 ) 20 21 var _ plugcmd.Aliaser = Generator{} 22 var _ generate.Generator = &Generator{} 23 var _ plugins.Plugin = &Generator{} 24 var _ plugins.Needer = &Generator{} 25 var _ plugins.Scoper = &Generator{} 26 27 type Generator struct { 28 skipActionTests bool 29 skipActions bool 30 skipMigrationTests bool 31 skipMigrations bool 32 skipModelTests bool 33 skipModels bool 34 skipTemplateTests bool 35 skipTemplates bool 36 37 flags *pflag.FlagSet 38 help bool 39 pluginsFn plugins.Feeder 40 } 41 42 func (g *Generator) WithPlugins(f plugins.Feeder) { 43 g.pluginsFn = f 44 } 45 46 func (g Generator) PluginName() string { 47 return "resource" 48 } 49 50 func (g Generator) CmdAliases() []string { 51 return []string{"r"} 52 } 53 54 func (g *Generator) ScopedPlugins() []plugins.Plugin { 55 var plugs []plugins.Plugin 56 if g.pluginsFn != nil { 57 plugs = g.pluginsFn() 58 } 59 60 var builders []plugins.Plugin 61 62 for _, p := range plugs { 63 switch p.(type) { 64 case BeforeGenerator: 65 builders = append(builders, p) 66 case AfterGenerator: 67 builders = append(builders, p) 68 case Stdouter: 69 builders = append(builders, p) 70 case Actioner: 71 builders = append(builders, p) 72 case ActionTester: 73 builders = append(builders, p) 74 case Modeler: 75 builders = append(builders, p) 76 case ModelTester: 77 builders = append(builders, p) 78 case Templater: 79 builders = append(builders, p) 80 case TemplateTester: 81 builders = append(builders, p) 82 case Migrationer: 83 builders = append(builders, p) 84 case MigrationTester: 85 builders = append(builders, p) 86 case Flagger: 87 builders = append(builders, p) 88 case Pflagger: 89 builders = append(builders, p) 90 } 91 } 92 93 return builders 94 } 95 96 func (g *Generator) beforeGenerate(ctx context.Context, root string, args []string) error { 97 plugs := g.ScopedPlugins() 98 99 for _, p := range plugs { 100 if b, ok := p.(BeforeGenerator); ok { 101 if err := b.BeforeGenerateResource(ctx, root, args); err != nil { 102 return plugins.Wrap(p, err) 103 } 104 } 105 } 106 107 return nil 108 } 109 110 func (g *Generator) addResource(root string, n string) error { 111 fp := filepath.Join(root, "actions", "app.go") 112 113 b, err := ioutil.ReadFile(fp) 114 if err != nil { 115 return plugins.Wrap(g, err) 116 } 117 118 pres := name.New(n) 119 stmt := fmt.Sprintf("app.Resource(\"/%s\", %sResource{})", pres.URL(), pres.Resource()) 120 121 gf, err := gogen.AddInsideBlock(genny.NewFileB(fp, b), "if app == nil {", stmt) 122 if err != nil { 123 return plugins.Wrap(g, err) 124 } 125 126 f, err := os.Create(fp) 127 if err != nil { 128 return plugins.Wrap(g, err) 129 } 130 defer f.Close() 131 132 _, err = f.WriteString(gf.String()) 133 if err != nil { 134 return plugins.Wrap(g, err) 135 } 136 137 return nil 138 } 139 140 func (g *Generator) afterGenerate(ctx context.Context, root string, args []string, err error) error { 141 plugs := g.ScopedPlugins() 142 143 if err == nil && len(args) > 0 { 144 if err := g.addResource(root, args[0]); err != nil { 145 return plugins.Wrap(g, err) 146 } 147 } 148 149 for _, p := range plugs { 150 if b, ok := p.(AfterGenerator); ok { 151 if err := b.AfterGenerateResource(ctx, root, args, err); err != nil { 152 return plugins.Wrap(b, err) 153 } 154 } 155 } 156 157 return nil 158 } 159 160 // Generate implements generate.Generator and is the entry point for `buffalo generate resource` 161 func (g *Generator) Generate(ctx context.Context, root string, args []string) error { 162 if len(args) == 0 { 163 err := fmt.Errorf("you must specify a name for the resource") 164 return plugins.Wrap(g, err) 165 } 166 167 flags := g.Flags() 168 if err := flags.Parse(args); err != nil { 169 return plugins.Wrap(g, err) 170 } 171 172 args = flags.Args() 173 174 plugs := g.ScopedPlugins() 175 176 if g.help { 177 return plugprint.Print(plugio.Stdout(plugs...), g) 178 } 179 180 err := g.run(ctx, root, args) 181 return g.afterGenerate(ctx, root, args, err) 182 } 183 184 func (g *Generator) run(ctx context.Context, root string, args []string) error { 185 if err := g.beforeGenerate(ctx, root, args); err != nil { 186 return plugins.Wrap(g, err) 187 } 188 189 type step func(context.Context, string, []string) error 190 191 steps := []step{ 192 g.generateActionTests, 193 g.generateActions, 194 g.generateMigrationTests, 195 g.generateMigrations, 196 g.generateModelTests, 197 g.generateModels, 198 g.generateTemplateTests, 199 g.generateTemplates, 200 } 201 202 for i, step := range steps { 203 if err := step(ctx, root, args); err != nil { 204 return fmt.Errorf("(%d) %w", i, plugins.Wrap(g, err)) 205 } 206 } 207 208 return nil 209 } 210 211 func (g *Generator) generateActions(ctx context.Context, root string, args []string) error { 212 if g.skipActions { 213 return nil 214 } 215 216 for _, p := range g.ScopedPlugins() { 217 if ag, ok := p.(Actioner); ok { 218 if err := ag.GenerateResourceActions(ctx, root, args); err != nil { 219 return plugins.Wrap(ag, err) 220 } 221 } 222 } 223 224 return nil 225 } 226 227 func (g *Generator) generateActionTests(ctx context.Context, root string, args []string) error { 228 if g.skipActionTests { 229 return nil 230 } 231 232 for _, p := range g.ScopedPlugins() { 233 if ag, ok := p.(ActionTester); ok { 234 if err := ag.GenerateResourceActionTests(ctx, root, args); err != nil { 235 return plugins.Wrap(ag, err) 236 } 237 } 238 } 239 240 return nil 241 } 242 243 func (g *Generator) generateTemplates(ctx context.Context, root string, args []string) error { 244 if g.skipTemplates { 245 return nil 246 } 247 248 for _, p := range g.ScopedPlugins() { 249 if ag, ok := p.(Templater); ok { 250 if err := ag.GenerateResourceTemplates(ctx, root, args); err != nil { 251 return plugins.Wrap(ag, err) 252 } 253 } 254 } 255 256 return nil 257 } 258 259 func (g *Generator) generateTemplateTests(ctx context.Context, root string, args []string) error { 260 if g.skipTemplateTests { 261 return nil 262 } 263 264 for _, p := range g.ScopedPlugins() { 265 if ag, ok := p.(TemplateTester); ok { 266 if err := ag.GenerateResourceTemplateTests(ctx, root, args); err != nil { 267 return plugins.Wrap(ag, err) 268 } 269 } 270 } 271 272 return nil 273 } 274 275 func (g *Generator) generateModels(ctx context.Context, root string, args []string) error { 276 if g.skipModels { 277 return nil 278 } 279 for _, p := range g.ScopedPlugins() { 280 if ag, ok := p.(Modeler); ok { 281 if err := ag.GenerateResourceModels(ctx, root, args); err != nil { 282 return plugins.Wrap(p, err) 283 } 284 } 285 } 286 return nil 287 } 288 289 func (g *Generator) generateModelTests(ctx context.Context, root string, args []string) error { 290 if g.skipModelTests { 291 return nil 292 } 293 294 for _, p := range g.ScopedPlugins() { 295 if ag, ok := p.(ModelTester); ok { 296 if err := ag.GenerateResourceModelTests(ctx, root, args); err != nil { 297 return plugins.Wrap(ag, err) 298 } 299 } 300 } 301 302 return nil 303 } 304 305 func (g *Generator) generateMigrations(ctx context.Context, root string, args []string) error { 306 if g.skipMigrations { 307 return nil 308 } 309 310 for _, p := range g.ScopedPlugins() { 311 if ag, ok := p.(Migrationer); ok { 312 if err := ag.GenerateResourceMigrations(ctx, root, args); err != nil { 313 return plugins.Wrap(ag, err) 314 } 315 } 316 } 317 318 return nil 319 } 320 321 func (g *Generator) generateMigrationTests(ctx context.Context, root string, args []string) error { 322 if g.skipMigrationTests { 323 return nil 324 } 325 326 for _, p := range g.ScopedPlugins() { 327 if ag, ok := p.(MigrationTester); ok { 328 if err := ag.GenerateResourceMigrationTests(ctx, root, args); err != nil { 329 return plugins.Wrap(ag, err) 330 } 331 } 332 } 333 334 return nil 335 }