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
|
// Package option provides interface-based, resource-agnostic configuration
// options shared by the file, dir, and link resource packages.
package options
import (
"log"
"os"
)
// Option configures a resource. It is applied to the concrete resource value
// (e.g. *file.File) during construction.
type Option func(any)
// Capability interfaces. A resource implements only the setters it supports.
type (
Owner interface{ SetOwner(string) }
Grouped interface{ SetGroup(string) }
Moded interface{ SetMode(os.FileMode) }
Sourced interface{ SetSource(string) }
Contented interface{ SetContent(string) }
FileModed interface{ SetFileMode(os.FileMode) }
Prunable interface{ SetPrune() }
Absentable interface{ SetAbsent() }
Latestable interface{ SetLatest() }
Linkable interface {
SetSymlink(target string)
SetHardlink(target string)
}
)
// WithOwner sets the owning user of the resource.
func WithOwner(owner string) Option {
return func(t any) {
r, ok := t.(Owner)
if !ok {
log.Fatalf("%T does not support WithOwner", t)
}
r.SetOwner(owner)
}
}
// WithGroup sets the owning group of the resource.
func WithGroup(group string) Option {
return func(t any) {
r, ok := t.(Grouped)
if !ok {
log.Fatalf("%T does not support WithGroup", t)
}
r.SetGroup(group)
}
}
// WithMode sets the resource's own file mode.
func WithMode(mode os.FileMode) Option {
return func(t any) {
r, ok := t.(Moded)
if !ok {
log.Fatalf("%T does not support WithMode", t)
}
r.SetMode(mode)
}
}
// WithSource sets the source path the resource is populated from.
func WithSource(source string) Option {
return func(t any) {
r, ok := t.(Sourced)
if !ok {
log.Fatalf("%T does not support WithSource", t)
}
r.SetSource(source)
}
}
// WithContent sets literal content for the resource.
func WithContent(content string) Option {
return func(t any) {
r, ok := t.(Contented)
if !ok {
log.Fatalf("%T does not support WithContent", t)
}
r.SetContent(content)
}
}
// WithFileMode sets the mode applied to regular files copied from a source
// tree (distinct from the resource's own mode).
func WithFileMode(mode os.FileMode) Option {
return func(t any) {
r, ok := t.(FileModed)
if !ok {
log.Fatalf("%T does not support WithFileMode", t)
}
r.SetFileMode(mode)
}
}
// WithPrune enables reconciliation of extra destination entries during a
// source copy, and recursive removal during IsAbsent().
var WithPrune = func(t any) {
r, ok := t.(Prunable)
if !ok {
log.Fatalf("%T does not support WithPrune", t)
}
r.SetPrune()
}
func WithPruneFunc() Option { return WithPrune }
// IsAbsent marks the resource for removal.
var IsAbsent = func(t any) {
r, ok := t.(Absentable)
if !ok {
log.Fatalf("%T does not support IsAbsent", t)
}
r.SetAbsent()
}
func IsAbsentFunc() Option { return IsAbsent }
// IsLatest marks the package resource to be updated to the latest version.
var IsLatest = func(t any) {
r, ok := t.(Latestable)
if !ok {
log.Fatalf("%T does not support IsLatest", t)
}
r.SetLatest()
}
func IsLatestFunc() Option { return IsLatest }
// WithSymlink makes the resource a symbolic link pointing at target.
func WithSymlink(target string) Option {
return func(t any) {
r, ok := t.(Linkable)
if !ok {
log.Fatalf("%T does not support WithSymlink", t)
}
r.SetSymlink(target)
}
}
// WithHardlink makes the resource a hard link pointing at target.
func WithHardlink(target string) Option {
return func(t any) {
r, ok := t.(Linkable)
if !ok {
log.Fatalf("%T does not support WithHardlink", t)
}
r.SetHardlink(target)
}
}
|