github.com/Datadog/cnab-go@v0.3.3-beta1.0.20191007143216-bba4b7e723d0/utils/crud/filesystem.go (about)

     1  package crud
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"io/ioutil"
     7  	"os"
     8  	"path/filepath"
     9  	"strings"
    10  )
    11  
    12  // ErrRecordDoesNotExist represents when file path is not found on file system
    13  var ErrRecordDoesNotExist = errors.New("File does not exist")
    14  
    15  // NewFileSystemStore creates a Store backed by a file system directory.
    16  // Each key is represented by a file in that directory.
    17  func NewFileSystemStore(baseDirectory string, fileExtension string) Store {
    18  	return fileSystemStore{
    19  		baseDirectory: baseDirectory,
    20  		fileExtension: fileExtension,
    21  	}
    22  }
    23  
    24  type fileSystemStore struct {
    25  	baseDirectory string
    26  	fileExtension string
    27  }
    28  
    29  func (s fileSystemStore) List() ([]string, error) {
    30  	if err := s.ensure(); err != nil {
    31  		return nil, err
    32  	}
    33  
    34  	files, err := ioutil.ReadDir(s.baseDirectory)
    35  	if err != nil {
    36  		return []string{}, err
    37  	}
    38  
    39  	return names(s.storageFiles(files)), nil
    40  }
    41  
    42  func (s fileSystemStore) Store(name string, data []byte) error {
    43  	filename, err := s.fullyQualifiedName(name)
    44  	if err != nil {
    45  		return err
    46  	}
    47  
    48  	return ioutil.WriteFile(filename, data, os.ModePerm)
    49  }
    50  
    51  func (s fileSystemStore) Read(name string) ([]byte, error) {
    52  	filename, err := s.fullyQualifiedName(name)
    53  	if err != nil {
    54  		return nil, err
    55  	}
    56  
    57  	if _, err := os.Stat(filename); os.IsNotExist(err) {
    58  		return nil, ErrRecordDoesNotExist
    59  	}
    60  
    61  	return ioutil.ReadFile(filename)
    62  }
    63  
    64  func (s fileSystemStore) Delete(name string) error {
    65  	filename, err := s.fullyQualifiedName(name)
    66  	if err != nil {
    67  		return err
    68  	}
    69  	return os.Remove(filename)
    70  }
    71  
    72  func (s fileSystemStore) fileNameOf(name string) string {
    73  	return filepath.Join(s.baseDirectory, fmt.Sprintf("%s.%s", name, s.fileExtension))
    74  }
    75  
    76  func (s fileSystemStore) fullyQualifiedName(name string) (string, error) {
    77  	if err := s.ensure(); err != nil {
    78  		return "", err
    79  	}
    80  	return s.fileNameOf(name), nil
    81  }
    82  
    83  func (s fileSystemStore) ensure() error {
    84  	fi, err := os.Stat(s.baseDirectory)
    85  	if err == nil {
    86  		if fi.IsDir() {
    87  			return nil
    88  		}
    89  		return errors.New("Storage directory name exists, but is not a directory")
    90  	}
    91  	return os.MkdirAll(s.baseDirectory, os.ModePerm)
    92  }
    93  
    94  func (s fileSystemStore) storageFiles(files []os.FileInfo) []os.FileInfo {
    95  	result := make([]os.FileInfo, 0)
    96  	ext := "." + s.fileExtension
    97  	for _, file := range files {
    98  		if !file.IsDir() && filepath.Ext(file.Name()) == ext {
    99  			result = append(result, file)
   100  		}
   101  	}
   102  	return result
   103  }
   104  
   105  func names(files []os.FileInfo) []string {
   106  	result := make([]string, 0)
   107  	for _, file := range files {
   108  		result = append(result, name(file.Name()))
   109  	}
   110  	return result
   111  }
   112  
   113  func name(filename string) string {
   114  	return strings.TrimSuffix(filepath.Base(filename), filepath.Ext(filename))
   115  }