github.com/grafana/tanka@v0.26.1-0.20240506093700-c22cfc35c21a/pkg/tanka/format.go (about) 1 package tanka 2 3 import ( 4 "fmt" 5 "os" 6 7 "github.com/gobwas/glob" 8 "github.com/google/go-jsonnet/formatter" 9 "github.com/grafana/tanka/pkg/jsonnet" 10 "github.com/pkg/errors" 11 ) 12 13 // FormatOpts modify the behaviour of Format 14 type FormatOpts struct { 15 // Excludes are a list of globs to exclude files while searching for Jsonnet 16 // files 17 Excludes []glob.Glob 18 19 // OutFn receives the formatted file and it's name. If left nil, the file 20 // will be formatted in place. 21 OutFn OutFn 22 23 // PrintNames causes all filenames to be printed 24 PrintNames bool 25 } 26 27 // OutFn is a function that receives the formatted file for further action, 28 // like persisting to disc 29 type OutFn func(name, content string) error 30 31 // FormatFiles takes a list of files and directories, processes them and returns 32 // which files were formatted and perhaps an error. 33 func FormatFiles(fds []string, opts *FormatOpts) ([]string, error) { 34 var paths []string 35 for _, f := range fds { 36 fs, err := jsonnet.FindFiles(f, opts.Excludes) 37 if err != nil { 38 return nil, errors.Wrap(err, "finding Jsonnet files") 39 } 40 paths = append(paths, fs...) 41 } 42 43 // if nothing defined, default to save inplace 44 outFn := opts.OutFn 45 if outFn == nil { 46 outFn = func(name, content string) error { 47 return os.WriteFile(name, []byte(content), 0644) 48 } 49 } 50 51 // print each file? 52 printFn := func(...interface{}) {} 53 if opts.PrintNames { 54 printFn = func(i ...interface{}) { fmt.Println(i...) } 55 } 56 57 var changed []string 58 for _, p := range paths { 59 content, err := os.ReadFile(p) 60 if err != nil { 61 return nil, err 62 } 63 64 formatted, err := Format(p, string(content)) 65 if err != nil { 66 return nil, err 67 } 68 69 if string(content) != formatted { 70 printFn("fmt", p) 71 changed = append(changed, p) 72 } else { 73 printFn("ok ", p) 74 } 75 76 if err := outFn(p, formatted); err != nil { 77 return nil, err 78 } 79 } 80 81 return changed, nil 82 } 83 84 // Format takes a file's name and contents and returns them in properly 85 // formatted. The file does not have to exist on disk. 86 func Format(filename string, content string) (string, error) { 87 return formatter.Format(filename, content, formatter.DefaultOptions()) 88 }