Files
diple/persistence.go

54 lines
1.0 KiB
Go

package main
import (
"encoding/json"
"errors"
"os"
"path/filepath"
)
func atomicWriteJSON(path string, value any, mode os.FileMode) error {
if path == "" {
return nil
}
dir := filepath.Dir(path)
if err := os.MkdirAll(dir, 0o700); err != nil {
return err
}
data, err := json.MarshalIndent(value, "", " ")
if err != nil {
return err
}
temp, err := os.CreateTemp(dir, ".diple-*")
if err != nil {
return err
}
name := temp.Name()
defer os.Remove(name)
if err := temp.Chmod(mode); err != nil {
_ = temp.Close()
return err
}
if _, err := temp.Write(data); err != nil {
_ = temp.Close()
return err
}
if err := temp.Sync(); err != nil {
_ = temp.Close()
return err
}
if err := temp.Close(); err != nil {
return err
}
if err := os.Rename(name, path); err != nil {
return err
}
if directory, err := os.Open(dir); err == nil {
defer directory.Close()
if syncErr := directory.Sync(); syncErr != nil && !errors.Is(syncErr, os.ErrInvalid) {
return syncErr
}
}
return nil
}