github.com/wynshop-open-source/gomplate@v3.5.0+incompatible/file/file.go (about) 1 // Package file contains functions for working with files and directories on the local filesystem 2 package file 3 4 import ( 5 "io/ioutil" 6 "os" 7 "path/filepath" 8 "strings" 9 10 "github.com/pkg/errors" 11 12 "github.com/spf13/afero" 13 ) 14 15 // for overriding in tests 16 var fs = afero.NewOsFs() 17 18 // Read - 19 func Read(filename string) (string, error) { 20 inFile, err := fs.OpenFile(filename, os.O_RDONLY, 0) 21 if err != nil { 22 return "", errors.Wrapf(err, "failed to open %s", filename) 23 } 24 // nolint: errcheck 25 defer inFile.Close() 26 bytes, err := ioutil.ReadAll(inFile) 27 if err != nil { 28 err = errors.Wrapf(err, "read failed for %s", filename) 29 return "", err 30 } 31 return string(bytes), nil 32 } 33 34 // ReadDir - 35 func ReadDir(path string) ([]string, error) { 36 f, err := fs.Open(path) 37 if err != nil { 38 return nil, err 39 } 40 i, err := f.Stat() 41 if err != nil { 42 return nil, err 43 } 44 if i.IsDir() { 45 return f.Readdirnames(0) 46 } 47 return nil, errors.New("file is not a directory") 48 } 49 50 // Write a 51 func Write(filename string, content []byte) error { 52 err := assertPathInWD(filename) 53 if err != nil { 54 return errors.Wrapf(err, "failed to open %s", filename) 55 } 56 57 fi, err := os.Stat(filename) 58 if err != nil && !os.IsNotExist(err) { 59 return errors.Wrapf(err, "failed to stat %s", filename) 60 } 61 mode := os.FileMode(0644) 62 if fi != nil { 63 mode = fi.Mode() 64 } 65 err = fs.MkdirAll(filepath.Dir(filename), 0755) 66 if err != nil { 67 return errors.Wrapf(err, "failed to make dirs for %s", filename) 68 } 69 inFile, err := fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, mode) 70 if err != nil { 71 return errors.Wrapf(err, "failed to open %s", filename) 72 } 73 n, err := inFile.Write(content) 74 if err != nil { 75 return errors.Wrapf(err, "failed to write %s", filename) 76 } 77 if n != len(content) { 78 return errors.Wrapf(err, "short write on %s (%d bytes)", filename, n) 79 } 80 return nil 81 } 82 83 func assertPathInWD(filename string) error { 84 wd, err := os.Getwd() 85 if err != nil { 86 return err 87 } 88 f, err := filepath.Abs(filename) 89 if err != nil { 90 return err 91 } 92 r, err := filepath.Rel(wd, f) 93 if err != nil { 94 return err 95 } 96 if strings.HasPrefix(r, "..") { 97 return errors.Errorf("path %s not contained by working directory %s (rel: %s)", filename, wd, r) 98 } 99 return nil 100 }