diff --git a/fileinfo.go b/fileinfo.go index cb55dbf..b95a22e 100644 --- a/fileinfo.go +++ b/fileinfo.go @@ -10,6 +10,7 @@ type fileinfo struct { size int64 modified time.Time mode fs.FileMode + sys interface{} } // Name is the base name of the file (without directory) @@ -48,7 +49,7 @@ func (f fileinfo) IsDir() bool { return f.Mode().IsDir() } -// Sys is the underlying data source of the file (always nil) +// Sys is the underlying data source of the file (can return nil) func (f fileinfo) Sys() interface{} { - return nil + return f.sys } diff --git a/fs.go b/fs.go index e7de22c..cf77840 100644 --- a/fs.go +++ b/fs.go @@ -158,3 +158,17 @@ func (m *FS) SetModified(name string, modified time.Time) error { } return &fs.PathError{Op: "set modified", Path: name, Err: fs.ErrNotExist} } + +// SetSys set underlying data source to file or directory +func (m *FS) SetSys(name string, sys interface{}) error { + name = cleanse(name) + if f, err := m.dir.getFile(name); err == nil { + f.info.sys = sys + return nil + } + if f, err := m.dir.getDir(name); err == nil { + f.info.sys = sys + return nil + } + return &fs.PathError{Op: "set sys", Path: name, Err: fs.ErrNotExist} +} diff --git a/fs_test.go b/fs_test.go index 0891ded..7a56979 100644 --- a/fs_test.go +++ b/fs_test.go @@ -263,6 +263,55 @@ func Test_AllOperations(t *testing.T) { _, err = memfs.Stat("not_found.txt") assert.Error(t, err) }) + + t.Run("Set sys to directory", func(t *testing.T) { + type sysStat struct { + Gid int + Uid int + } + + sys := sysStat{ + Uid: 123, + Gid: 456, + } + + stat, err := memfs.Stat("files/a/b/c") + assert.NoError(t, err) + assert.Nil(t, stat.Sys()) + + err = memfs.SetSys("files/a/b/c", sys) + assert.NoError(t, err) + + stat, err = memfs.Stat("files/a/b/c") + assert.NoError(t, err) + assert.Equal(t, sys, stat.Sys()) + }) + + t.Run("Set sys to file", func(t *testing.T) { + type sysStat struct { + Gid int + Uid int + } + + sys := sysStat{ + Uid: 123, + Gid: 456, + } + + stat, err := memfs.Stat("test.txt") + assert.NoError(t, err) + assert.Nil(t, stat.Sys()) + + err = memfs.SetSys("test.txt", sys) + assert.NoError(t, err) + + stat, err = memfs.Stat("test.txt") + assert.NoError(t, err) + assert.Equal(t, sys, stat.Sys()) + + err = memfs.SetSys("not_found.txt", sys) + assert.Error(t, err) + }) } func Test_ConcurrentWritesToDirectory(t *testing.T) {