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 }