1 // Read and write the state file used to keep data over multiple runs
3 // Copyright (C) 2019-2021 Simon Ruderich
5 // This program is free software: you can redistribute it and/or modify
6 // it under the terms of the GNU Affero General Public License as published by
7 // the Free Software Foundation, either version 3 of the License, or
8 // (at your option) any later version.
10 // This program is distributed in the hope that it will be useful,
11 // but WITHOUT ANY WARRANTY; without even the implied warranty of
12 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 // GNU Affero General Public License for more details.
15 // You should have received a copy of the GNU Affero General Public License
16 // along with this program. If not, see <https://www.gnu.org/licenses/>.
27 "github.com/google/renameio"
32 LastModified map[string]time.Time
33 Checksum map[string]string // SHA512 in hex
36 func LoadState(path string) (*State, error) {
39 x, err := ioutil.ReadFile(path)
41 // It's fine if the state file does not exist yet, we'll
42 // create it later when writing the state
43 if !os.IsNotExist(err) {
47 err := json.Unmarshal(x, &state)
53 if state.LastModified == nil {
54 state.LastModified = make(map[string]time.Time)
56 if state.Checksum == nil {
57 state.Checksum = make(map[string]string)
63 func WriteState(path string, state *State) error {
64 // Update the state file even if nothing has changed to provide a
65 // simple way to check if nsscash ran successfully (the state is only
66 // updated if there were no errors)
68 x, err := json.Marshal(state)
73 f, err := renameio.TempFile(filepath.Dir(path), path)
83 err = f.CloseAtomicallyReplace()
87 return syncPath(filepath.Dir(path))