diff --git a/pkg/filesystem/directory_posix.go b/pkg/filesystem/directory_posix.go index 5d7b6403..4e9095de 100644 --- a/pkg/filesystem/directory_posix.go +++ b/pkg/filesystem/directory_posix.go @@ -4,6 +4,7 @@ package filesystem import ( "os" + "path/filepath" "runtime" "strconv" "strings" @@ -519,6 +520,28 @@ func Rename( ) } +// Touch updates the access and modification times of the given path to the +// current time. +// +// This function does not create non-existent files. +func Touch(directory *Directory, nameOrPath string) error { + var filePath string + + // If a target directory has been provided, then verify that the target name + // is a valid name and not a path. + if directory != nil { + if err := ensureValidName(nameOrPath); err != nil { + return errors.Wrap(err, "target name invalid") + } + filePath = filepath.Join(directory.file.Name(), nameOrPath) + } else { + filePath = nameOrPath + } + + now := time.Now() + return os.Chtimes(filePath, now, now) +} + // IsCrossDeviceError checks whether or not an error returned from rename // represents a cross-device error. func IsCrossDeviceError(err error) bool { diff --git a/pkg/filesystem/directory_windows.go b/pkg/filesystem/directory_windows.go index 83a3b64d..edd182ec 100644 --- a/pkg/filesystem/directory_windows.go +++ b/pkg/filesystem/directory_windows.go @@ -6,6 +6,7 @@ import ( "path/filepath" "strings" "syscall" + "time" "github.com/pkg/errors" @@ -521,6 +522,28 @@ func Rename( return os.Rename(sourceNameOrPath, targetNameOrPath) } +// Touch updates the access and modification times of the given path to the +// current time. +// +// This function does not create non-existent files. +func Touch(directory *Directory, nameOrPath string) error { + var filePath string + + // If a target directory has been provided, then verify that the target name + // is a valid name and not a path. + if directory != nil { + if err := ensureValidName(nameOrPath); err != nil { + return errors.Wrap(err, "target name invalid") + } + filePath = filepath.Join(directory.file.Name(), nameOrPath) + } else { + filePath = nameOrPath + } + + now := time.Now() + return os.Chtimes(filePath, now, now) +} + const ( // _ERROR_NOT_SAME_DEVICE is the error code returned by MoveFileEx on // Windows when attempting to move a file across devices. This can actually diff --git a/pkg/synchronization/core/transition.go b/pkg/synchronization/core/transition.go index 7702d701..1374abaa 100644 --- a/pkg/synchronization/core/transition.go +++ b/pkg/synchronization/core/transition.go @@ -552,6 +552,10 @@ func (t *transitioner) findAndMoveStagedFileIntoPlace( // Attempt to atomically rename the file. If we succeed, we're done. renameErr := filesystem.Rename(nil, stagedPath, parent, name) if renameErr == nil { + if true { // TODO: Only touch when configured to + // Ignore errors, since updating access and modification times is not mandatory + filesystem.Touch(parent, name) + } return nil } @@ -612,6 +616,10 @@ func (t *transitioner) findAndMoveStagedFileIntoPlace( // there's not much we can or need to do about them at this point. os.Remove(stagedPath) + if true { // TODO: Only touch when configured to + filesystem.Touch(parent, name) + } + // Success. return nil }