fyne icon indicating copy to clipboard operation
fyne copied to clipboard

storage.Move() must keep file modification time unchanged

Open vinser opened this issue 2 years ago • 2 comments

Checklist

  • [X] I have searched the issue tracker for open issues that relate to the same problem, before opening a new one.
  • [X] This issue only relates to a single bug. I will open new issues for any other problems.

Describe the bug

When moving file with storage.Move() the tatter sets file modification time to current time unlike os.Rename()

How to reproduce

Run the code below

Screenshots

os package ================ time: 2023-11-10 15:32:12 +0500 +05 ./os_source.txt time: 2023-11-10 15:32:12 +0500 +05 ./os_renamed.txt storage package ================ time: 2023-11-10 15:32:12 +0500 +05 ./storage_source.txt time: 2023-11-11 10:32:12.078185654 +0500 +05 ./storage_moved.txt

Example code

package main

import (
	"fmt"
	"log"
	"os"
	"time"

	"fyne.io/fyne/v2/app"
	"fyne.io/fyne/v2/storage"
)

func main() {
	a := app.NewWithID("com.github.vinser.t_uri")
	w := a.NewWindow("Move Files")
	doJob()
	w.Close()
}

func doJob() {
	yesterday := time.Now().Add(-24 * time.Hour).Format("2006.01.02 15:04:05")
	content := "File test content"

	// os package
	fmt.Println("os package ================")
	CreateFile("./os_source.txt", yesterday, content)
	printFileInfo("./os_source.txt")
	os.Rename("./os_source.txt", "./os_renamed.txt")
	printFileInfo("./os_renamed.txt")

	// storage package
	fmt.Println("storage package ================")
	CreateFile("./storage_source.txt", yesterday, content)
	printFileInfo("./storage_source.txt")
	storage.Move(storage.NewFileURI("./storage_source.txt"), storage.NewFileURI("./storage_moved.txt"))
	printFileInfo("./storage_moved.txt")
}

func CreateFile(name, date, content string) error {
	err := createFileWithContent(name, content)
	if err != nil {
		return err
	}
	return setFileDate(name, date)
}
func createFileWithContent(name, content string) error {
	f, err := os.Create(name)
	if err != nil {
		log.Fatal(err)
	}
	defer f.Close()
	_, err = f.WriteString(content)

	return err
}

func setFileDate(name, date string) error {
	newTime, err := time.Parse("2006.01.02 15:04:05", date)
	if err != nil {
		return err
	}
	return os.Chtimes(name, newTime, newTime)
}

func printFileInfo(name string) {
	stat, err := os.Stat(name)
	if err != nil {
		log.Fatal(err)
	}
	fmt.Println("time:", stat.ModTime(), name)
}

Fyne version

2.4.1

Go compiler version

1.21.4

Operating system and version

Ubuntu mate 22.04

Additional Information

No response

vinser avatar Nov 11 '23 07:11 vinser

The challenge is that Move is not a Rename operation. It works across filesystem boundaries and storage schemes.

It may be possible to detect if the source and destination are both files on the same storage volume and issue a move instead of a data copy... would need to look into what assumptions came before made at the storage level.

andydotxyz avatar Nov 11 '23 07:11 andydotxyz

Also, check out internal/repository/file.go:293, the comments there may be wrong or out of date.

andydotxyz avatar Nov 11 '23 21:11 andydotxyz