github.com/JarrahG/buffalocli@v0.0.0-20230801092127-b85bfd5d395a/internal/genny/fix/imports.go (about) 1 package fix 2 3 import ( 4 "bytes" 5 "fmt" 6 "go/ast" 7 "go/parser" 8 "go/printer" 9 "go/token" 10 "os" 11 "path/filepath" 12 "strconv" 13 14 "github.com/gobuffalo/genny/v2" 15 "golang.org/x/tools/go/ast/astutil" 16 ) 17 18 var replace = map[string]string{ 19 "github.com/gobuffalo/buffalo-plugins": "github.com/JarrahG/buffalocli/internal/plugins", 20 "github.com/gobuffalo/buffalo-pop/": "github.com/gobuffalo/buffalo-pop/v3", 21 "github.com/gobuffalo/buffalo-pop/v2/": "github.com/gobuffalo/buffalo-pop/v3", 22 "github.com/gobuffalo/buffalo-pop/pop/popmw": "github.com/gobuffalo/buffalo-pop/v3/pop/popmw", 23 "github.com/gobuffalo/buffalo-pop/v2/pop/popmw": "github.com/gobuffalo/buffalo-pop/v3/pop/popmw", 24 "github.com/gobuffalo/genny": "github.com/gobuffalo/genny/v2", 25 "github.com/gobuffalo/mw-contenttype": "github.com/gobuffalo/middleware/contenttype", 26 "github.com/gobuffalo/mw-csrf": "github.com/gobuffalo/middleware/csrf", 27 "github.com/gobuffalo/mw-forcessl": "github.com/gobuffalo/middleware/forcessl", 28 "github.com/gobuffalo/mw-i18n": "github.com/gobuffalo/middleware/i18n", 29 "github.com/gobuffalo/mw-i18n/v2": "github.com/gobuffalo/middleware/i18n", 30 "github.com/gobuffalo/mw-paramlogger": "github.com/gobuffalo/middleware/paramlogger", 31 "github.com/gobuffalo/packr/v2": "", 32 "github.com/gobuffalo/plush": "github.com/gobuffalo/plush/v4", 33 "github.com/gobuffalo/pop": "github.com/gobuffalo/pop/v6", 34 "github.com/gobuffalo/pop/v5": "github.com/gobuffalo/pop/v6", 35 "github.com/gobuffalo/pop/nulls": "github.com/gobuffalo/nulls", 36 "github.com/gobuffalo/suite": "github.com/gobuffalo/suite/v4", 37 "github.com/gobuffalo/uuid": "github.com/gofrs/uuid", 38 "github.com/gobuffalo/validate": "github.com/gobuffalo/validate/v3", 39 "github.com/gobuffalo/validate/validators": "github.com/gobuffalo/validate/v3/validators", 40 "github.com/markbates/grift": "github.com/gobuffalo/grift", 41 "github.com/markbates/grift/grift": "github.com/gobuffalo/grift/grift", 42 "github.com/markbates/pop": "github.com/gobuffalo/pop/v6", 43 "github.com/markbates/refresh": "github.com/gobuffalo/refresh", 44 "github.com/markbates/validate": "github.com/gobuffalo/validate/v3", 45 "github.com/markbates/willie": "github.com/gobuffalo/httptest", 46 "github.com/satori/go.uuid": "github.com/gofrs/uuid", 47 "github.com/shurcooL/github_flavored_markdown": "github.com/gobuffalo/github_flavored_markdown", 48 } 49 50 // RewriteImports walks all the .go files in an application 51 // It will then attempt to convert any old import paths to any new import paths 52 // used by this version Buffalo. 53 func RewriteImports(opts *Options) genny.RunFn { 54 return func(r *genny.Runner) error { 55 fmt.Println("~~~ Rewriting Imports ~~~") 56 return walkDisk(r.Disk, ".", func(path string, info os.FileInfo, err error) error { 57 if err != nil { 58 return err 59 } 60 61 if info.IsDir() { 62 return nil 63 } 64 65 if filepath.Ext(path) != ".go" { 66 return nil 67 } 68 69 f, err := r.FindFile(path) 70 if err != nil { 71 return err 72 } 73 if err := rewriteImports(f); err != nil { 74 return err 75 } 76 return r.File(f) 77 }) 78 } 79 } 80 81 func rewriteImports(file genny.File) error { 82 fset := token.NewFileSet() 83 f, err := parser.ParseFile(fset, file.Name(), file.String(), parser.ParseComments) 84 if err != nil { 85 return err 86 } 87 88 names := make(map[string]string) 89 for _, imports := range astutil.Imports(fset, f) { 90 for _, imp := range imports { 91 i, err := strconv.Unquote(imp.Path.Value) 92 if err != nil { 93 return err 94 } 95 if imp.Name != nil { 96 names[i] = imp.Name.Name 97 } else { 98 names[i] = "" 99 } 100 } 101 } 102 103 changed := false 104 for key, value := range replace { 105 name, ok := names[key] 106 if !ok { 107 continue 108 } 109 110 astutil.DeleteNamedImport(fset, f, name, key) 111 if value != "" { 112 astutil.AddNamedImport(fset, f, names[key], value) 113 } 114 115 changed = true 116 } 117 118 // if no change occurred, then we don't need to write to disk, just return. 119 if !changed { 120 return nil 121 } 122 123 // since the imports changed, resort them. 124 ast.SortImports(fset, f) 125 126 bb := &bytes.Buffer{} 127 if err := printer.Fprint(bb, fset, f); err != nil { 128 return err 129 } 130 131 _, err = file.Write(bb.Bytes()) 132 return err 133 }