github.com/lenfree/buffalo@v0.7.3-0.20170207163156-891616ea4064/buffalo/cmd/generate/action.go (about) 1 package generate 2 3 import ( 4 "errors" 5 "fmt" 6 "io/ioutil" 7 "os" 8 "path/filepath" 9 "strings" 10 11 "github.com/markbates/gentronics" 12 "github.com/markbates/inflect" 13 "github.com/spf13/cobra" 14 ) 15 16 var runningTests = false 17 18 //ActionCmd is the cmd that generates actions. 19 var ActionCmd = &cobra.Command{ 20 Use: "action [name] [actionName...]", 21 Aliases: []string{"a", "actions"}, 22 Short: "Generates new action(s)", 23 RunE: func(cmd *cobra.Command, args []string) error { 24 if len(args) < 2 { 25 return errors.New("you should provide action name and handler name at least") 26 } 27 28 if _, err := os.Stat("actions"); err != nil { 29 return errors.New("actions directory not found, ensure you're inside your buffalo folder") 30 } 31 32 name := args[0] 33 actions := args[1:] 34 35 data := gentronics.Data{ 36 "filename": inflect.Underscore(name), 37 "namespace": inflect.Camelize(name), 38 } 39 40 filePath := filepath.Join("actions", fmt.Sprintf("%v.go", data["filename"])) 41 actionsTemplate := buildActionsTemplate(filePath) 42 testFilePath := filepath.Join("actions", fmt.Sprintf("%v_test.go", data["filename"])) 43 testsTemplate := buildTestsTemplate(testFilePath) 44 actionsToAdd := findActionsToAdd(name, filePath, actions) 45 testsToAdd := findTestsToAdd(name, testFilePath, actions) 46 47 data["actions"] = actionsToAdd 48 data["tests"] = testsToAdd 49 50 g := gentronics.New() 51 g.Add(gentronics.NewFile(filepath.Join("actions", fmt.Sprintf("%s.go", data["filename"])), actionsTemplate)) 52 g.Add(gentronics.NewFile(filepath.Join("actions", fmt.Sprintf("%s_test.go", data["filename"])), testsTemplate)) 53 g.Add(&gentronics.Func{ 54 Should: func(data gentronics.Data) bool { return true }, 55 Runner: func(root string, data gentronics.Data) error { 56 routes := []string{} 57 for _, a := range actions { 58 routes = append(routes, fmt.Sprintf("app.GET(\"/%s/%s\", %s)", name, a, data["namespace"].(string)+inflect.Camelize(a))) 59 } 60 return addInsideAppBlock(routes...) 61 }, 62 }) 63 addTemplateFiles(actionsToAdd, data) 64 65 if !runningTests { 66 g.Add(Fmt) 67 } 68 69 return g.Run(".", data) 70 }, 71 } 72 73 func buildActionsTemplate(filePath string) string { 74 actionsTemplate := rActionFileT 75 fileContents, err := ioutil.ReadFile(filePath) 76 if err == nil { 77 actionsTemplate = string(fileContents) 78 } 79 80 actionsTemplate = actionsTemplate + ` 81 {{#each actions as |action|}} 82 // {{namespace}}{{camelize action}} default implementation. 83 func {{namespace}}{{camelize action}}(c buffalo.Context) error { 84 return c.Render(200, r.HTML("{{filename}}/{{underscore action}}.html")) 85 } 86 {{/each}}` 87 return actionsTemplate 88 } 89 90 func buildTestsTemplate(filePath string) string { 91 testsTemplate := `package actions_test 92 93 import ( 94 "testing" 95 96 "github.com/stretchr/testify/require" 97 ) 98 ` 99 fileContents, err := ioutil.ReadFile(filePath) 100 if err == nil { 101 testsTemplate = string(fileContents) 102 } 103 104 testsTemplate = testsTemplate + ` 105 {{#each tests as |action|}} 106 func Test_{{namespace}}_{{camelize action}}(t *testing.T) { 107 r := require.New(t) 108 r.Fail("Not Implemented!") 109 } 110 111 {{/each}}` 112 return testsTemplate 113 } 114 115 func addTemplateFiles(actionsToAdd []string, data gentronics.Data) { 116 for _, action := range actionsToAdd { 117 vg := gentronics.New() 118 viewPath := filepath.Join("templates", fmt.Sprintf("%s", data["filename"]), fmt.Sprintf("%s.html", inflect.Underscore(action))) 119 vg.Add(gentronics.NewFile(viewPath, rViewT)) 120 vg.Run(".", gentronics.Data{ 121 "namespace": data["namespace"], 122 "action": inflect.Camelize(action), 123 }) 124 } 125 } 126 127 func findActionsToAdd(name, path string, actions []string) []string { 128 fileContents, err := ioutil.ReadFile(path) 129 if err != nil { 130 fileContents = []byte("") 131 } 132 133 actionsToAdd := []string{} 134 135 for _, action := range actions { 136 funcSignature := fmt.Sprintf("func %s%s(c buffalo.Context) error", inflect.Camelize(name), inflect.Camelize(action)) 137 if strings.Contains(string(fileContents), funcSignature) { 138 fmt.Printf("--> [warning] skipping %v%v since it already exists\n", inflect.Camelize(name), inflect.Camelize(action)) 139 continue 140 } 141 142 actionsToAdd = append(actionsToAdd, action) 143 } 144 145 return actionsToAdd 146 } 147 148 func findTestsToAdd(name, path string, actions []string) []string { 149 fileContents, err := ioutil.ReadFile(path) 150 if err != nil { 151 fileContents = []byte("") 152 } 153 154 actionsToAdd := []string{} 155 156 for _, action := range actions { 157 funcSignature := fmt.Sprintf("func Test_%v_%v(c buffalo.Context) error", inflect.Camelize(name), inflect.Camelize(action)) 158 if strings.Contains(string(fileContents), funcSignature) { 159 fmt.Printf("--> [warning] skipping Test_%v_%v since it already exists\n", inflect.Camelize(name), inflect.Camelize(action)) 160 continue 161 } 162 163 actionsToAdd = append(actionsToAdd, action) 164 } 165 166 return actionsToAdd 167 } 168 169 const ( 170 rActionFileT = `package actions 171 import "github.com/gobuffalo/buffalo"` 172 173 rViewT = `<h1>{{namespace}}#{{action}}</h1>` 174 rActionFuncT = ` 175 // {{namespace}}{{action}} default implementation. 176 func {{namespace}}{{action}}(c buffalo.Context) error { 177 return c.Render(200, r.HTML("{{namespace_under}}/{{action_under}}.html")) 178 } 179 ` 180 )