Skip to content

Commit 18f8786

Browse files
authored
Merge pull request #98 from pjbgf/memfs-modtime
memfs: Add deterministic modification times
2 parents 6f20320 + 36eabfe commit 18f8786

File tree

3 files changed

+50
-8
lines changed

3 files changed

+50
-8
lines changed

memfs/memory.go

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -228,6 +228,7 @@ type file struct {
228228
position int64
229229
flag int
230230
mode os.FileMode
231+
modTime time.Time
231232

232233
isClosed bool
233234
}
@@ -291,6 +292,7 @@ func (f *file) WriteAt(p []byte, off int64) (int, error) {
291292
return 0, errors.New("write not supported")
292293
}
293294

295+
f.modTime = time.Now()
294296
n, err := f.content.WriteAt(p, off)
295297
f.position = off + int64(n)
296298

@@ -322,6 +324,7 @@ func (f *file) Duplicate(filename string, mode os.FileMode, flag int) billy.File
322324
content: f.content,
323325
mode: mode,
324326
flag: flag,
327+
modTime: f.modTime,
325328
}
326329

327330
if isTruncate(flag) {
@@ -337,9 +340,10 @@ func (f *file) Duplicate(filename string, mode os.FileMode, flag int) billy.File
337340

338341
func (f *file) Stat() (os.FileInfo, error) {
339342
return &fileInfo{
340-
name: f.Name(),
341-
mode: f.mode,
342-
size: f.content.Len(),
343+
name: f.Name(),
344+
mode: f.mode,
345+
size: f.content.Len(),
346+
modTime: f.modTime,
343347
}, nil
344348
}
345349

@@ -354,9 +358,10 @@ func (f *file) Unlock() error {
354358
}
355359

356360
type fileInfo struct {
357-
name string
358-
size int
359-
mode os.FileMode
361+
name string
362+
size int
363+
mode os.FileMode
364+
modTime time.Time
360365
}
361366

362367
func (fi *fileInfo) Name() string {
@@ -371,8 +376,8 @@ func (fi *fileInfo) Mode() os.FileMode {
371376
return fi.mode
372377
}
373378

374-
func (*fileInfo) ModTime() time.Time {
375-
return time.Now()
379+
func (fi *fileInfo) ModTime() time.Time {
380+
return fi.modTime
376381
}
377382

378383
func (fi *fileInfo) IsDir() bool {

memfs/memory_test.go

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,12 @@ import (
66
"os"
77
"runtime"
88
"testing"
9+
"time"
910

1011
"github.com/go-git/go-billy/v5"
1112
"github.com/go-git/go-billy/v5/util"
1213
"github.com/stretchr/testify/assert"
14+
"github.com/stretchr/testify/require"
1315
)
1416

1517
func TestRootExists(t *testing.T) {
@@ -28,6 +30,39 @@ func TestCapabilities(t *testing.T) {
2830
assert.Equal(t, billy.DefaultCapabilities&^billy.LockCapability, caps)
2931
}
3032

33+
func TestModTime(t *testing.T) {
34+
fs := New()
35+
_, err := fs.Create("/file1")
36+
require.NoError(t, err)
37+
38+
if runtime.GOOS == "windows" {
39+
time.Sleep(20 * time.Millisecond)
40+
}
41+
42+
_, err = fs.Create("/file2")
43+
require.NoError(t, err)
44+
45+
fi1a, err := fs.Stat("/file1")
46+
require.NoError(t, err)
47+
48+
fi2, err := fs.Stat("/file2")
49+
require.NoError(t, err)
50+
51+
fi1b, err := fs.Stat("/file1")
52+
require.NoError(t, err)
53+
54+
modtime := fi1a.ModTime()
55+
56+
// file 1 and file 2 should have different mod times.
57+
assert.NotEqual(t, modtime, fi2.ModTime())
58+
59+
// a new file info for the same unmodified file, should still match mod time.
60+
assert.Equal(t, modtime, fi1b.ModTime())
61+
62+
// new calls to ModTime() retain existing mod time.
63+
assert.Equal(t, modtime, fi1a.ModTime())
64+
}
65+
3166
func TestNegativeOffsets(t *testing.T) {
3267
fs := New()
3368
f, err := fs.Create("negative")

memfs/storage.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import (
88
"path/filepath"
99
"strings"
1010
"sync"
11+
"time"
1112
)
1213

1314
type storage struct {
@@ -46,6 +47,7 @@ func (s *storage) New(path string, mode os.FileMode, flag int) (*file, error) {
4647
content: &content{name: name},
4748
mode: mode,
4849
flag: flag,
50+
modTime: time.Now(),
4951
}
5052

5153
s.files[path] = f

0 commit comments

Comments
 (0)