github.com/jackgris/buffalo@v0.10.3-0.20171206174715-b1dbfd2402de/generators/helpers.go (about) 1 package generators 2 3 import ( 4 "errors" 5 "fmt" 6 "go/ast" 7 "go/parser" 8 "go/token" 9 "io/ioutil" 10 "strings" 11 ) 12 13 // AddRoute adds a new route inside the `action/app.go` file. 14 func AddRoute(method, path, handlerName string) error { 15 routeDefinition := fmt.Sprintf(`app.%v("%v", %v)`, method, path, handlerName) 16 return AddInsideAppBlock(routeDefinition) 17 } 18 19 // AddInsideAppBlock will add anything inside of the app declaration block inside of `actions/app.go` 20 func AddInsideAppBlock(expressions ...string) error { 21 src, err := ioutil.ReadFile("actions/app.go") 22 if err != nil { 23 return err 24 } 25 26 fset := token.NewFileSet() 27 f, err := parser.ParseFile(fset, "actions/app.go", string(src), 0) 28 if err != nil { 29 return err 30 } 31 32 srcContent := string(src) 33 fileLines := strings.Split(srcContent, "\n") 34 35 end := findClosingRouteBlockEnd(f, fset, fileLines) 36 if end < 0 { 37 return errors.New("could not find desired block on the app.go file") 38 } 39 40 for i := 0; i < len(expressions); i++ { 41 expressions[i] = fmt.Sprintf("\t\t%s", expressions[i]) 42 } 43 fileLines = append(fileLines[:end], append(expressions, fileLines[end:]...)...) 44 45 fileContent := strings.Join(fileLines, "\n") 46 err = ioutil.WriteFile("actions/app.go", []byte(fileContent), 0755) 47 return err 48 } 49 50 func findClosingRouteBlockEnd(f *ast.File, fset *token.FileSet, fileLines []string) int { 51 var end = -1 52 53 ast.Inspect(f, func(n ast.Node) bool { 54 switch x := n.(type) { 55 case *ast.BlockStmt: 56 start := fset.Position(x.Lbrace).Line 57 blockDeclaration := fmt.Sprintf("%s\n", fileLines[start-1]) 58 59 if strings.Contains(blockDeclaration, "if app == nil {") { 60 end = fset.Position(x.Rbrace).Line - 1 61 } 62 63 } 64 return true 65 }) 66 67 return end 68 } 69 70 // AddImport adds n number of import statements into the path provided 71 func AddImport(path string, imports ...string) error { 72 src, err := ioutil.ReadFile(path) 73 if err != nil { 74 return err 75 } 76 77 fset := token.NewFileSet() 78 f, err := parser.ParseFile(fset, path, string(src), 0) 79 if err != nil { 80 return err 81 } 82 83 srcContent := string(src) 84 fileLines := strings.Split(srcContent, "\n") 85 86 end := findLastImport(f, fset, fileLines) 87 88 x := make([]string, len(imports), len(imports)+2) 89 for _, i := range imports { 90 x = append(x, fmt.Sprintf("\t\"%s\"", i)) 91 92 } 93 if end < 0 { 94 x = append([]string{"import ("}, x...) 95 x = append(x, ")") 96 } 97 98 fileLines = append(fileLines[:end], append(x, fileLines[end:]...)...) 99 100 fileContent := strings.Join(fileLines, "\n") 101 err = ioutil.WriteFile(path, []byte(fileContent), 0755) 102 return err 103 } 104 105 func findLastImport(f *ast.File, fset *token.FileSet, fileLines []string) int { 106 var end = -1 107 108 ast.Inspect(f, func(n ast.Node) bool { 109 switch x := n.(type) { 110 case *ast.ImportSpec: 111 end = fset.Position(x.End()).Line 112 return true 113 } 114 return true 115 }) 116 117 return end 118 }