github.com/influx6/npkg@v0.8.8/nfs/filefs.go (about)

     1  package nfs
     2  
     3  import (
     4  	"io/ioutil"
     5  	"os"
     6  	"path/filepath"
     7  )
     8  
     9  // FilePortal defines an error which exposes methods to
    10  // treat a underline store has a file system.
    11  type FilePortal interface {
    12  	Name() string
    13  	Has(string) bool
    14  	RemoveAll() error
    15  	Remove(string) error
    16  	Dirs() ([]FilePortal, error)
    17  	Save(string, []byte) error
    18  	Get(string) ([]byte, error)
    19  	Within(string) (FilePortal, error)
    20  }
    21  
    22  // FileFS implements a simple store for storing and retrieving
    23  // file from underneath nfs.
    24  type FileFS struct {
    25  	Dir string
    26  }
    27  
    28  // Within returns a new FilePortal which exists within the current path.
    29  // It enforces all operations to occur within provided path.
    30  func (fs FileFS) Within(path string) (FilePortal, error) {
    31  	return FileFS{Dir: filepath.Join(fs.Dir, path)}, nil
    32  }
    33  
    34  // Name returns underline name of giving FS.
    35  func (fs FileFS) Name() string {
    36  	return filepath.Base(fs.Dir)
    37  }
    38  
    39  // Has return true/false if giving file exists in directory of fs.
    40  func (fs FileFS) Has(file string) bool {
    41  	if _, err := os.Stat(filepath.Join(fs.Dir, file)); err != nil {
    42  		return false
    43  	}
    44  	return true
    45  }
    46  
    47  // Dirs returns all top level directory in file.
    48  func (fs FileFS) Dirs() ([]FilePortal, error) {
    49  	item, err := os.Open(fs.Dir)
    50  	if err != nil {
    51  		return nil, err
    52  	}
    53  
    54  	dirs, err := item.Readdir(-1)
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  
    59  	var portals []FilePortal
    60  	for _, dir := range dirs {
    61  		portals = append(portals, FileFS{
    62  			Dir: filepath.Join(fs.Dir, dir.Name()),
    63  		})
    64  	}
    65  
    66  	return portals, nil
    67  }
    68  
    69  // Save saves giving file into FileFS.Dir, overwriting any same file
    70  // existing.
    71  func (fs FileFS) Save(file string, data []byte) error {
    72  	targetPath := filepath.Join(fs.Dir, file)
    73  	targetDir := filepath.Dir(targetPath)
    74  
    75  	if _, err := os.Stat(targetDir); err != nil {
    76  		if mkerr := os.MkdirAll(targetDir, 0700); mkerr != nil {
    77  			return mkerr
    78  		}
    79  	}
    80  
    81  	targetFile, err := os.Create(targetPath)
    82  	if err != nil {
    83  		return err
    84  	}
    85  
    86  	defer targetFile.Close()
    87  
    88  	_, err = targetFile.Write(data)
    89  	return err
    90  }
    91  
    92  // RemoveAll removes all files within FileFS.Dir and contents.
    93  func (fs FileFS) RemoveAll() error {
    94  	if err := os.RemoveAll(fs.Dir); err != nil {
    95  		if perr, ok := err.(*os.PathError); ok && perr.Err == os.ErrNotExist {
    96  			return nil
    97  		}
    98  		return err
    99  	}
   100  	return nil
   101  }
   102  
   103  // Remove deletes giving file path within FileFS.Dir.
   104  func (fs FileFS) Remove(file string) error {
   105  	targetFile := filepath.Join(fs.Dir, file)
   106  	if _, err := os.Stat(targetFile); err != nil {
   107  		return nil
   108  	}
   109  
   110  	return os.Remove(targetFile)
   111  }
   112  
   113  // Get retrieves giving file path within FileFS.Dir.
   114  func (fs FileFS) Get(file string) ([]byte, error) {
   115  	targetFile := filepath.Join(fs.Dir, file)
   116  	if _, err := os.Stat(targetFile); err != nil {
   117  		return nil, err
   118  	}
   119  
   120  	return ioutil.ReadFile(targetFile)
   121  }