diff options
Diffstat (limited to 'utils/fs/os')
-rw-r--r-- | utils/fs/os/os.go | 188 | ||||
-rw-r--r-- | utils/fs/os/os_test.go | 29 |
2 files changed, 217 insertions, 0 deletions
diff --git a/utils/fs/os/os.go b/utils/fs/os/os.go new file mode 100644 index 0000000..0b0173f --- /dev/null +++ b/utils/fs/os/os.go @@ -0,0 +1,188 @@ +package os + +import ( + "io/ioutil" + "os" + "path" + "path/filepath" + + . "gopkg.in/src-d/go-git.v4/utils/fs" +) + +// OS a filesystem base on the os filesystem +type OS struct { + base string +} + +// NewOS returns a new OS filesystem +func NewOS(baseDir string) *OS { + return &OS{ + base: baseDir, + } +} + +// Create creates a new GlusterFSFile +func (fs *OS) Create(filename string) (File, error) { + fullpath := path.Join(fs.base, filename) + + if err := fs.createDir(fullpath); err != nil { + return nil, err + } + + f, err := os.Create(fullpath) + if err != nil { + return nil, err + } + + filename, err = filepath.Rel(fs.base, fullpath) + if err != nil { + return nil, err + } + + return newOSFile(filename, f), nil +} + +func (fs *OS) createDir(fullpath string) error { + dir := filepath.Dir(fullpath) + if dir != "." { + if err := os.MkdirAll(dir, 0755); err != nil { + return err + } + } + + return nil +} + +// ReadDir returns the filesystem info for all the archives under the specified +// path. +func (fs *OS) ReadDir(path string) ([]FileInfo, error) { + fullpath := fs.Join(fs.base, 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 (fs *OS) Rename(from, to string) error { + from = fs.Join(fs.base, from) + to = fs.Join(fs.base, to) + + if err := fs.createDir(to); err != nil { + return err + } + + return os.Rename(from, to) +} + +// Open opens the named file for reading. If successful, methods on the returned +// file can be used for reading only. +func (fs *OS) Open(filename string) (File, error) { + fullpath := fs.Join(fs.base, filename) + f, err := os.Open(fullpath) + if err != nil { + return nil, err + } + + return newOSFile(filename, f), nil +} + +// Stat returns the FileInfo structure describing file. +func (fs *OS) Stat(filename string) (FileInfo, error) { + fullpath := fs.Join(fs.base, filename) + return os.Stat(fullpath) +} + +func (fs *OS) TempFile(dir, prefix string) (File, error) { + fullpath := fs.Join(fs.base, dir) + if err := fs.createDir(fullpath + string(os.PathSeparator)); err != nil { + return nil, err + } + + f, err := ioutil.TempFile(fullpath, prefix) + if err != nil { + return nil, err + } + + s, err := f.Stat() + if err != nil { + return nil, err + } + + filename, err := filepath.Rel(fs.base, fs.Join(fullpath, s.Name())) + if err != nil { + return nil, err + } + + return newOSFile(filename, f), nil +} + +// Join joins the specified elements using the filesystem separator. +func (fs *OS) Join(elem ...string) string { + return filepath.Join(elem...) +} + +// Dir returns a new Filesystem from the same type of fs using as baseDir the +// given path +func (fs *OS) Dir(path string) Filesystem { + return NewOS(fs.Join(fs.base, path)) +} + +// Base returns the base path of the filesytem +func (fs *OS) Base() string { + return fs.base +} + +// osFile represents a file in the os filesystem +type osFile struct { + filename string + closed bool + file *os.File +} + +func newOSFile(filename string, file *os.File) File { + return &osFile{ + filename: filename, + closed: false, + file: file, + } +} + +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() +} + +func (f *osFile) ReadAt(p []byte, off int64) (n int, err error) { + return f.file.ReadAt(p, off) +} + +//Filename returns the filename from the File +func (f *osFile) Filename() string { + return f.filename +} + +//IsClosed returns if te file is closed +func (f *osFile) IsClosed() bool { + return f.closed +} diff --git a/utils/fs/os/os_test.go b/utils/fs/os/os_test.go new file mode 100644 index 0000000..02a0a6c --- /dev/null +++ b/utils/fs/os/os_test.go @@ -0,0 +1,29 @@ +package os_test + +import ( + "io/ioutil" + stdos "os" + "testing" + + . "gopkg.in/check.v1" + "gopkg.in/src-d/go-git.v4/utils/fs/os" + "gopkg.in/src-d/go-git.v4/utils/fs/test" +) + +func Test(t *testing.T) { TestingT(t) } + +type OSSuite struct { + test.FilesystemSuite + path string +} + +var _ = Suite(&OSSuite{}) + +func (s *OSSuite) SetUpTest(c *C) { + s.path, _ = ioutil.TempDir(stdos.TempDir(), "go-git-os-fs-test") + s.FilesystemSuite.Fs = os.NewOS(s.path) +} +func (s *OSSuite) TearDownTest(c *C) { + err := stdos.RemoveAll(s.path) + c.Assert(err, IsNil) +} |