|
1 | 1 | package config |
2 | 2 |
|
3 | 3 | import ( |
4 | | - "fmt" |
5 | 4 | "os" |
6 | 5 | "regexp" |
7 | 6 | "strings" |
| 7 | + |
| 8 | + "github.com/azuyamat/pace/internal/logger" |
8 | 9 | ) |
9 | 10 |
|
10 | 11 | var varPattern = regexp.MustCompile(`\$\{([^}]+)\}`) |
11 | 12 |
|
12 | 13 | type Resolver struct { |
13 | | - config *Config |
| 14 | + config *Config |
| 15 | + unresolvedVars map[string]bool |
14 | 16 | } |
15 | 17 |
|
16 | 18 | func NewResolver(config *Config) *Resolver { |
17 | | - return &Resolver{config: config} |
| 19 | + return &Resolver{ |
| 20 | + config: config, |
| 21 | + unresolvedVars: make(map[string]bool), |
| 22 | + } |
18 | 23 | } |
19 | 24 |
|
20 | | -// ResolveString resolves variable references in a string |
21 | 25 | func (r *Resolver) ResolveString(input string) string { |
22 | 26 | return varPattern.ReplaceAllStringFunc(input, func(match string) string { |
23 | | - // Extract variable name from ${VAR} |
24 | 27 | varName := match[2 : len(match)-1] |
25 | 28 |
|
26 | | - // Check in constants first |
27 | 29 | if value, exists := r.config.Constants[varName]; exists { |
28 | 30 | return value |
29 | 31 | } |
30 | 32 |
|
31 | | - // Check in globals |
32 | 33 | if value, exists := r.config.Globals[varName]; exists { |
33 | 34 | return value |
34 | 35 | } |
35 | 36 |
|
36 | | - // Check environment variables |
37 | 37 | if value := os.Getenv(varName); value != "" { |
38 | 38 | return value |
39 | 39 | } |
40 | 40 |
|
41 | | - // Return original if not found |
| 41 | + if !r.unresolvedVars[varName] { |
| 42 | + logger.Warning("Unresolved variable: ${%s}", varName) |
| 43 | + r.unresolvedVars[varName] = true |
| 44 | + } |
| 45 | + |
42 | 46 | return match |
43 | 47 | }) |
44 | 48 | } |
45 | 49 |
|
46 | | -// ResolveStringSlice resolves variables in a slice of strings |
47 | 50 | func (r *Resolver) ResolveStringSlice(slice []string) []string { |
48 | 51 | result := make([]string, len(slice)) |
49 | 52 | for i, s := range slice { |
@@ -111,40 +114,3 @@ func ExpandEnvVars(s string) string { |
111 | 114 |
|
112 | 115 | return result.String() |
113 | 116 | } |
114 | | - |
115 | | -// EvaluateCondition evaluates simple conditional expressions |
116 | | -func EvaluateCondition(condition string) (bool, error) { |
117 | | - condition = strings.TrimSpace(condition) |
118 | | - |
119 | | - // Handle OS checks: OS == "windows" or OS == "linux" |
120 | | - if strings.Contains(condition, "OS") { |
121 | | - osPattern := regexp.MustCompile(`OS\s*==\s*"([^"]+)"`) |
122 | | - matches := osPattern.FindStringSubmatch(condition) |
123 | | - if len(matches) > 1 { |
124 | | - targetOS := strings.ToLower(matches[1]) |
125 | | - currentOS := strings.ToLower(os.Getenv("GOOS")) |
126 | | - if currentOS == "" { |
127 | | - currentOS = "windows" // Default for this system |
128 | | - } |
129 | | - return currentOS == targetOS, nil |
130 | | - } |
131 | | - } |
132 | | - |
133 | | - // Handle environment variable checks: ENV_VAR == "value" |
134 | | - envPattern := regexp.MustCompile(`([A-Z_][A-Z0-9_]*)\s*==\s*"([^"]+)"`) |
135 | | - matches := envPattern.FindStringSubmatch(condition) |
136 | | - if len(matches) > 2 { |
137 | | - envVar := matches[1] |
138 | | - expectedValue := matches[2] |
139 | | - actualValue := os.Getenv(envVar) |
140 | | - return actualValue == expectedValue, nil |
141 | | - } |
142 | | - |
143 | | - // Handle boolean environment variables: ENV_VAR |
144 | | - if matched, _ := regexp.MatchString(`^[A-Z_][A-Z0-9_]*$`, condition); matched { |
145 | | - value := os.Getenv(condition) |
146 | | - return value != "" && value != "0" && strings.ToLower(value) != "false", nil |
147 | | - } |
148 | | - |
149 | | - return false, fmt.Errorf("unable to evaluate condition: %s", condition) |
150 | | -} |
0 commit comments