aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSergio Arbeo <serabe@gmail.com>2016-12-19 10:42:14 +0100
committerMáximo Cuadros <mcuadros@gmail.com>2016-12-19 10:42:14 +0100
commit1eb39394cdf09b26eb2f5c98225fb2912980e61f (patch)
tree25e7b370498733aba66688c5d53c29fcef6aa21c
parentc9353b2bd7c1cbdf8f78dad6deac64ed2f2ed9eb (diff)
downloadgo-git-1eb39394cdf09b26eb2f5c98225fb2912980e61f.tar.gz
Extract billy (#173)
* Extract billy Billy is a new library directly extracted from go-git. It abstract several storages systems in a filesystem interface. More in github.com/src-d/billy * Fix grouping in imports block * Update billy to v1 * Re-remove fs_implementation example
-rw-r--r--fixtures/fixtures.go12
-rw-r--r--plumbing/format/packfile/decoder_test.go3
-rw-r--r--remote_test.go3
-rw-r--r--repository.go3
-rw-r--r--storage/filesystem/config_test.go3
-rw-r--r--storage/filesystem/internal/dotgit/dotgit.go21
-rw-r--r--storage/filesystem/internal/dotgit/dotgit_test.go3
-rw-r--r--storage/filesystem/internal/dotgit/writers.go15
-rw-r--r--storage/filesystem/internal/dotgit/writers_test.go3
-rw-r--r--storage/filesystem/object.go7
-rw-r--r--storage/filesystem/storage.go5
-rw-r--r--storage/filesystem/storage_test.go3
-rw-r--r--utils/fs/fs.go52
-rw-r--r--utils/fs/memory/memory.go364
-rw-r--r--utils/fs/memory/memory_test.go33
-rw-r--r--utils/fs/os/os.go183
-rw-r--r--utils/fs/os/os_test.go37
-rw-r--r--utils/fs/test/fs_suite.go479
18 files changed, 46 insertions, 1183 deletions
diff --git a/fixtures/fixtures.go b/fixtures/fixtures.go
index 00e7871..fdf852e 100644
--- a/fixtures/fixtures.go
+++ b/fixtures/fixtures.go
@@ -7,12 +7,12 @@ import (
"os"
"path/filepath"
- "github.com/alcortesm/tgz"
-
"gopkg.in/check.v1"
"gopkg.in/src-d/go-git.v4/plumbing"
- "gopkg.in/src-d/go-git.v4/utils/fs"
- osfs "gopkg.in/src-d/go-git.v4/utils/fs/os"
+
+ "github.com/alcortesm/tgz"
+ "srcd.works/go-billy.v1"
+ osfs "srcd.works/go-billy.v1/os"
)
var RootFolder = ""
@@ -182,7 +182,7 @@ func (f *Fixture) Idx() *os.File {
// DotGit creates a new temporary directory and unpacks the repository .git
// directory into it. Multiple calls to DotGit returns different directories.
-func (f *Fixture) DotGit() fs.Filesystem {
+func (f *Fixture) DotGit() billy.Filesystem {
fn := filepath.Join(RootFolder, DataFolder, fmt.Sprintf("git-%s.tgz", f.DotGitHash))
path, err := tgz.Extract(fn)
if err != nil {
@@ -193,7 +193,7 @@ func (f *Fixture) DotGit() fs.Filesystem {
return osfs.New(path)
}
-func (f *Fixture) Worktree() fs.Filesystem {
+func (f *Fixture) Worktree() billy.Filesystem {
fn := filepath.Join(RootFolder, DataFolder, fmt.Sprintf("git-%s.tgz", f.DotGitHash))
git, err := tgz.Extract(fn)
if err != nil {
diff --git a/plumbing/format/packfile/decoder_test.go b/plumbing/format/packfile/decoder_test.go
index eeb1e3d..10d3bc2 100644
--- a/plumbing/format/packfile/decoder_test.go
+++ b/plumbing/format/packfile/decoder_test.go
@@ -10,7 +10,8 @@ import (
"gopkg.in/src-d/go-git.v4/plumbing/storer"
"gopkg.in/src-d/go-git.v4/storage/filesystem"
"gopkg.in/src-d/go-git.v4/storage/memory"
- fs "gopkg.in/src-d/go-git.v4/utils/fs/memory"
+
+ fs "srcd.works/go-billy.v1/memory"
. "gopkg.in/check.v1"
)
diff --git a/remote_test.go b/remote_test.go
index f75adee..47c8180 100644
--- a/remote_test.go
+++ b/remote_test.go
@@ -11,7 +11,8 @@ import (
"gopkg.in/src-d/go-git.v4/plumbing/storer"
"gopkg.in/src-d/go-git.v4/storage/filesystem"
"gopkg.in/src-d/go-git.v4/storage/memory"
- osfs "gopkg.in/src-d/go-git.v4/utils/fs/os"
+
+ osfs "srcd.works/go-billy.v1/os"
. "gopkg.in/check.v1"
)
diff --git a/repository.go b/repository.go
index 7d964a4..b9afb9a 100644
--- a/repository.go
+++ b/repository.go
@@ -11,7 +11,8 @@ import (
"gopkg.in/src-d/go-git.v4/plumbing/storer"
"gopkg.in/src-d/go-git.v4/storage/filesystem"
"gopkg.in/src-d/go-git.v4/storage/memory"
- osfs "gopkg.in/src-d/go-git.v4/utils/fs/os"
+
+ osfs "srcd.works/go-billy.v1/os"
)
var (
diff --git a/storage/filesystem/config_test.go b/storage/filesystem/config_test.go
index b86eaee..6fbf826 100644
--- a/storage/filesystem/config_test.go
+++ b/storage/filesystem/config_test.go
@@ -6,7 +6,8 @@ import (
"gopkg.in/src-d/go-git.v4/fixtures"
"gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit"
- "gopkg.in/src-d/go-git.v4/utils/fs/os"
+
+ "srcd.works/go-billy.v1/os"
. "gopkg.in/check.v1"
)
diff --git a/storage/filesystem/internal/dotgit/dotgit.go b/storage/filesystem/internal/dotgit/dotgit.go
index 3405908..f9763d1 100644
--- a/storage/filesystem/internal/dotgit/dotgit.go
+++ b/storage/filesystem/internal/dotgit/dotgit.go
@@ -10,7 +10,8 @@ import (
"strings"
"gopkg.in/src-d/go-git.v4/plumbing"
- "gopkg.in/src-d/go-git.v4/utils/fs"
+
+ "srcd.works/go-billy.v1"
)
const (
@@ -51,33 +52,33 @@ var (
// The DotGit type represents a local git repository on disk. This
// type is not zero-value-safe, use the New function to initialize it.
type DotGit struct {
- fs fs.Filesystem
+ fs billy.Filesystem
}
// New returns a DotGit value ready to be used. The path argument must
// be the absolute path of a git repository directory (e.g.
// "/foo/bar/.git").
-func New(fs fs.Filesystem) *DotGit {
+func New(fs billy.Filesystem) *DotGit {
return &DotGit{fs: fs}
}
// ConfigWriter returns a file pointer for write to the config file
-func (d *DotGit) ConfigWriter() (fs.File, error) {
+func (d *DotGit) ConfigWriter() (billy.File, error) {
return d.fs.Create(configPath)
}
// Config returns a file pointer for read to the config file
-func (d *DotGit) Config() (fs.File, error) {
+func (d *DotGit) Config() (billy.File, error) {
return d.fs.Open(configPath)
}
// ShallowWriter returns a file pointer for write to the shallow file
-func (d *DotGit) ShallowWriter() (fs.File, error) {
+func (d *DotGit) ShallowWriter() (billy.File, error) {
return d.fs.Create(shallowPath)
}
// Shallow returns a file pointer for read to the shallow file
-func (d *DotGit) Shallow() (fs.File, error) {
+func (d *DotGit) Shallow() (billy.File, error) {
f, err := d.fs.Open(shallowPath)
if err != nil {
if os.IsNotExist(err) {
@@ -124,7 +125,7 @@ func (d *DotGit) ObjectPacks() ([]plumbing.Hash, error) {
}
// ObjectPack returns a fs.File of the given packfile
-func (d *DotGit) ObjectPack(hash plumbing.Hash) (fs.File, error) {
+func (d *DotGit) ObjectPack(hash plumbing.Hash) (billy.File, error) {
file := d.fs.Join(objectsPath, packPath, fmt.Sprintf("pack-%s.pack", hash.String()))
pack, err := d.fs.Open(file)
@@ -140,7 +141,7 @@ func (d *DotGit) ObjectPack(hash plumbing.Hash) (fs.File, error) {
}
// ObjectPackIdx returns a fs.File of the index file for a given packfile
-func (d *DotGit) ObjectPackIdx(hash plumbing.Hash) (fs.File, error) {
+func (d *DotGit) ObjectPackIdx(hash plumbing.Hash) (billy.File, error) {
file := d.fs.Join(objectsPath, packPath, fmt.Sprintf("pack-%s.idx", hash.String()))
idx, err := d.fs.Open(file)
if err != nil {
@@ -190,7 +191,7 @@ func (d *DotGit) Objects() ([]plumbing.Hash, error) {
}
// Object return a fs.File poiting the object file, if exists
-func (d *DotGit) Object(h plumbing.Hash) (fs.File, error) {
+func (d *DotGit) Object(h plumbing.Hash) (billy.File, error) {
hash := h.String()
file := d.fs.Join(objectsPath, hash[0:2], hash[2:40])
diff --git a/storage/filesystem/internal/dotgit/dotgit_test.go b/storage/filesystem/internal/dotgit/dotgit_test.go
index b645a85..48f02f0 100644
--- a/storage/filesystem/internal/dotgit/dotgit_test.go
+++ b/storage/filesystem/internal/dotgit/dotgit_test.go
@@ -9,7 +9,8 @@ import (
"gopkg.in/src-d/go-git.v4/fixtures"
"gopkg.in/src-d/go-git.v4/plumbing"
- osfs "gopkg.in/src-d/go-git.v4/utils/fs/os"
+
+ osfs "srcd.works/go-billy.v1/os"
. "gopkg.in/check.v1"
)
diff --git a/storage/filesystem/internal/dotgit/writers.go b/storage/filesystem/internal/dotgit/writers.go
index 8e22a39..1cd893d 100644
--- a/storage/filesystem/internal/dotgit/writers.go
+++ b/storage/filesystem/internal/dotgit/writers.go
@@ -9,7 +9,8 @@ import (
"gopkg.in/src-d/go-git.v4/plumbing/format/idxfile"
"gopkg.in/src-d/go-git.v4/plumbing/format/objfile"
"gopkg.in/src-d/go-git.v4/plumbing/format/packfile"
- "gopkg.in/src-d/go-git.v4/utils/fs"
+
+ "srcd.works/go-billy.v1"
)
// PackWriter is a io.Writer that generates the packfile index simultaneously,
@@ -21,15 +22,15 @@ import (
type PackWriter struct {
Notify func(h plumbing.Hash, i idxfile.Idxfile)
- fs fs.Filesystem
- fr, fw fs.File
+ fs billy.Filesystem
+ fr, fw billy.File
synced *syncedReader
checksum plumbing.Hash
index idxfile.Idxfile
result chan error
}
-func newPackWrite(fs fs.Filesystem) (*PackWriter, error) {
+func newPackWrite(fs billy.Filesystem) (*PackWriter, error) {
fw, err := fs.TempFile(fs.Join(objectsPath, packPath), "tmp_pack_")
if err != nil {
return nil, err
@@ -248,11 +249,11 @@ func (s *syncedReader) Close() error {
type ObjectWriter struct {
objfile.Writer
- fs fs.Filesystem
- f fs.File
+ fs billy.Filesystem
+ f billy.File
}
-func newObjectWriter(fs fs.Filesystem) (*ObjectWriter, error) {
+func newObjectWriter(fs billy.Filesystem) (*ObjectWriter, error) {
f, err := fs.TempFile(fs.Join(objectsPath, packPath), "tmp_obj_")
if err != nil {
return nil, err
diff --git a/storage/filesystem/internal/dotgit/writers_test.go b/storage/filesystem/internal/dotgit/writers_test.go
index c66613a..c546a3a 100644
--- a/storage/filesystem/internal/dotgit/writers_test.go
+++ b/storage/filesystem/internal/dotgit/writers_test.go
@@ -9,7 +9,8 @@ import (
"strconv"
"gopkg.in/src-d/go-git.v4/fixtures"
- osfs "gopkg.in/src-d/go-git.v4/utils/fs/os"
+
+ osfs "srcd.works/go-billy.v1/os"
. "gopkg.in/check.v1"
)
diff --git a/storage/filesystem/object.go b/storage/filesystem/object.go
index 836e7f3..e9b5bb7 100644
--- a/storage/filesystem/object.go
+++ b/storage/filesystem/object.go
@@ -11,7 +11,8 @@ import (
"gopkg.in/src-d/go-git.v4/plumbing/storer"
"gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit"
"gopkg.in/src-d/go-git.v4/storage/memory"
- "gopkg.in/src-d/go-git.v4/utils/fs"
+
+ "srcd.works/go-billy.v1"
)
type ObjectStorage struct {
@@ -261,7 +262,7 @@ func (i index) Decode(r io.Reader) error {
}
type packfileIter struct {
- f fs.File
+ f billy.File
d *packfile.Decoder
t plumbing.ObjectType
@@ -270,7 +271,7 @@ type packfileIter struct {
total uint32
}
-func newPackfileIter(f fs.File, t plumbing.ObjectType, seen map[plumbing.Hash]bool) (storer.EncodedObjectIter, error) {
+func newPackfileIter(f billy.File, t plumbing.ObjectType, seen map[plumbing.Hash]bool) (storer.EncodedObjectIter, error) {
s := packfile.NewScanner(f)
_, total, err := s.Header()
if err != nil {
diff --git a/storage/filesystem/storage.go b/storage/filesystem/storage.go
index e414428..a60d0f4 100644
--- a/storage/filesystem/storage.go
+++ b/storage/filesystem/storage.go
@@ -3,7 +3,8 @@ package filesystem
import (
"gopkg.in/src-d/go-git.v4/storage/filesystem/internal/dotgit"
- "gopkg.in/src-d/go-git.v4/utils/fs"
+
+ "srcd.works/go-billy.v1"
)
// Storage is an implementation of git.Storer that stores data on disk in the
@@ -17,7 +18,7 @@ type Storage struct {
}
// NewStorage returns a new Storage backed by a given `fs.Filesystem`
-func NewStorage(fs fs.Filesystem) (*Storage, error) {
+func NewStorage(fs billy.Filesystem) (*Storage, error) {
dir := dotgit.New(fs)
o, err := newObjectStorage(dir)
if err != nil {
diff --git a/storage/filesystem/storage_test.go b/storage/filesystem/storage_test.go
index c24d5d5..0e8ffb3 100644
--- a/storage/filesystem/storage_test.go
+++ b/storage/filesystem/storage_test.go
@@ -4,7 +4,8 @@ import (
"testing"
"gopkg.in/src-d/go-git.v4/storage/test"
- "gopkg.in/src-d/go-git.v4/utils/fs/os"
+
+ "srcd.works/go-billy.v1/os"
. "gopkg.in/check.v1"
)
diff --git a/utils/fs/fs.go b/utils/fs/fs.go
deleted file mode 100644
index 7e6c01f..0000000
--- a/utils/fs/fs.go
+++ /dev/null
@@ -1,52 +0,0 @@
-// Package fs interace and implementations used by storage/filesystem
-package fs
-
-import (
- "errors"
- "io"
- "os"
-)
-
-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)
- OpenFile(filename string, flag int, perm os.FileMode) (File, error)
- Stat(filename string) (FileInfo, error)
- ReadDir(path string) ([]FileInfo, error)
- TempFile(dir, prefix string) (File, error)
- Rename(from, to string) error
- Remove(filename string) error
- Join(elem ...string) string
- Dir(path string) Filesystem
- Base() string
-}
-
-type File interface {
- Filename() string
- IsClosed() bool
- io.Writer
- io.Reader
- io.Seeker
- io.Closer
-}
-
-type FileInfo os.FileInfo
-
-type BaseFile struct {
- BaseFilename string
- Closed bool
-}
-
-func (f *BaseFile) Filename() string {
- return f.BaseFilename
-}
-
-func (f *BaseFile) IsClosed() bool {
- return f.Closed
-}
diff --git a/utils/fs/memory/memory.go b/utils/fs/memory/memory.go
deleted file mode 100644
index 54dd497..0000000
--- a/utils/fs/memory/memory.go
+++ /dev/null
@@ -1,364 +0,0 @@
-package memory
-
-import (
- "errors"
- "fmt"
- "io"
- "os"
- "path/filepath"
- "strings"
- "time"
-
- "gopkg.in/src-d/go-git.v4/utils/fs"
-)
-
-const separator = '/'
-
-// Memory a very convenient filesystem based on memory files
-type Memory struct {
- base string
- s *storage
- tempCount int
-}
-
-//New returns a new Memory filesystem
-func New() *Memory {
- return &Memory{
- base: "/",
- s: &storage{make(map[string]*file, 0)},
- }
-}
-
-func (fs *Memory) Create(filename string) (fs.File, error) {
- return fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0)
-}
-
-func (fs *Memory) Open(filename string) (fs.File, error) {
- return fs.OpenFile(filename, os.O_RDONLY, 0)
-}
-
-func (fs *Memory) OpenFile(filename string, flag int, perm os.FileMode) (fs.File, error) {
- fullpath := fs.Join(fs.base, filename)
- f, ok := fs.s.files[fullpath]
-
- if !ok && !isCreate(flag) {
- return nil, os.ErrNotExist
- }
-
- if f == nil {
- fs.s.files[fullpath] = newFile(fs.base, fullpath, flag)
- return fs.s.files[fullpath], nil
- }
-
- n := newFile(fs.base, fullpath, flag)
- n.content = f.content
-
- if isAppend(flag) {
- n.position = int64(n.content.Len())
- }
-
- if isTruncate(flag) {
- n.content.Truncate()
- }
-
- return n, nil
-}
-
-func (fs *Memory) Stat(filename string) (fs.FileInfo, error) {
- fullpath := fs.Join(fs.base, filename)
-
- if _, ok := fs.s.files[filename]; ok {
- return newFileInfo(fs.base, fullpath, fs.s.files[filename].content.Len()), nil
- }
-
- info, err := fs.ReadDir(filename)
- if err == nil && len(info) != 0 {
- return newFileInfo(fs.base, fullpath, len(info)), nil
- }
-
- return nil, os.ErrNotExist
-}
-
-func (fs *Memory) ReadDir(base string) (entries []fs.FileInfo, err error) {
- base = fs.Join(fs.base, base)
-
- appendedDirs := make(map[string]bool, 0)
- for fullpath, f := range fs.s.files {
- if !strings.HasPrefix(fullpath, base) {
- continue
- }
-
- fullpath, _ = filepath.Rel(base, fullpath)
- parts := strings.Split(fullpath, string(separator))
-
- if len(parts) == 1 {
- entries = append(entries, &fileInfo{name: parts[0], size: f.content.Len()})
- continue
- }
-
- if _, ok := appendedDirs[parts[0]]; ok {
- continue
- }
-
- entries = append(entries, &fileInfo{name: parts[0], isDir: true})
- appendedDirs[parts[0]] = true
- }
-
- return
-}
-
-var maxTempFiles = 1024 * 4
-
-func (fs *Memory) TempFile(dir, prefix string) (fs.File, error) {
- var fullpath string
- for {
- if fs.tempCount >= maxTempFiles {
- return nil, errors.New("max. number of tempfiles reached")
- }
-
- fullpath = fs.getTempFilename(dir, prefix)
- if _, ok := fs.s.files[fullpath]; !ok {
- break
- }
- }
-
- return fs.Create(fullpath)
-}
-
-func (fs *Memory) getTempFilename(dir, prefix string) string {
- fs.tempCount++
- filename := fmt.Sprintf("%s_%d_%d", prefix, fs.tempCount, time.Now().UnixNano())
- return fs.Join(fs.base, dir, filename)
-}
-
-func (fs *Memory) Rename(from, to string) error {
- from = fs.Join(fs.base, from)
- to = fs.Join(fs.base, to)
-
- if _, ok := fs.s.files[from]; !ok {
- return os.ErrNotExist
- }
-
- fs.s.files[to] = fs.s.files[from]
- fs.s.files[to].BaseFilename = to
- delete(fs.s.files, from)
-
- return nil
-}
-
-func (fs *Memory) Remove(filename string) error {
- fullpath := fs.Join(fs.base, filename)
- if _, ok := fs.s.files[fullpath]; !ok {
- return os.ErrNotExist
- }
-
- delete(fs.s.files, fullpath)
- return nil
-}
-
-func (fs *Memory) Join(elem ...string) string {
- return filepath.Join(elem...)
-}
-
-func (fs *Memory) Dir(path string) fs.Filesystem {
- return &Memory{
- base: fs.Join(fs.base, path),
- s: fs.s,
- }
-}
-
-func (fs *Memory) Base() string {
- return fs.base
-}
-
-type file struct {
- fs.BaseFile
-
- content *content
- position int64
- flag int
-}
-
-func newFile(base, fullpath string, flag int) *file {
- filename, _ := filepath.Rel(base, fullpath)
-
- return &file{
- BaseFile: fs.BaseFile{BaseFilename: filename},
- content: &content{},
- flag: flag,
- }
-}
-
-func (f *file) Read(b []byte) (int, error) {
- n, err := f.ReadAt(b, f.position)
- if err != nil {
- return 0, err
- }
-
- return n, err
-}
-
-func (f *file) ReadAt(b []byte, off int64) (int, error) {
- if f.IsClosed() {
- return 0, fs.ErrClosed
- }
-
- if !isReadAndWrite(f.flag) && !isReadOnly(f.flag) {
- return 0, errors.New("read not supported")
- }
-
- n, err := f.content.ReadAt(b, off)
- f.position += int64(n)
-
- return n, err
-}
-
-func (f *file) Seek(offset int64, whence int) (int64, error) {
- if f.IsClosed() {
- return 0, fs.ErrClosed
- }
-
- switch whence {
- case io.SeekCurrent:
- f.position += offset
- case io.SeekStart:
- f.position = offset
- case io.SeekEnd:
- f.position = int64(f.content.Len()) - offset
- }
-
- return f.position, nil
-}
-
-func (f *file) Write(p []byte) (int, error) {
- if f.IsClosed() {
- return 0, fs.ErrClosed
- }
-
- if !isReadAndWrite(f.flag) && !isWriteOnly(f.flag) {
- return 0, errors.New("write not supported")
- }
-
- n, err := f.content.WriteAt(p, f.position)
- f.position += int64(n)
-
- return n, err
-}
-
-func (f *file) Close() error {
- if f.IsClosed() {
- return errors.New("file already closed")
- }
-
- f.Closed = true
- return nil
-}
-
-func (f *file) Open() error {
- f.Closed = false
- return nil
-}
-
-type fileInfo struct {
- name string
- size int
- isDir bool
-}
-
-func newFileInfo(base, fullpath string, size int) *fileInfo {
- filename, _ := filepath.Rel(base, fullpath)
-
- return &fileInfo{
- name: filename,
- size: size,
- }
-}
-
-func (fi *fileInfo) Name() string {
- return fi.name
-}
-
-func (fi *fileInfo) Size() int64 {
- return int64(fi.size)
-}
-
-func (fi *fileInfo) Mode() os.FileMode {
- return os.FileMode(0)
-}
-
-func (*fileInfo) ModTime() time.Time {
- return time.Now()
-}
-
-func (fi *fileInfo) IsDir() bool {
- return fi.isDir
-}
-
-func (*fileInfo) Sys() interface{} {
- return nil
-}
-
-type storage struct {
- files map[string]*file
-}
-
-type content struct {
- bytes []byte
-}
-
-func (c *content) WriteAt(p []byte, off int64) (int, error) {
- prev := len(c.bytes)
- c.bytes = append(c.bytes[:off], p...)
- if len(c.bytes) < prev {
- c.bytes = c.bytes[:prev]
- }
-
- return len(p), nil
-}
-
-func (c *content) ReadAt(b []byte, off int64) (int, error) {
- size := int64(len(c.bytes))
- if off >= size {
- return 0, io.EOF
- }
-
- l := int64(len(b))
- if off+l > size {
- l = size - off
- }
-
- n := copy(b, c.bytes[off:off+l])
- return n, nil
-}
-
-func (c *content) Truncate() {
- c.bytes = make([]byte, 0)
-}
-
-func (c *content) Len() int {
- return len(c.bytes)
-}
-
-func isCreate(flag int) bool {
- return flag&os.O_CREATE != 0
-}
-
-func isAppend(flag int) bool {
- return flag&os.O_APPEND != 0
-}
-
-func isTruncate(flag int) bool {
- return flag&os.O_TRUNC != 0
-}
-
-func isReadAndWrite(flag int) bool {
- return flag&os.O_RDWR != 0
-}
-
-func isReadOnly(flag int) bool {
- return flag == os.O_RDONLY
-}
-
-func isWriteOnly(flag int) bool {
- return flag&os.O_WRONLY != 0
-}
diff --git a/utils/fs/memory/memory_test.go b/utils/fs/memory/memory_test.go
deleted file mode 100644
index 4645fe7..0000000
--- a/utils/fs/memory/memory_test.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package memory
-
-import (
- "testing"
-
- . "gopkg.in/check.v1"
- "gopkg.in/src-d/go-git.v4/utils/fs/test"
-)
-
-func Test(t *testing.T) { TestingT(t) }
-
-type MemorySuite struct {
- test.FilesystemSuite
- path string
-}
-
-var _ = Suite(&MemorySuite{})
-
-func (s *MemorySuite) SetUpTest(c *C) {
- s.FilesystemSuite.Fs = New()
-}
-
-func (s *MemorySuite) TestTempFileMaxTempFiles(c *C) {
- for i := 0; i < maxTempFiles; i++ {
- f, err := s.FilesystemSuite.Fs.TempFile("", "")
- c.Assert(err, IsNil)
- c.Assert(f, NotNil)
- }
-
- f, err := s.FilesystemSuite.Fs.TempFile("", "")
- c.Assert(err, NotNil)
- c.Assert(f, IsNil)
-}
diff --git a/utils/fs/os/os.go b/utils/fs/os/os.go
deleted file mode 100644
index 5f9df67..0000000
--- a/utils/fs/os/os.go
+++ /dev/null
@@ -1,183 +0,0 @@
-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
-}
-
-// New returns a new OS filesystem
-func New(baseDir string) *OS {
- return &OS{
- base: baseDir,
- }
-}
-
-// Create creates a file and opens it with standard permissions
-// and modes O_RDWR, O_CREATE and O_TRUNC.
-func (fs *OS) Create(filename string) (fs.File, error) {
- return fs.OpenFile(filename, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
-}
-
-// OpenFile is equivalent to standard os.OpenFile.
-// If flag os.O_CREATE is set, all parent directories will be created.
-func (fs *OS) OpenFile(filename string, flag int, perm os.FileMode) (fs.File, error) {
- fullpath := path.Join(fs.base, filename)
-
- if flag&os.O_CREATE != 0 {
- if err := fs.createDir(fullpath); err != nil {
- return nil, err
- }
- }
-
- f, err := os.OpenFile(fullpath, flag, perm)
- 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 (ofs *OS) ReadDir(path string) ([]fs.FileInfo, error) {
- fullpath := ofs.Join(ofs.base, path)
-
- l, err := ioutil.ReadDir(fullpath)
- if err != nil {
- return nil, err
- }
-
- var s = make([]fs.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 a file in read-only mode.
-func (fs *OS) Open(filename string) (fs.File, error) {
- return fs.OpenFile(filename, os.O_RDONLY, 0)
-}
-
-// Stat returns the FileInfo structure describing file.
-func (fs *OS) Stat(filename string) (fs.FileInfo, error) {
- fullpath := fs.Join(fs.base, filename)
- return os.Stat(fullpath)
-}
-
-func (fs *OS) Remove(filename string) error {
- fullpath := fs.Join(fs.base, filename)
- return os.Remove(fullpath)
-}
-
-func (fs *OS) TempFile(dir, prefix string) (fs.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) fs.Filesystem {
- return New(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 {
- fs.BaseFile
- file *os.File
-}
-
-func newOSFile(filename string, file *os.File) fs.File {
- return &osFile{
- BaseFile: fs.BaseFile{BaseFilename: filename},
- 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.BaseFile.Closed = true
-
- return f.file.Close()
-}
-
-func (f *osFile) ReadAt(p []byte, off int64) (int, error) {
- return f.file.ReadAt(p, off)
-}
diff --git a/utils/fs/os/os_test.go b/utils/fs/os/os_test.go
deleted file mode 100644
index 5e8f5c1..0000000
--- a/utils/fs/os/os_test.go
+++ /dev/null
@@ -1,37 +0,0 @@
-package os_test
-
-import (
- "io/ioutil"
- stdos "os"
- "path/filepath"
- "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.New(s.path)
-}
-func (s *OSSuite) TearDownTest(c *C) {
- err := stdos.RemoveAll(s.path)
- c.Assert(err, IsNil)
-}
-
-func (s *OSSuite) TestOpenDoesNotCreateDir(c *C) {
- _, err := s.Fs.Open("dir/non-existent")
- c.Assert(err, NotNil)
- _, err = stdos.Stat(filepath.Join(s.path, "dir"))
- c.Assert(stdos.IsNotExist(err), Equals, true)
-}
diff --git a/utils/fs/test/fs_suite.go b/utils/fs/test/fs_suite.go
deleted file mode 100644
index 91b2be5..0000000
--- a/utils/fs/test/fs_suite.go
+++ /dev/null
@@ -1,479 +0,0 @@
-package test
-
-import (
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "strings"
- "testing"
-
- "bytes"
-
- . "gopkg.in/check.v1"
- . "gopkg.in/src-d/go-git.v4/utils/fs"
-)
-
-func Test(t *testing.T) { TestingT(t) }
-
-type FilesystemSuite struct {
- Fs Filesystem
-}
-
-func (s *FilesystemSuite) TestCreate(c *C) {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
- c.Assert(f.Filename(), Equals, "foo")
-}
-
-func (s *FilesystemSuite) TestCreateDepth(c *C) {
- f, err := s.Fs.Create("bar/foo")
- c.Assert(err, IsNil)
- c.Assert(f.Filename(), Equals, "bar/foo")
-}
-
-func (s *FilesystemSuite) TestCreateDepthAbsolute(c *C) {
- f, err := s.Fs.Create("/bar/foo")
- c.Assert(err, IsNil)
- c.Assert(f.Filename(), Equals, "bar/foo")
-}
-
-func (s *FilesystemSuite) TestCreateOverwrite(c *C) {
- for i := 0; i < 3; i++ {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
-
- l, err := f.Write([]byte(fmt.Sprintf("foo%d", i)))
- c.Assert(err, IsNil)
- c.Assert(l, Equals, 4)
-
- err = f.Close()
- c.Assert(err, IsNil)
- }
-
- f, err := s.Fs.Open("foo")
- c.Assert(err, IsNil)
-
- wrote, err := ioutil.ReadAll(f)
- c.Assert(err, IsNil)
- c.Assert(string(wrote), DeepEquals, "foo2")
-}
-
-func (s *FilesystemSuite) TestCreateClose(c *C) {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
- c.Assert(f.IsClosed(), Equals, false)
-
- _, err = f.Write([]byte("foo"))
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
-
- f, err = s.Fs.Open(f.Filename())
- c.Assert(err, IsNil)
-
- wrote, err := ioutil.ReadAll(f)
- c.Assert(err, IsNil)
- c.Assert(string(wrote), DeepEquals, "foo")
- c.Assert(f.Close(), IsNil)
-}
-
-func (s *FilesystemSuite) TestOpenFileNoTruncate(c *C) {
- defaultMode := os.FileMode(0666)
-
- // Create when it does not exist
- f, err := s.Fs.OpenFile("foo1", os.O_CREATE|os.O_WRONLY, defaultMode)
- c.Assert(err, IsNil)
- c.Assert(f.Filename(), Equals, "foo1")
- s.testWriteClose(c, f, "foo1")
-
- f, err = s.Fs.OpenFile("foo1", os.O_RDONLY, defaultMode)
- c.Assert(err, IsNil)
- s.testReadClose(c, f, "foo1")
-
- // Create when it does exist
- f, err = s.Fs.OpenFile("foo1", os.O_CREATE|os.O_WRONLY, defaultMode)
- c.Assert(err, IsNil)
- c.Assert(f.Filename(), Equals, "foo1")
- s.testWriteClose(c, f, "bar")
-
- f, err = s.Fs.OpenFile("foo1", os.O_RDONLY, defaultMode)
- c.Assert(err, IsNil)
- s.testReadClose(c, f, "bar1")
-}
-
-func (s *FilesystemSuite) TestOpenFileAppend(c *C) {
- defaultMode := os.FileMode(0666)
-
- f, err := s.Fs.OpenFile("foo1", os.O_CREATE|os.O_WRONLY|os.O_APPEND, defaultMode)
- c.Assert(err, IsNil)
- c.Assert(f.Filename(), Equals, "foo1")
- s.testWriteClose(c, f, "foo1")
-
- f, err = s.Fs.OpenFile("foo1", os.O_WRONLY|os.O_APPEND, defaultMode)
- c.Assert(err, IsNil)
- c.Assert(f.Filename(), Equals, "foo1")
- s.testWriteClose(c, f, "bar1")
-
- f, err = s.Fs.OpenFile("foo1", os.O_RDONLY, defaultMode)
- c.Assert(err, IsNil)
- s.testReadClose(c, f, "foo1bar1")
-}
-
-func (s *FilesystemSuite) TestOpenFileReadWrite(c *C) {
- defaultMode := os.FileMode(0666)
-
- f, err := s.Fs.OpenFile("foo1", os.O_CREATE|os.O_TRUNC|os.O_RDWR, defaultMode)
- c.Assert(err, IsNil)
- c.Assert(f.Filename(), Equals, "foo1")
-
- written, err := f.Write([]byte("foobar"))
- c.Assert(written, Equals, 6)
- c.Assert(err, IsNil)
-
- _, err = f.Seek(0, os.SEEK_SET)
- c.Assert(err, IsNil)
-
- written, err = f.Write([]byte("qux"))
- c.Assert(written, Equals, 3)
- c.Assert(err, IsNil)
-
- _, err = f.Seek(0, os.SEEK_SET)
- c.Assert(err, IsNil)
-
- s.testReadClose(c, f, "quxbar")
-}
-
-func (s *FilesystemSuite) TestOpenFile(c *C) {
- defaultMode := os.FileMode(0666)
-
- f, err := s.Fs.OpenFile("foo1", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, defaultMode)
- c.Assert(err, IsNil)
- s.testWriteClose(c, f, "foo1")
-
- // Truncate if it exists
- f, err = s.Fs.OpenFile("foo1", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, defaultMode)
- c.Assert(err, IsNil)
- c.Assert(f.Filename(), Equals, "foo1")
- s.testWriteClose(c, f, "foo1overwritten")
-
- // Read-only if it exists
- f, err = s.Fs.OpenFile("foo1", os.O_RDONLY, defaultMode)
- c.Assert(err, IsNil)
- c.Assert(f.Filename(), Equals, "foo1")
- s.testReadClose(c, f, "foo1overwritten")
-
- // Create when it does exist
- f, err = s.Fs.OpenFile("foo1", os.O_CREATE|os.O_WRONLY|os.O_TRUNC, defaultMode)
- c.Assert(err, IsNil)
- c.Assert(f.Filename(), Equals, "foo1")
- s.testWriteClose(c, f, "bar")
-
- f, err = s.Fs.OpenFile("foo1", os.O_RDONLY, defaultMode)
- c.Assert(err, IsNil)
- s.testReadClose(c, f, "bar")
-}
-
-func (s *FilesystemSuite) testWriteClose(c *C, f File, content string) {
- written, err := f.Write([]byte(content))
- c.Assert(written, Equals, len(content))
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
-}
-
-func (s *FilesystemSuite) testReadClose(c *C, f File, content string) {
- read, err := ioutil.ReadAll(f)
- c.Assert(err, IsNil)
- c.Assert(string(read), Equals, content)
- c.Assert(f.Close(), IsNil)
-}
-
-func (s *FilesystemSuite) TestFileCreateReadSeek(c *C) {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
-
- n, err := f.Write([]byte("0123456789abcdefghijklmnopqrstuvwxyz"))
- c.Assert(err, IsNil)
- c.Assert(n, Equals, 36)
-
- p, err := f.Seek(10, io.SeekStart)
- c.Assert(err, IsNil)
- c.Assert(int(p), Equals, 10)
-
- all, err := ioutil.ReadAll(f)
- c.Assert(err, IsNil)
- c.Assert(string(all), Equals, "abcdefghijklmnopqrstuvwxyz")
- c.Assert(f.Close(), IsNil)
-}
-
-func (s *FilesystemSuite) TestFileOpenReadSeek(c *C) {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
-
- n, err := f.Write([]byte("0123456789abcdefghijklmnopqrstuvwxyz"))
- c.Assert(err, IsNil)
- c.Assert(n, Equals, 36)
-
- c.Assert(f.Close(), IsNil)
-
- f, err = s.Fs.Open("foo")
- c.Assert(err, IsNil)
-
- p, err := f.Seek(10, io.SeekStart)
- c.Assert(err, IsNil)
- c.Assert(int(p), Equals, 10)
-
- all, err := ioutil.ReadAll(f)
- c.Assert(err, IsNil)
- c.Assert(string(all), Equals, "abcdefghijklmnopqrstuvwxyz")
- c.Assert(f.Close(), IsNil)
-}
-
-func (s *FilesystemSuite) TestFileCloseTwice(c *C) {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
-
- c.Assert(f.Close(), IsNil)
- c.Assert(f.Close(), NotNil)
-}
-
-func (s *FilesystemSuite) TestReadDirAndDir(c *C) {
- files := []string{"foo", "bar", "qux/baz", "qux/qux"}
- for _, name := range files {
- f, err := s.Fs.Create(name)
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
- }
-
- info, err := s.Fs.ReadDir("/")
- c.Assert(err, IsNil)
- c.Assert(info, HasLen, 3)
-
- info, err = s.Fs.ReadDir("/qux")
- c.Assert(err, IsNil)
- c.Assert(info, HasLen, 2)
-
- qux := s.Fs.Dir("/qux")
- info, err = qux.ReadDir("/")
- c.Assert(err, IsNil)
- c.Assert(info, HasLen, 2)
-}
-
-func (s *FilesystemSuite) TestReadDirFileInfo(c *C) {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
- n, err := f.Write([]byte{'F', 'O', 'O'})
- c.Assert(n, Equals, 3)
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
-
- info, err := s.Fs.ReadDir("/")
- c.Assert(err, IsNil)
- c.Assert(info, HasLen, 1)
-
- c.Assert(info[0].Size(), Equals, int64(3))
- c.Assert(info[0].IsDir(), Equals, false)
- c.Assert(info[0].Name(), Equals, "foo")
-}
-
-func (s *FilesystemSuite) TestReadDirFileInfoDirs(c *C) {
- files := []string{"qux/baz/foo"}
- for _, name := range files {
- f, err := s.Fs.Create(name)
- c.Assert(err, IsNil)
- n, err := f.Write([]byte{'F', 'O', 'O'})
- c.Assert(n, Equals, 3)
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
- }
-
- info, err := s.Fs.ReadDir("qux")
- c.Assert(err, IsNil)
- c.Assert(info, HasLen, 1)
- c.Assert(info[0].IsDir(), Equals, true)
- c.Assert(info[0].Name(), Equals, "baz")
-
- info, err = s.Fs.ReadDir("qux/baz")
- c.Assert(err, IsNil)
- c.Assert(info, HasLen, 1)
- c.Assert(info[0].Size(), Equals, int64(3))
- c.Assert(info[0].IsDir(), Equals, false)
- c.Assert(info[0].Name(), Equals, "foo")
-}
-
-func (s *FilesystemSuite) TestDirStat(c *C) {
- files := []string{"foo", "bar", "qux/baz", "qux/qux"}
- for _, name := range files {
- f, err := s.Fs.Create(name)
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
- }
-
- qux := s.Fs.Dir("qux")
- fi, err := qux.Stat("baz")
- c.Assert(err, IsNil)
- c.Assert(fi.Name(), Equals, "baz")
-
- fi, err = qux.Stat("/baz")
- c.Assert(err, IsNil)
- c.Assert(fi.Name(), Equals, "baz")
-}
-
-func (s *FilesystemSuite) TestCreateInDir(c *C) {
- dir := s.Fs.Dir("foo")
- f, err := dir.Create("bar")
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
- c.Assert(f.Filename(), Equals, "bar")
-}
-
-func (s *FilesystemSuite) TestRename(c *C) {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
-
- err = s.Fs.Rename("foo", "bar")
- c.Assert(err, IsNil)
-
- foo, err := s.Fs.Stat("foo")
- c.Assert(foo, IsNil)
- c.Assert(err, NotNil)
-
- bar, err := s.Fs.Stat("bar")
- c.Assert(bar, NotNil)
- c.Assert(err, IsNil)
-}
-
-func (s *FilesystemSuite) TestTempFile(c *C) {
- f, err := s.Fs.TempFile("", "bar")
- c.Assert(err, IsNil)
-
- c.Assert(strings.HasPrefix(f.Filename(), "bar"), Equals, true)
-}
-
-func (s *FilesystemSuite) TestTempFileWithPath(c *C) {
- f, err := s.Fs.TempFile("foo", "bar")
- c.Assert(err, IsNil)
- c.Assert(strings.HasPrefix(f.Filename(), s.Fs.Join("foo", "bar")), Equals, true)
-}
-
-func (s *FilesystemSuite) TestTempFileFullWithPath(c *C) {
- f, err := s.Fs.TempFile("/foo", "bar")
- c.Assert(err, IsNil)
- c.Assert(strings.HasPrefix(f.Filename(), s.Fs.Join("foo", "bar")), Equals, true)
-}
-
-func (s *FilesystemSuite) TestOpenAndWrite(c *C) {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
-
- foo, err := s.Fs.Open("foo")
- c.Assert(foo, NotNil)
- c.Assert(err, IsNil)
-
- n, err := foo.Write([]byte("foo"))
- c.Assert(err, NotNil)
- c.Assert(n, Equals, 0)
-}
-
-func (s *FilesystemSuite) TestOpenAndStat(c *C) {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
-
- foo, err := s.Fs.Open("foo")
- c.Assert(foo, NotNil)
- c.Assert(foo.Filename(), Equals, "foo")
- c.Assert(err, IsNil)
-
- stat, err := s.Fs.Stat("foo")
- c.Assert(stat, NotNil)
- c.Assert(err, IsNil)
- c.Assert(stat.Name(), Equals, "foo")
-}
-
-func (s *FilesystemSuite) TestRemove(c *C) {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
-
- err = s.Fs.Remove("foo")
- c.Assert(err, IsNil)
-}
-
-func (s *FilesystemSuite) TestRemoveNonExisting(c *C) {
- c.Assert(s.Fs.Remove("NON-EXISTING"), NotNil)
-}
-
-func (s *FilesystemSuite) TestRemoveTempFile(c *C) {
- f, err := s.Fs.TempFile("test-dir", "test-prefix")
- c.Assert(err, IsNil)
-
- fn := f.Filename()
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
-
- c.Assert(s.Fs.Remove(fn), IsNil)
-}
-
-func (s *FilesystemSuite) TestJoin(c *C) {
- c.Assert(s.Fs.Join("foo", "bar"), Equals, "foo/bar")
-}
-
-func (s *FilesystemSuite) TestBase(c *C) {
- c.Assert(s.Fs.Base(), Not(Equals), "")
-}
-
-func (s *FilesystemSuite) TestReadAtOnReadWrite(c *C) {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
- _, err = f.Write([]byte("abcdefg"))
- c.Assert(err, IsNil)
- rf, ok := f.(io.ReaderAt)
- c.Assert(ok, Equals, true)
- b := make([]byte, 3)
- n, err := rf.ReadAt(b, 2)
- c.Assert(err, IsNil)
- c.Assert(n, Equals, 3)
- c.Assert(string(b), Equals, "cde")
- c.Assert(f.Close(), IsNil)
-}
-
-func (s *FilesystemSuite) TestReadAtOnReadOnly(c *C) {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
- _, err = f.Write([]byte("abcdefg"))
- c.Assert(err, IsNil)
- c.Assert(f.Close(), IsNil)
-
- f, err = s.Fs.Open("foo")
- c.Assert(err, IsNil)
- rf, ok := f.(io.ReaderAt)
- c.Assert(ok, Equals, true)
- b := make([]byte, 3)
- n, err := rf.ReadAt(b, 2)
- c.Assert(err, IsNil)
- c.Assert(n, Equals, 3)
- c.Assert(string(b), Equals, "cde")
- c.Assert(f.Close(), IsNil)
-}
-
-func (s *FilesystemSuite) TestReadWriteLargeFile(c *C) {
- f, err := s.Fs.Create("foo")
- c.Assert(err, IsNil)
-
- size := 1 << 20
-
- n, err := f.Write(bytes.Repeat([]byte("F"), size))
- c.Assert(err, IsNil)
- c.Assert(n, Equals, size)
-
- err = f.Close()
- c.Assert(err, IsNil)
-
- f, err = s.Fs.Open("foo")
- c.Assert(err, IsNil)
- b, err := ioutil.ReadAll(f)
- c.Assert(err, IsNil)
- c.Assert(len(b), Equals, size)
-}