summaryrefslogtreecommitdiff
path: root/api/options/option.go
blob: 22156a81517b86686f37c6a2955246f434a0dd47 (plain)
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
// Package option provides interface-based, resource-agnostic configuration
// options shared by the file, dir, and link resource packages.
package options

import (
	"log"
	"os"

	"codeberg.org/snonux/gonf/internal/resource"
)

// 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() }
	Dependable interface{ AddDependency(id string) }
	Linkable   interface {
		SetSymlink(target string)
		SetHardlink(target string)
	}
)

// DependsOn declares that the resource being configured must be applied only
// after every given resource has been applied. Each argument may be a single
// resource or a Multi; a Multi is expanded so the dependency is recorded for
// each of its members individually.
func DependsOn(deps ...resource.Dependency) Option {
	return func(t any) {
		r, ok := t.(Dependable)
		if !ok {
			log.Fatalf("%T does not support DependsOn", t)
		}
		for _, dep := range deps {
			for _, id := range dep.Dependencies() {
				r.AddDependency(id)
			}
		}
	}
}

// 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)
	}
}