Skip to content

Commit

Permalink
Undo dir mod time removal
Browse files Browse the repository at this point in the history
Mistakenly removed those tests and the mod time code.

Signed-off-by: Gabriel Adrian Samfira <[email protected]>
  • Loading branch information
gabriel-samfira committed Feb 9, 2023
1 parent e66cb41 commit 4594477
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 13 deletions.
1 change: 1 addition & 0 deletions chtimes_nolinux.go
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
//go:build !linux
// +build !linux

package fsutil
Expand Down
3 changes: 3 additions & 0 deletions copy/mkdir.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,17 +22,20 @@ func MkdirAll(path string, perm os.FileMode, user Chowner, tm *time.Time) error
for i > 0 && os.IsPathSeparator(path[i-1]) { // Skip trailing path separator.
i--
}

j := i
for j > 0 && !os.IsPathSeparator(path[j-1]) { // Scan backward over element.
j--
}

if j > 1 {
// Create parent.
err = MkdirAll(fixRootDirectory(path[:j-1]), perm, user, tm)
if err != nil {
return err
}
}

dir, err1 := os.Lstat(path)
if err1 == nil && dir.IsDir() {
return nil
Expand Down
3 changes: 1 addition & 2 deletions diff.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ import (
"context"
"hash"
"os"
"path/filepath"

"github.com/pkg/errors"
"github.com/tonistiigi/fsutil/types"
Expand Down Expand Up @@ -33,7 +32,7 @@ func getWalkerFn(root string) walkerFn {
}

p := &currentPath{
path: filepath.FromSlash(path),
path: path,
stat: stat,
}

Expand Down
40 changes: 29 additions & 11 deletions diskwriter.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"hash"
"io"
gofs "io/fs"
"os"
"path/filepath"
"strconv"
Expand Down Expand Up @@ -33,10 +34,11 @@ type DiskWriter struct {
opt DiskWriterOpt
dest string

ctx context.Context
cancel func()
eg *errgroup.Group
filter FilterFunc
ctx context.Context
cancel func()
eg *errgroup.Group
filter FilterFunc
dirModTimes map[string]int64
}

func NewDiskWriter(ctx context.Context, dest string, opt DiskWriterOpt) (*DiskWriter, error) {
Expand All @@ -51,17 +53,32 @@ func NewDiskWriter(ctx context.Context, dest string, opt DiskWriterOpt) (*DiskWr
eg, ctx := errgroup.WithContext(ctx)

return &DiskWriter{
opt: opt,
dest: dest,
eg: eg,
ctx: ctx,
cancel: cancel,
filter: opt.Filter,
opt: opt,
dest: dest,
eg: eg,
ctx: ctx,
cancel: cancel,
filter: opt.Filter,
dirModTimes: map[string]int64{},
}, nil
}

func (dw *DiskWriter) Wait(ctx context.Context) error {
return dw.eg.Wait()
if err := dw.eg.Wait(); err != nil {
return err
}
return filepath.WalkDir(dw.dest, func(path string, d gofs.DirEntry, prevErr error) error {
if prevErr != nil {
return prevErr
}
if !d.IsDir() {
return nil
}
if mtime, ok := dw.dirModTimes[path]; ok {
return chtimes(path, mtime)
}
return nil
})
}

func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, err error) (retErr error) {
Expand Down Expand Up @@ -147,6 +164,7 @@ func (dw *DiskWriter) HandleChange(kind ChangeKind, p string, fi os.FileInfo, er
if err := os.Mkdir(newPath, fi.Mode()); err != nil {
return errors.Wrapf(err, "failed to create dir %s", newPath)
}
dw.dirModTimes[destPath] = statCopy.ModTime
case fi.Mode()&os.ModeDevice != 0 || fi.Mode()&os.ModeNamedPipe != 0:
if err := handleTarTypeBlockCharFifo(newPath, &statCopy); err != nil {
return errors.Wrapf(err, "failed to create device %s", newPath)
Expand Down
36 changes: 36 additions & 0 deletions receive_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,42 @@ func TestCopyWithSubDir(t *testing.T) {
assert.Equal(t, "data1", string(dt))
}

func TestCopyDirectoryTimestamps(t *testing.T) {
d, err := tmpDir(changeStream([]string{
"ADD foo dir",
"ADD foo/bar file data1",
}))
assert.NoError(t, err)
defer os.RemoveAll(d)

timestamp := time.Unix(0, 0)
require.NoError(t, os.Chtimes(filepath.Join(d, "foo"), timestamp, timestamp))

dest := t.TempDir()

eg, ctx := errgroup.WithContext(context.Background())
s1, s2 := sockPairProto(ctx)

eg.Go(func() error {
defer s1.(*fakeConnProto).closeSend()
return Send(ctx, s1, NewFS(d, nil), nil)
})
eg.Go(func() error {
return Receive(ctx, s2, dest, ReceiveOpt{})
})

err = eg.Wait()
assert.NoError(t, err)

dt, err := os.ReadFile(filepath.Join(dest, "foo/bar"))
assert.NoError(t, err)
assert.Equal(t, "data1", string(dt))

stat, err := os.Stat(filepath.Join(dest, "foo"))
require.NoError(t, err)
assert.Equal(t, timestamp, stat.ModTime())
}

func TestCopySwitchDirToFile(t *testing.T) {
d, err := tmpDir(changeStream([]string{
"ADD foo file data1",
Expand Down

0 comments on commit 4594477

Please sign in to comment.