/
spec.go
118 lines (99 loc) · 2.41 KB
/
spec.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
package list
import (
"strings"
"github.com/cybriq/proc/pkg/opts/config"
"github.com/cybriq/proc/pkg/opts/meta"
"github.com/cybriq/proc/pkg/opts/normalize"
"github.com/cybriq/proc/pkg/path"
"go.uber.org/atomic"
)
type Opt struct {
p path.Path
m meta.Metadata
v atomic.Value
x atomic.Value
h []Hook
}
var _ config.Option = &Opt{}
func (o *Opt) Path() (p path.Path) {
return o.p
}
func (o *Opt) SetPath(p path.Path) {
o.p = p
}
type Hook func(*Opt) error
func New(m meta.Data, h ...Hook) (o *Opt) {
o = &Opt{m: meta.New(m, meta.List), h: h}
_ = o.FromString(m.Default)
return
}
func (o *Opt) Meta() meta.Metadata { return o.m }
func (o *Opt) Type() meta.Type { return o.m.Typ }
func (o *Opt) ToOption() config.Option { return o }
func (o *Opt) RunHooks() (e error) {
for i := range o.h {
e = o.h[i](o)
if e != nil {
return
}
}
return
}
func (o *Opt) FromValue(v []string) *Opt {
o.v.Store(v)
return o
}
func (o *Opt) FromString(s string) (e error) {
s = strings.TrimSpace(s)
split := strings.Split(s, ",")
o.v.Store(split)
e = o.RunHooks()
return
}
func (o *Opt) String() (s string) {
return strings.Join(o.v.Load().([]string), ",")
}
func (o *Opt) Expanded() (s string) {
return o.String()
}
func (o *Opt) SetExpanded(s string) {
err := o.FromString(s)
log.E.Chk(err)
}
func (o *Opt) Value() (c config.Concrete) {
c = config.NewConcrete()
c.List = func() []string { return o.v.Load().([]string) }
return
}
// NormalizeNetworkAddress checks correctness of a network address
// specification, and adds a default path if needed, and enforces whether the
// port requires root permission and clamps it if not.
func NormalizeNetworkAddress(defaultPort string,
userOnly bool) func(*Opt) error {
return func(o *Opt) (e error) {
var a []string
a, e = normalize.Addresses(
o.v.Load().([]string), defaultPort, userOnly)
if !log.E.Chk(e) {
o.x.Store(a)
}
return
}
}
// NormalizeFilesystemPath cleans a directory specification, expands the ~ home
// folder shortcut, and if abs is set to true, returns the absolute path from
// filesystem root
func NormalizeFilesystemPath(abs bool, appName string) func(*Opt) error {
return func(o *Opt) (e error) {
strings := o.v.Load().([]string)
for i := range strings {
var cleaned string
cleaned, e = normalize.ResolvePath(strings[i], appName, abs)
if !log.E.Chk(e) {
strings[i] = cleaned
}
}
o.x.Store(strings)
return
}
}