aboutsummaryrefslogtreecommitdiffstats
path: root/utils/fs
diff options
context:
space:
mode:
Diffstat (limited to 'utils/fs')
-rw-r--r--utils/fs/fs.go46
-rw-r--r--utils/fs/os.go128
-rw-r--r--utils/fs/os_test.go153
3 files changed, 178 insertions, 149 deletions
diff --git a/utils/fs/fs.go b/utils/fs/fs.go
index cfab692..4c97340 100644
--- a/utils/fs/fs.go
+++ b/utils/fs/fs.go
@@ -2,21 +2,49 @@
package fs
import (
+ "errors"
"io"
"os"
)
-// FS interface represent an abstracted filesystem, so you can
-// use NewRepositoryFromFS from any medium.
-type FS interface {
- Stat(path string) (os.FileInfo, error)
- Open(path string) (ReadSeekCloser, error)
- ReadDir(path string) ([]os.FileInfo, error)
+var (
+ ErrClosed = errors.New("File: Writing on closed file.")
+ ErrReadOnly = errors.New("this is a read-only filesystem")
+ ErrNotSupported = errors.New("feature not supported")
+)
+
+type Filesystem interface {
+ Create(filename string) (File, error)
+ Open(filename string) (File, error)
+ Rename(from, to string) error
+ Stat(filename string) (FileInfo, error)
+ ReadDir(path string) ([]FileInfo, error)
Join(elem ...string) string
+ Dir(path string) Filesystem
+ Base() string
}
-// ReadSeekCloser is a Reader, Seeker and Closer.
-type ReadSeekCloser interface {
- io.ReadCloser
+type File interface {
+ Filename() string
+ io.Writer
+ io.Reader
io.Seeker
+ io.Closer
+}
+
+type FileInfo os.FileInfo
+
+type BaseFile struct {
+ filename string
+ closed bool
+}
+
+//Filename returns the filename from the File
+func (f *BaseFile) Filename() string {
+ return f.filename
+}
+
+//IsClosed returns if te file is closed
+func (f *BaseFile) IsClosed() bool {
+ return f.closed
}
diff --git a/utils/fs/os.go b/utils/fs/os.go
index 37ad75a..40942ba 100644
--- a/utils/fs/os.go
+++ b/utils/fs/os.go
@@ -3,34 +3,130 @@ package fs
import (
"io/ioutil"
"os"
+ "path"
"path/filepath"
)
-// OS is a simple FS implementation for the current host filesystem.
-type OS struct{}
-
// NewOS returns a new OS.
-func NewOS() FS {
- return &OS{}
+func NewOS() Filesystem {
+ return &OSClient{}
+}
+
+// OSClient a filesystem based on OSClient
+type OSClient struct {
+ RootDir string
+}
+
+// NewOSClient returns a new OSClient
+func NewOSClient(rootDir string) *OSClient {
+ return &OSClient{
+ RootDir: rootDir,
+ }
}
-// Stat returns the filesystem info for a path.
-func (o *OS) Stat(path string) (os.FileInfo, error) {
- return os.Stat(path)
+// Create creates a new GlusterFSFile
+func (c *OSClient) Create(filename string) (File, error) {
+ fullpath := path.Join(c.RootDir, filename)
+
+ dir := filepath.Dir(fullpath)
+ if dir != "." {
+ if err := os.MkdirAll(dir, 0755); err != nil {
+ return nil, err
+ }
+ }
+
+ f, err := os.Create(fullpath)
+ if err != nil {
+ return nil, err
+ }
+
+ return &OSFile{
+ BaseFile: BaseFile{filename: fullpath},
+ file: f,
+ }, nil
+}
+
+// ReadDir returns the filesystem info for all the archives under the specified
+// path.
+func (c *OSClient) ReadDir(path string) ([]FileInfo, error) {
+ fullpath := c.Join(c.RootDir, path)
+
+ l, err := ioutil.ReadDir(fullpath)
+ if err != nil {
+ return nil, err
+ }
+
+ var s = make([]FileInfo, len(l))
+ for i, f := range l {
+ s[i] = f
+ }
+
+ return s, nil
+}
+
+func (c *OSClient) Rename(from, to string) error {
+ if !filepath.IsAbs(from) {
+ from = c.Join(c.RootDir, from)
+ }
+
+ if !filepath.IsAbs(to) {
+ to = c.Join(c.RootDir, to)
+ }
+
+ return os.Rename(from, to)
}
-// Open returns a ReadSeekCloser for the specified path.
-func (o *OS) Open(path string) (ReadSeekCloser, error) {
- return os.Open(path)
+func (c *OSClient) Open(filename string) (File, error) {
+ fullpath := c.Join(c.RootDir, filename)
+
+ f, err := os.Open(fullpath)
+ if err != nil {
+ return nil, err
+ }
+
+ return &OSFile{
+ BaseFile: BaseFile{filename: fullpath},
+ file: f,
+ }, nil
}
-// ReadDir returns the filesystem info for all the archives under the
-// specified path.
-func (o *OS) ReadDir(path string) ([]os.FileInfo, error) {
- return ioutil.ReadDir(path)
+func (c *OSClient) Stat(filename string) (FileInfo, error) {
+ fullpath := c.Join(c.RootDir, filename)
+ return os.Stat(fullpath)
}
// Join joins the specified elements using the filesystem separator.
-func (o *OS) Join(elem ...string) string {
+func (c *OSClient) Join(elem ...string) string {
return filepath.Join(elem...)
}
+
+func (c *OSClient) Dir(path string) Filesystem {
+ return NewOSClient(c.Join(c.RootDir, path))
+}
+
+func (c *OSClient) Base() string {
+ return c.RootDir
+}
+
+type OSFile struct {
+ file *os.File
+ BaseFile
+}
+
+func (f *OSFile) Read(p []byte) (int, error) {
+ return f.file.Read(p)
+}
+
+func (f *OSFile) Seek(offset int64, whence int) (int64, error) {
+ return f.file.Seek(offset, whence)
+}
+
+func (f *OSFile) Write(p []byte) (int, error) {
+ return f.file.Write(p)
+}
+
+func (f *OSFile) Close() error {
+ f.closed = true
+
+ return f.file.Close()
+}
diff --git a/utils/fs/os_test.go b/utils/fs/os_test.go
index b6c00c6..c148265 100644
--- a/utils/fs/os_test.go
+++ b/utils/fs/os_test.go
@@ -5,147 +5,52 @@ import (
"os"
"testing"
- "github.com/alcortesm/tgz"
. "gopkg.in/check.v1"
)
func Test(t *testing.T) { TestingT(t) }
-type FSImplSuite struct {
- dir string
-}
+type WritersSuite struct{}
-var _ = Suite(&FSImplSuite{})
+var _ = Suite(&WritersSuite{})
-func (s *FSImplSuite) SetUpSuite(c *C) {
- dir, err := tgz.Extract("../../storage/filesystem/internal/dotgit/fixtures/spinnaker-gc.tgz")
- c.Assert(err, IsNil)
- s.dir = dir
-}
+func (s *WritersSuite) TestOSClient_Create(c *C) {
+ path := getTempDir()
+ client := NewOSClient(path)
-func (s *FSImplSuite) TearDownSuite(c *C) {
- err := os.RemoveAll(s.dir)
+ f, err := client.Create("foo")
c.Assert(err, IsNil)
+ c.Assert(f.(*OSFile).file.Name(), Equals, f.GetFilename())
}
-func (s *FSImplSuite) TestJoin(c *C) {
- fs := NewOS()
- for i, test := range [...]struct {
- input []string
- expected string
- }{
- {
- input: []string{},
- expected: "",
- }, {
- input: []string{"a"},
- expected: "a",
- }, {
- input: []string{"a", "b"},
- expected: "a/b",
- }, {
- input: []string{"a", "b", "c"},
- expected: "a/b/c",
- },
- } {
- obtained := fs.Join(test.input...)
- com := Commentf("test %d:\n\tinput = %v", i, test.input)
- c.Assert(obtained, Equals, test.expected, com)
- }
-}
-
-func (s *FSImplSuite) TestStat(c *C) {
- fs := NewOS()
- for i, path := range [...]string{
- ".git/index",
- ".git/info/refs",
- ".git/objects/pack/pack-584416f86235cac0d54bfabbdc399fb2b09a5269.pack",
- } {
- path := fs.Join(s.dir, path)
- com := Commentf("test %d", i)
-
- real, err := os.Open(path)
- c.Assert(err, IsNil, com)
-
- expected, err := real.Stat()
- c.Assert(err, IsNil, com)
-
- obtained, err := fs.Stat(path)
- c.Assert(err, IsNil, com)
-
- c.Assert(obtained, DeepEquals, expected, com)
+func (s *WritersSuite) TestOSClient_Write(c *C) {
+ path := getTempDir()
+ client := NewOSClient(path)
- err = real.Close()
- c.Assert(err, IsNil, com)
- }
-}
+ f, err := client.Create("foo")
+ c.Assert(err, IsNil)
+ l, err := f.Write([]byte("foo"))
+ c.Assert(l, Equals, 3)
+ c.Assert(err, IsNil)
-func (s *FSImplSuite) TestStatErrors(c *C) {
- fs := NewOS()
- for i, test := range [...]struct {
- input string
- errRegExp string
- }{
- {
- input: "bla",
- errRegExp: ".*bla: no such file or directory",
- }, {
- input: "bla/foo",
- errRegExp: ".*bla/foo: no such file or directory",
- },
- } {
- com := Commentf("test %d", i)
- _, err := fs.Stat(test.input)
- c.Assert(err, ErrorMatches, test.errRegExp, com)
- }
+ wrote, _ := ioutil.ReadFile(f.(*OSFile).file.Name())
+ c.Assert(wrote, DeepEquals, []byte("foo"))
}
-func (s *FSImplSuite) TestOpen(c *C) {
- fs := NewOS()
- for i, test := range [...]string{
- ".git/index",
- ".git/info/refs",
- ".git/objects/pack/pack-584416f86235cac0d54bfabbdc399fb2b09a5269.pack",
- } {
- com := Commentf("test %d", i)
- path := fs.Join(s.dir, test)
-
- real, err := os.Open(path)
- c.Assert(err, IsNil, com)
- realData, err := ioutil.ReadAll(real)
- c.Assert(err, IsNil, com)
- err = real.Close()
- c.Assert(err, IsNil, com)
+func (s *WritersSuite) TestOSClient_Close(c *C) {
+ path := getTempDir()
+ client := NewOSClient(path)
- obtained, err := fs.Open(path)
- c.Assert(err, IsNil, com)
- obtainedData, err := ioutil.ReadAll(obtained)
- c.Assert(err, IsNil, com)
- err = obtained.Close()
- c.Assert(err, IsNil, com)
+ f, err := client.Create("foo")
+ c.Assert(err, IsNil)
+ f.Write([]byte("foo"))
+ c.Assert(f.Close(), IsNil)
- c.Assert(obtainedData, DeepEquals, realData, com)
- }
+ wrote, _ := ioutil.ReadFile(f.GetFilename())
+ c.Assert(wrote, DeepEquals, []byte("foo"))
}
-func (s *FSImplSuite) TestReadDir(c *C) {
- fs := NewOS()
- for i, test := range [...]string{
- ".git/info",
- ".",
- "",
- ".git/objects",
- ".git/objects/pack",
- } {
- com := Commentf("test %d", i)
- path := fs.Join(s.dir, test)
-
- expected, err := ioutil.ReadDir(path)
- c.Assert(err, IsNil, com)
-
- obtained, err := fs.ReadDir(path)
- c.Assert(err, IsNil, com)
-
- c.Assert(obtained, DeepEquals, expected, com)
- }
+func getTempDir() string {
+ dir, _ := ioutil.TempDir(os.TempDir(), "--OSClientTest--")
+ return dir
}