forked from hyperledger/fabric-sdk-go
-
Notifications
You must be signed in to change notification settings - Fork 2
/
subst.go
81 lines (65 loc) · 1.98 KB
/
subst.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
/*
Copyright SecureKey Technologies Inc. All Rights Reserved.
SPDX-License-Identifier: Apache-2.0
*/
package pathvar
import (
"bytes"
"go/build"
"os"
"path/filepath"
"strings"
"github.com/hyperledger/fabric-sdk-go/test/metadata"
)
// goPath returns the current GOPATH. If the system
// has multiple GOPATHs then the first is used.
func goPath() string {
gpDefault := build.Default.GOPATH
gps := filepath.SplitList(gpDefault)
return gps[0]
}
// Subst replaces instances of '${VARNAME}' (eg ${GOPATH}) with the variable.
// Variables names that are not set by the SDK are replaced with the environment variable.
func Subst(path string) string {
const (
sepPrefix = "${"
sepSuffix = "}"
)
splits := strings.Split(path, sepPrefix)
var buffer bytes.Buffer
// first split precedes the first sepPrefix so should always be written
buffer.WriteString(splits[0]) // nolint: gas
for _, s := range splits[1:] {
subst, rest := substVar(s, sepPrefix, sepSuffix)
buffer.WriteString(subst) // nolint: gas
buffer.WriteString(rest) // nolint: gas
}
return buffer.String()
}
// substVar searches for an instance of a variables name and replaces them with their value.
// The first return value is substituted portion of the string or noMatch if no replacement occurred.
// The second return value is the unconsumed portion of s.
func substVar(s string, noMatch string, sep string) (string, string) {
endPos := strings.Index(s, sep)
if endPos == -1 {
return noMatch, s
}
v, ok := lookupVar(s[:endPos])
if !ok {
return noMatch, s
}
return v, s[endPos+1:]
}
// lookupVar returns the value of the variable.
// The local variable table is consulted first, followed by environment variables.
// Returns false if the variable doesn't exist.
func lookupVar(v string) (string, bool) {
// TODO: optimize if the number of variable names grows
switch v {
case "GOPATH":
return goPath(), true
case "CRYPTOCONFIG_FIXTURES_PATH":
return metadata.CryptoConfigPath, true
}
return os.LookupEnv(v)
}