// Read and write the state file used to keep data over multiple runs
-// Copyright (C) 2019 Simon Ruderich
+// Copyright (C) 2019-2021 Simon Ruderich
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
"os"
"path/filepath"
"time"
+
+ "github.com/google/renameio"
)
type State struct {
+ // Key is File.Url
LastModified map[string]time.Time
+ Checksum map[string]string // SHA512 in hex
}
func LoadState(path string) (*State, error) {
if state.LastModified == nil {
state.LastModified = make(map[string]time.Time)
}
+ if state.Checksum == nil {
+ state.Checksum = make(map[string]string)
+ }
return &state, nil
}
return err
}
- // Write the file in an atomic fashion by creating a temporary file
- // and renaming it over the target file
-
- dir := filepath.Dir(path)
- name := filepath.Base(path)
-
- f, err := ioutil.TempFile(dir, "tmp-"+name+"-")
+ f, err := renameio.TempFile(filepath.Dir(path), path)
if err != nil {
return err
}
- defer os.Remove(f.Name())
- defer f.Close()
+ defer f.Cleanup()
_, err = f.Write(x)
if err != nil {
return err
}
- err = f.Sync()
+ err = f.CloseAtomicallyReplace()
if err != nil {
return err
}
- return os.Rename(f.Name(), path)
+ return syncPath(filepath.Dir(path))
}