diff --git a/pkging/pkgtest/suite.go b/pkging/pkgtest/suite.go index af4fe78..7fbdc40 100644 --- a/pkging/pkgtest/suite.go +++ b/pkging/pkgtest/suite.go @@ -250,22 +250,21 @@ func (s Suite) Test_Open_File(t *testing.T) { body := "!" + pt.String() - f1, err := s.Create(tt.in) + pkgutil.WriteFile(s, tt.in, []byte(body), 0644) + + f, err := s.Open(tt.in) r.NoError(err) - _, err = io.Copy(f1, strings.NewReader(body)) - r.NoError(err) - r.NoError(f1.Close()) - - f2, err := s.Open(tt.in) - r.NoError(err) - - r.Equal(pt.Name, f2.Path().Name) - b, err := ioutil.ReadAll(f2) + r.Equal(pt.Name, f.Path().Name) + b, err := ioutil.ReadAll(f) r.NoError(err) r.Equal(body, string(b)) - r.NoError(f2.Close()) + b, err = pkgutil.ReadFile(s, tt.in) + r.NoError(err) + r.Equal(body, string(b)) + + r.NoError(f.Close()) }) } } diff --git a/pkging/pkgutil/file.go b/pkging/pkgutil/file.go index b7505a7..fb4760c 100644 --- a/pkging/pkgutil/file.go +++ b/pkging/pkgutil/file.go @@ -1,13 +1,43 @@ package pkgutil import ( + "io" "io/ioutil" + "os" + "sort" "github.com/markbates/pkger/pkging" ) +type Opener interface { + Open(name string) (pkging.File, error) +} + +type Creator interface { + Create(name string) (pkging.File, error) +} + +type OpenFiler interface { + OpenFile(name string, flag int, perm os.FileMode) (pkging.File, error) +} + +// ReadDir reads the directory named by dirname and returns a list of directory entries sorted by filename. +func ReadDir(pkg Opener, dirname string) ([]os.FileInfo, error) { + f, err := pkg.Open(dirname) + if err != nil { + return nil, err + } + list, err := f.Readdir(-1) + f.Close() + if err != nil { + return nil, err + } + sort.Slice(list, func(i, j int) bool { return list[i].Name() < list[j].Name() }) + return list, nil +} + // ReadFile reads the file named by filename and returns the contents. A successful call returns err == nil, not err == EOF. Because ReadFile reads the whole file, it does not treat an EOF from Read as an error to be reported. -func ReadFile(pkg pkging.Pkger, s string) ([]byte, error) { +func ReadFile(pkg Opener, s string) ([]byte, error) { f, err := pkg.Open(s) if err != nil { return nil, err @@ -15,3 +45,32 @@ func ReadFile(pkg pkging.Pkger, s string) ([]byte, error) { defer f.Close() return ioutil.ReadAll(f) } + +// WriteFile writes data to a file named by filename. If the file does not exist, WriteFile creates it with permissions perm; otherwise WriteFile truncates it before writing. +func WriteFile(pkg Creator, filename string, data []byte, perm os.FileMode) error { + var f pkging.File + var err error + + if of, ok := pkg.(OpenFiler); ok { + f, err = of.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, perm) + if err != nil { + return err + } + } + + if f == nil { + f, err = pkg.Create(filename) + if err != nil { + return err + } + } + + n, err := f.Write(data) + if err == nil && n < len(data) { + err = io.ErrShortWrite + } + if err1 := f.Close(); err == nil { + err = err1 + } + return err +} diff --git a/pkging/stdos/stdos.go b/pkging/stdos/stdos.go index 44ffa0e..d88d148 100644 --- a/pkging/stdos/stdos.go +++ b/pkging/stdos/stdos.go @@ -20,6 +20,18 @@ type Pkger struct { current here.Info } +func (p *Pkger) OpenFile(name string, flag int, perm os.FileMode) (pkging.File, error) { + name, err := p.Abs(name) + if err != nil { + return nil, err + } + f, err := os.OpenFile(name, flag, perm) + if err != nil { + return nil, err + } + return NewFile(p, f) +} + func (f *Pkger) Abs(p string) (string, error) { pt, err := f.Parse(p) if err != nil {