|
4 | 4 | "fmt" |
5 | 5 | "os" |
6 | 6 | "path/filepath" |
| 7 | + "strings" |
7 | 8 |
|
8 | 9 | "github.com/BurntSushi/toml" |
9 | 10 | "github.com/pkg/errors" |
@@ -70,7 +71,25 @@ type RunImageConfig struct { |
70 | 71 |
|
71 | 72 | // BuildConfig build image configuration |
72 | 73 | type BuildConfig struct { |
73 | | - Image string `toml:"image"` |
| 74 | + Image string `toml:"image"` |
| 75 | + Env []BuildConfigEnv `toml:"env"` |
| 76 | +} |
| 77 | + |
| 78 | +type Suffix string |
| 79 | + |
| 80 | +const ( |
| 81 | + NONE Suffix = "" |
| 82 | + DEFAULT Suffix = "default" |
| 83 | + OVERRIDE Suffix = "override" |
| 84 | + APPEND Suffix = "append" |
| 85 | + PREPEND Suffix = "prepend" |
| 86 | +) |
| 87 | + |
| 88 | +type BuildConfigEnv struct { |
| 89 | + Name string `toml:"name"` |
| 90 | + Value string `toml:"value"` |
| 91 | + Suffix Suffix `toml:"suffix,omitempty"` |
| 92 | + Delim string `toml:"delim,omitempty"` |
74 | 93 | } |
75 | 94 |
|
76 | 95 | // ReadConfig reads a builder configuration from the file path provided and returns the |
@@ -162,3 +181,92 @@ func parseConfig(file *os.File) (Config, error) { |
162 | 181 |
|
163 | 182 | return builderConfig, nil |
164 | 183 | } |
| 184 | + |
| 185 | +func ParseBuildConfigEnv(env []BuildConfigEnv, path string) (envMap map[string]string, warnings []string, err error) { |
| 186 | + envMap = map[string]string{} |
| 187 | + var appendOrPrependWithoutDelim = 0 |
| 188 | + for _, v := range env { |
| 189 | + if name := v.Name; name == "" || len(name) == 0 { |
| 190 | + return nil, nil, errors.Wrapf(errors.Errorf("env name should not be empty"), "parse contents of '%s'", path) |
| 191 | + } |
| 192 | + if val := v.Value; val == "" || len(val) == 0 { |
| 193 | + warnings = append(warnings, fmt.Sprintf("empty value for key/name %s", style.Symbol(v.Name))) |
| 194 | + } |
| 195 | + suffixName, delimName, err := getBuildConfigEnvFileName(v) |
| 196 | + if err != nil { |
| 197 | + return envMap, warnings, err |
| 198 | + } |
| 199 | + if val, e := envMap[suffixName]; e { |
| 200 | + warnings = append(warnings, fmt.Sprintf(errors.Errorf("overriding env with name: %s and suffix: %s from %s to %s", style.Symbol(v.Name), style.Symbol(string(v.Suffix)), style.Symbol(val), style.Symbol(v.Value)).Error(), "parse contents of '%s'", path)) |
| 201 | + } |
| 202 | + if val, e := envMap[delimName]; e { |
| 203 | + warnings = append(warnings, fmt.Sprintf(errors.Errorf("overriding env with name: %s and delim: %s from %s to %s", style.Symbol(v.Name), style.Symbol(v.Delim), style.Symbol(val), style.Symbol(v.Value)).Error(), "parse contents of '%s'", path)) |
| 204 | + } |
| 205 | + if delim := v.Delim; (delim != "" || len(delim) != 0) && (delimName != "" || len(delimName) != 0) { |
| 206 | + envMap[delimName] = delim |
| 207 | + } |
| 208 | + envMap[suffixName] = v.Value |
| 209 | + } |
| 210 | + |
| 211 | + for k := range envMap { |
| 212 | + name, suffix, err := getFilePrefixSuffix(k) |
| 213 | + if err != nil { |
| 214 | + continue |
| 215 | + } |
| 216 | + if _, ok := envMap[name+".delim"]; (suffix == "append" || suffix == "prepend") && !ok { |
| 217 | + warnings = append(warnings, fmt.Sprintf(errors.Errorf("env with name/key %s with suffix %s must to have a %s value", style.Symbol(name), style.Symbol(suffix), style.Symbol("delim")).Error(), "parse contents of '%s'", path)) |
| 218 | + appendOrPrependWithoutDelim++ |
| 219 | + } |
| 220 | + } |
| 221 | + if appendOrPrependWithoutDelim > 0 { |
| 222 | + return envMap, warnings, errors.Errorf("error parsing [[build.env]] in file '%s'", path) |
| 223 | + } |
| 224 | + return envMap, warnings, err |
| 225 | +} |
| 226 | + |
| 227 | +func getBuildConfigEnvFileName(env BuildConfigEnv) (suffixName, delimName string, err error) { |
| 228 | + suffix, err := getActionType(env.Suffix) |
| 229 | + if err != nil { |
| 230 | + return suffixName, delimName, err |
| 231 | + } |
| 232 | + if suffix == "" { |
| 233 | + suffixName = env.Name |
| 234 | + } else { |
| 235 | + suffixName = env.Name + suffix |
| 236 | + } |
| 237 | + if delim := env.Delim; delim != "" || len(delim) != 0 { |
| 238 | + delimName = env.Name + ".delim" |
| 239 | + } |
| 240 | + return suffixName, delimName, err |
| 241 | +} |
| 242 | + |
| 243 | +func getActionType(suffix Suffix) (suffixString string, err error) { |
| 244 | + const delim = "." |
| 245 | + switch suffix { |
| 246 | + case NONE: |
| 247 | + return "", nil |
| 248 | + case DEFAULT: |
| 249 | + return delim + string(DEFAULT), nil |
| 250 | + case OVERRIDE: |
| 251 | + return delim + string(OVERRIDE), nil |
| 252 | + case APPEND: |
| 253 | + return delim + string(APPEND), nil |
| 254 | + case PREPEND: |
| 255 | + return delim + string(PREPEND), nil |
| 256 | + default: |
| 257 | + return suffixString, errors.Errorf("unknown action type %s", style.Symbol(string(suffix))) |
| 258 | + } |
| 259 | +} |
| 260 | + |
| 261 | +func getFilePrefixSuffix(filename string) (prefix, suffix string, err error) { |
| 262 | + val := strings.Split(filename, ".") |
| 263 | + if len(val) <= 1 { |
| 264 | + return val[0], suffix, errors.Errorf("Suffix might be null") |
| 265 | + } |
| 266 | + if len(val) == 2 { |
| 267 | + suffix = val[1] |
| 268 | + } else { |
| 269 | + suffix = strings.Join(val[1:], ".") |
| 270 | + } |
| 271 | + return val[0], suffix, err |
| 272 | +} |
0 commit comments