-
Notifications
You must be signed in to change notification settings - Fork 37
/
assets.go
92 lines (82 loc) · 2.52 KB
/
assets.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
package kflags
import (
"github.com/enfabrica/enkit/lib/logger"
"path/filepath"
"strings"
)
type asset struct {
// Original name of the asset.
name string
// Byte content of the asset.
data []byte
}
type AssetAugmenter struct {
log logger.Logger
index map[string]asset
forns string
}
// NewAssetAugmenter creates a new AssetAugmenter.
//
// An asset-resolver looks up configuration flags in a built in dict where the key is
// the name of a file, and the value is what should be passed to the flag.
// Extensions of the key are ignored.
//
// For example, let's say you have a dict containing:
//
// "/etc/astore/astore-server.flag.txt": "127.0.0.1"
//
// Now let's say you have a binary that takes a --astore-server or -astore-server flag.
//
// When invoked, the returned AssetAugmenter will set the default value of --astore-server to 127.0.0.1.
//
// This is extremely powerful when combined to a library to embed files at build time,
// like the go_embed_data target of bazel.
func NewAssetAugmenter(log logger.Logger, forns string, assets map[string][]byte) *AssetAugmenter {
index := map[string]asset{}
for name, data := range assets {
original := name
for {
index[name] = asset{
name: original,
data: data,
}
ext := filepath.Ext(name)
if ext == "" {
break
}
name = strings.TrimSuffix(name, ext)
}
}
return &AssetAugmenter{
log: log,
index: index,
forns: forns,
}
}
// VisitCommand implements the VisitCommand interface of Augmenter. In AssetAugmenter, it is a noop.
func (ar *AssetAugmenter) VisitCommand(ns string, command Command) (bool, error) {
return false, nil
}
// VisitFlag implements the VisitFlag interface of Augmenter.
//
// If the namespace matches the one configured with the constructor, VisitFlag will look
// for an asset named after the flag name.
//
// If one is found, the content of the flag is set to that of the asset.
func (ar *AssetAugmenter) VisitFlag(reqns string, fl Flag) (bool, error) {
if reqns != ar.forns {
ar.log.Debugf("%s flag %s: no asset assigned - namespace %s != %s", ar.forns, fl.Name(), reqns, ar.forns)
return false, nil
}
asset, found := ar.index[fl.Name()]
if !found {
ar.log.Debugf("%s flag %s: not found among assets - not in index", ar.forns, fl.Name())
return false, nil
}
ar.log.Infof("%s flag %s: set from static assets (%d bytes)", ar.forns, fl.Name(), len(asset.data))
return true, fl.SetContent(asset.name, asset.data)
}
// Done implements the Done interface of Augmenter.
func (ar *AssetAugmenter) Done() error {
return nil
}