github.com/JarrahG/buffalocli@v0.0.0-20230801092127-b85bfd5d395a/internal/genny/fix/deprecations.go (about)

     1  package fix
     2  
     3  import (
     4  	"bytes"
     5  	"fmt"
     6  	"go/ast"
     7  	"go/format"
     8  	"go/parser"
     9  	"go/printer"
    10  	"go/token"
    11  	"io"
    12  	"os"
    13  	"path/filepath"
    14  	"regexp"
    15  	"strings"
    16  
    17  	"github.com/gobuffalo/genny/v2"
    18  	"golang.org/x/tools/go/ast/astutil"
    19  )
    20  
    21  // DeprecationsCheck will either log, or fix, deprecated items in the application
    22  func DeprecationsCheck(opts *Options) genny.RunFn {
    23  	return func(r *genny.Runner) error {
    24  		fmt.Println("~~~ Checking for deprecations ~~~")
    25  		f, err := r.FindFile("cmd/app/main.go")
    26  		if err != nil {
    27  			return err
    28  		}
    29  
    30  		if strings.Contains(f.String(), "app.Start") {
    31  			opts.warnings = append(opts.warnings, "app.Start has been removed in v0.11.0. Use app.Serve Instead. [main.go]")
    32  		}
    33  
    34  		err = walkDisk(r.Disk, "actions", packrMigrateFun(r, opts))
    35  		if err != nil {
    36  			return err
    37  		}
    38  
    39  		return walkDisk(r.Disk, ".", updateSuiteFun(r, opts))
    40  	}
    41  }
    42  
    43  func packrMigrateFun(r *genny.Runner, opts *Options) func(path string, info os.FileInfo, err error) error {
    44  	return func(path string, info os.FileInfo, err error) error {
    45  		if err != nil {
    46  			return err
    47  		}
    48  
    49  		if info.IsDir() {
    50  			return nil
    51  		}
    52  
    53  		if filepath.Ext(path) != ".go" {
    54  			return nil
    55  		}
    56  
    57  		f, err := r.FindFile(path)
    58  		if err != nil {
    59  			return err
    60  		}
    61  		b, err := io.ReadAll(f)
    62  		if err != nil {
    63  			return err
    64  		}
    65  
    66  		if bytes.Contains(b, []byte("AssetsBox")) {
    67  			b, err = addImport(path, b, fmt.Sprintf("%s/public", opts.App.PackagePkg))
    68  			if err != nil {
    69  				return err
    70  			}
    71  
    72  			rx := regexp.MustCompile("AssetsBox:.*,")
    73  			b = rx.ReplaceAll(b, []byte("AssetsFS: public.FS(),"))
    74  
    75  			rx = regexp.MustCompile(`(?m)^.*assetsBox.*=.*packr\.New.*$`)
    76  			b = rx.ReplaceAll(b, []byte(""))
    77  		}
    78  
    79  		if bytes.Contains(b, []byte("TemplatesBox")) {
    80  			b, err = addImport(path, b, fmt.Sprintf("%s/templates", opts.App.PackagePkg))
    81  			if err != nil {
    82  				return err
    83  			}
    84  
    85  			rx := regexp.MustCompile("TemplatesBox:.*,")
    86  			b = rx.ReplaceAll(b, []byte("TemplatesFS: templates.FS(),"))
    87  		}
    88  
    89  		rx := regexp.MustCompile(`i18n\.New\(packr\.New\(.*\),(?P<Lang>.*)\)`)
    90  		if rx.Match(b) {
    91  			b, err = addImport(path, b, fmt.Sprintf("%s/locales", opts.App.PackagePkg))
    92  			if err != nil {
    93  				return err
    94  			}
    95  
    96  			match := rx.FindSubmatch(b)
    97  			new := fmt.Sprintf("i18n.New(locales.FS(),%s)", match[1])
    98  			b = rx.ReplaceAll(b, []byte(new))
    99  		}
   100  
   101  		if bytes.Contains(b, []byte("app.ServeFiles(\"/\", assetsBox)")) {
   102  			b, err = addImport(path, b, fmt.Sprintf("%s/public", opts.App.PackagePkg))
   103  			if err != nil {
   104  				return err
   105  			}
   106  
   107  			b, err = addImport(path, b, "net/http")
   108  			if err != nil {
   109  				return err
   110  			}
   111  
   112  			rx := regexp.MustCompile(`app\.ServeFiles\(.*assetsBox\)`)
   113  			b = rx.ReplaceAll(b, []byte("app.ServeFiles(\"/\", http.FS(public.FS()))"))
   114  		}
   115  
   116  		b, err = format.Source(b)
   117  		if err != nil {
   118  			return err
   119  		}
   120  
   121  		if _, err := f.Write(b); err != nil {
   122  			return err
   123  		}
   124  		return r.File(f)
   125  	}
   126  }
   127  
   128  func updateSuiteFun(r *genny.Runner, opts *Options) func(path string, info os.FileInfo, err error) error {
   129  	return func(path string, info os.FileInfo, err error) error {
   130  		if err != nil {
   131  			return err
   132  		}
   133  
   134  		if info.IsDir() {
   135  			return nil
   136  		}
   137  
   138  		if filepath.Ext(path) != ".go" {
   139  			return nil
   140  		}
   141  
   142  		f, err := r.FindFile(path)
   143  		if err != nil {
   144  			return err
   145  		}
   146  		b, err := io.ReadAll(f)
   147  		if err != nil {
   148  			return err
   149  		}
   150  
   151  		rx := regexp.MustCompile(`suite\.NewModelWithFixtures\(packr\.New\(".*", (?P<path>.*)\)\)`)
   152  		if rx.Match(b) {
   153  			b, err = addImport(path, b, "os")
   154  			if err != nil {
   155  				return err
   156  			}
   157  
   158  			match := rx.FindSubmatch(b)
   159  			new := fmt.Sprintf("suite.NewModelWithFixtures(os.DirFS(%s))", match[1])
   160  			b = rx.ReplaceAll(b, []byte(new))
   161  		}
   162  
   163  		rx = regexp.MustCompile(`suite\.NewActionWithFixtures\((?P<app>.*), packr\.New\(".*", (?P<path>.*)\)\)`)
   164  		if rx.Match(b) {
   165  			b, err = addImport(path, b, "os")
   166  			if err != nil {
   167  				return err
   168  			}
   169  
   170  			match := rx.FindSubmatch(b)
   171  			new := fmt.Sprintf("suite.NewActionWithFixtures(%s, os.DirFS(%s))", match[1], match[2])
   172  			b = rx.ReplaceAll(b, []byte(new))
   173  		}
   174  
   175  		b, err = format.Source(b)
   176  		if err != nil {
   177  			return err
   178  		}
   179  
   180  		if _, err := f.Write(b); err != nil {
   181  			return err
   182  		}
   183  		return r.File(f)
   184  	}
   185  }
   186  
   187  func addImport(path string, src []byte, value string) ([]byte, error) {
   188  	fset := token.NewFileSet()
   189  	f, err := parser.ParseFile(fset, path, src, parser.ParseComments)
   190  	if err != nil {
   191  		return nil, err
   192  	}
   193  
   194  	astutil.AddImport(fset, f, value)
   195  	ast.SortImports(fset, f)
   196  
   197  	bb := &bytes.Buffer{}
   198  	err = printer.Fprint(bb, fset, f)
   199  	return bb.Bytes(), err
   200  }