replaceEnvVars replaces all occurrences of environment variables. It mutates the underlying array and returns the updated slice.
(input []byte)
| 67 | // replaceEnvVars replaces all occurrences of environment variables. |
| 68 | // It mutates the underlying array and returns the updated slice. |
| 69 | func replaceEnvVars(input []byte) []byte { |
| 70 | var offset int |
| 71 | for { |
| 72 | begin := bytes.Index(input[offset:], spanOpen) |
| 73 | if begin < 0 { |
| 74 | break |
| 75 | } |
| 76 | begin += offset // make beginning relative to input, not offset |
| 77 | end := bytes.Index(input[begin+len(spanOpen):], spanClose) |
| 78 | if end < 0 { |
| 79 | break |
| 80 | } |
| 81 | end += begin + len(spanOpen) // make end relative to input, not begin |
| 82 | |
| 83 | // get the name; if there is no name, skip it |
| 84 | envString := input[begin+len(spanOpen) : end] |
| 85 | if len(envString) == 0 { |
| 86 | offset = end + len(spanClose) |
| 87 | continue |
| 88 | } |
| 89 | |
| 90 | // split the string into a key and an optional default |
| 91 | envParts := strings.SplitN(string(envString), envVarDefaultDelimiter, 2) |
| 92 | |
| 93 | // do a lookup for the env var, replace with the default if not found |
| 94 | envVarValue, found := os.LookupEnv(envParts[0]) |
| 95 | if !found && len(envParts) == 2 { |
| 96 | envVarValue = envParts[1] |
| 97 | } |
| 98 | |
| 99 | // get the value of the environment variable |
| 100 | // note that this causes one-level deep chaining |
| 101 | envVarBytes := []byte(envVarValue) |
| 102 | |
| 103 | // splice in the value |
| 104 | input = append(input[:begin], |
| 105 | append(envVarBytes, input[end+len(spanClose):]...)...) |
| 106 | |
| 107 | // continue at the end of the replacement |
| 108 | offset = begin + len(envVarBytes) |
| 109 | } |
| 110 | return input |
| 111 | } |
| 112 | |
| 113 | type parser struct { |
| 114 | *Dispenser |
no outgoing calls