-
Notifications
You must be signed in to change notification settings - Fork 467
/
sourcestateentry.go
289 lines (243 loc) · 7.97 KB
/
sourcestateentry.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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
package chezmoi
import (
"encoding/hex"
"log/slog"
"github.com/twpayne/chezmoi/v2/internal/chezmoilog"
)
// A SourceAttr contains attributes of the source.
type SourceAttr struct {
Condition ScriptCondition
Encrypted bool
External bool
Template bool
}
// A SourceStateOrigin represents the origin of a source state.
type SourceStateOrigin interface {
Path() AbsPath
OriginString() string
}
// A SourceStateOriginAbsPath is an absolute path.
type SourceStateOriginAbsPath AbsPath
// A SourceStateEntry represents the state of an entry in the source state.
type SourceStateEntry interface {
slog.LogValuer
Evaluate() error
Order() ScriptOrder
Origin() SourceStateOrigin
SourceRelPath() SourceRelPath
TargetStateEntry(destSystem System, destDirAbsPath AbsPath) (TargetStateEntry, error)
}
// A SourceStateCommand represents a command that should be run.
type SourceStateCommand struct {
cmd *lazyCommand
origin SourceStateOrigin
forceRefresh bool
refreshPeriod Duration
sourceAttr SourceAttr
}
// A SourceStateDir represents the state of a directory in the source state.
type SourceStateDir struct {
Attr DirAttr
origin SourceStateOrigin
sourceRelPath SourceRelPath
targetStateEntry TargetStateEntry
}
// A SourceStateFile represents the state of a file in the source state.
type SourceStateFile struct {
*lazyContents
Attr FileAttr
origin SourceStateOrigin
sourceRelPath SourceRelPath
targetStateEntryFunc targetStateEntryFunc
targetStateEntry TargetStateEntry
targetStateEntryErr error
}
// A SourceStateImplicitDir represents the state of a directory that is implicit
// in the source state, typically because it is a parent directory of an
// external. Implicit directories have no attributes and are considered
// equivalent to any other directory.
type SourceStateImplicitDir struct {
origin SourceStateOrigin
targetStateEntry TargetStateEntry
}
// A SourceStateRemove represents that an entry should be removed.
type SourceStateRemove struct {
origin SourceStateOrigin
sourceRelPath SourceRelPath
targetRelPath RelPath
}
// A SourceStateOriginRemove is used for removes. The source of the remove is
// not currently tracked. The remove could come from an exact_ directory, a
// non-empty_ file with empty contents, or one of many patterns in many
// .chezmoiignore files.
//
// FIXME remove this when the sources of all removes are tracked.
type SourceStateOriginRemove struct{}
// Evaluate evaluates s and returns any error.
func (s *SourceStateCommand) Evaluate() error {
return nil
}
// LogValue implements log/slog.LogValuer.LogValue.
func (s *SourceStateCommand) LogValue() slog.Value {
return slog.GroupValue(
slog.Any("cmd", chezmoilog.OSExecCmdLogValuer{Cmd: s.cmd.Command()}),
slog.String("origin", s.origin.OriginString()),
)
}
// Order returns s's order.
func (s *SourceStateCommand) Order() ScriptOrder {
return ScriptOrderDuring
}
// Origin returns s's origin.
func (s *SourceStateCommand) Origin() SourceStateOrigin {
return s.origin
}
// SourceRelPath returns s's source relative path.
func (s *SourceStateCommand) SourceRelPath() SourceRelPath {
return emptySourceRelPath
}
// TargetStateEntry returns s's target state entry.
func (s *SourceStateCommand) TargetStateEntry(destSystem System, destDirAbsPath AbsPath) (TargetStateEntry, error) {
return &TargetStateModifyDirWithCmd{
cmd: s.cmd,
forceRefresh: s.forceRefresh,
refreshPeriod: s.refreshPeriod,
sourceAttr: s.sourceAttr,
}, nil
}
// Evaluate evaluates s and returns any error.
func (s *SourceStateDir) Evaluate() error {
return nil
}
// LogValue implements log/slog.LogValuer.LogValue.
func (s *SourceStateDir) LogValue() slog.Value {
return slog.GroupValue(
chezmoilog.Stringer("sourceRelPath", s.sourceRelPath),
slog.Any("attr", s.Attr),
)
}
// Order returns s's order.
func (s *SourceStateDir) Order() ScriptOrder {
return ScriptOrderDuring
}
// Origin returns s's origin.
func (s *SourceStateDir) Origin() SourceStateOrigin {
return s.origin
}
// SourceRelPath returns s's source relative path.
func (s *SourceStateDir) SourceRelPath() SourceRelPath {
return s.sourceRelPath
}
// TargetStateEntry returns s's target state entry.
func (s *SourceStateDir) TargetStateEntry(destSystem System, destDirAbsPath AbsPath) (TargetStateEntry, error) {
return s.targetStateEntry, nil
}
// Evaluate evaluates s and returns any error.
func (s *SourceStateFile) Evaluate() error {
_, err := s.ContentsSHA256()
return err
}
// LogValue implements log/slog.LogValuer.LogValue.
func (s *SourceStateFile) LogValue() slog.Value {
attrs := []slog.Attr{
chezmoilog.Stringer("sourceRelPath", s.sourceRelPath),
slog.Any("attr", s.Attr),
}
contents, contentsErr := s.Contents()
attrs = append(attrs, chezmoilog.FirstFewBytes("contents", contents))
if contentsErr != nil {
attrs = append(attrs, slog.Any("contentsErr", contentsErr))
}
contentsSHA256, contentsSHA256Err := s.ContentsSHA256()
attrs = append(attrs, slog.String("contentsSHA256", hex.EncodeToString(contentsSHA256)))
if contentsSHA256Err != nil {
attrs = append(attrs, slog.Any("contentsSHA256Err", contentsSHA256Err))
}
return slog.GroupValue(attrs...)
}
// Order returns s's order.
func (s *SourceStateFile) Order() ScriptOrder {
return s.Attr.Order
}
// Origin returns s's origin.
func (s *SourceStateFile) Origin() SourceStateOrigin {
return s.origin
}
// SourceRelPath returns s's source relative path.
func (s *SourceStateFile) SourceRelPath() SourceRelPath {
return s.sourceRelPath
}
// TargetStateEntry returns s's target state entry.
func (s *SourceStateFile) TargetStateEntry(destSystem System, destDirAbsPath AbsPath) (TargetStateEntry, error) {
if s.targetStateEntryFunc != nil {
s.targetStateEntry, s.targetStateEntryErr = s.targetStateEntryFunc(destSystem, destDirAbsPath)
s.targetStateEntryFunc = nil
}
return s.targetStateEntry, s.targetStateEntryErr
}
// Evaluate evaluates s and returns any error.
func (s *SourceStateImplicitDir) Evaluate() error {
return nil
}
// LogValue implements log/slog.LogValuer.LogValue.
func (s *SourceStateImplicitDir) LogValue() slog.Value {
return slog.GroupValue()
}
// Order returns s's order.
func (s *SourceStateImplicitDir) Order() ScriptOrder {
return ScriptOrderDuring
}
// Origin returns s's origin.
func (s *SourceStateImplicitDir) Origin() SourceStateOrigin {
return s.origin
}
// SourceRelPath returns s's source relative path.
func (s *SourceStateImplicitDir) SourceRelPath() SourceRelPath {
return emptySourceRelPath
}
// TargetStateEntry returns s's target state entry.
func (s *SourceStateImplicitDir) TargetStateEntry(destSystem System, destDirAbsPath AbsPath) (TargetStateEntry, error) {
return s.targetStateEntry, nil
}
// Evaluate evaluates s and returns any error.
func (s *SourceStateRemove) Evaluate() error {
return nil
}
// LogValue implements log/slog.LogValuer.LogValue.
func (s *SourceStateRemove) LogValue() slog.Value {
return slog.GroupValue(
chezmoilog.Stringer("targetRelPath", s.targetRelPath),
)
}
// Order returns s's order.
func (s *SourceStateRemove) Order() ScriptOrder {
return ScriptOrderDuring
}
// Origin returns s's origin.
func (s *SourceStateRemove) Origin() SourceStateOrigin {
return s.origin
}
// SourceRelPath returns s's source relative path.
func (s *SourceStateRemove) SourceRelPath() SourceRelPath {
return SourceRelPath{}
}
// TargetStateEntry returns s's target state entry.
func (s *SourceStateRemove) TargetStateEntry(destSystem System, destDirAbsPath AbsPath) (TargetStateEntry, error) {
return &TargetStateRemove{}, nil
}
// Path returns s's path.
func (s SourceStateOriginAbsPath) Path() AbsPath {
return AbsPath(s)
}
// OriginString returns s's origin.
func (s SourceStateOriginAbsPath) OriginString() string {
return AbsPath(s).String()
}
// Path returns s's path.
func (s SourceStateOriginRemove) Path() AbsPath {
return EmptyAbsPath
}
// OriginString returns s's origin.
func (s SourceStateOriginRemove) OriginString() string {
return "remove"
}