-
Notifications
You must be signed in to change notification settings - Fork 7
/
writer.go
67 lines (58 loc) · 1.67 KB
/
writer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
// Copyright 2020, Verizon Media Inc.
// Licensed under the terms of the 3-Clause BSD license. See LICENSE file in
// github.com/yahoo/k8s-athenz-identity for terms.
package util
import (
"bytes"
"io"
"os"
)
// Writer writes multiple files with modified suffixes and renames all of them
// to their final names on save.
type Writer struct {
files []string
}
// NewWriter returns a writer.
func NewWriter() *Writer {
return &Writer{}
}
func tmpFile(file string) string {
return file + ".tmp"
}
// AddBytes writes a file with the supplied bytes.
func (w *Writer) AddBytes(target string, perms os.FileMode, content []byte) error {
return w.AddReader(target, perms, bytes.NewBuffer(content))
}
// AddFile writes a file using the supplied file as source.
func (w *Writer) AddFile(target string, perms os.FileMode, source string) error {
f, err := os.Open(source)
if err != nil {
return err
}
defer f.Close()
return w.AddReader(target, perms, f)
}
// AddReader writes a file using the supplied reader as source.
func (w *Writer) AddReader(target string, perms os.FileMode, content io.Reader) error {
t := tmpFile(target)
f, err := os.OpenFile(t, os.O_WRONLY|os.O_TRUNC|os.O_CREATE, perms)
if err != nil {
return err
}
defer f.Close()
if _, err := io.Copy(f, content); err != nil {
return err
}
w.files = append(w.files, target)
return nil
}
// Save renames all temp files written to their final names. When multiple files are involved,
// this reduces race conditions with inconsistent data but does not completely eliminate it.
func (w *Writer) Save() error {
for _, f := range w.files {
if err := os.Rename(tmpFile(f), f); err != nil {
return err
}
}
return nil
}