|
1 | 1 | package summary |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "fmt" |
| 5 | + "os" |
4 | 6 | "strings" |
5 | 7 |
|
6 | 8 | "github.com/go-task/task/v3/internal/logger" |
@@ -29,6 +31,9 @@ func PrintSpaceBetweenSummaries(l *logger.Logger, i int) { |
29 | 31 | func PrintTask(l *logger.Logger, t *ast.Task) { |
30 | 32 | printTaskName(l, t) |
31 | 33 | printTaskDescribingText(t, l) |
| 34 | + printTaskVars(l, t) |
| 35 | + printTaskEnv(l, t) |
| 36 | + printTaskRequires(l, t) |
32 | 37 | printTaskDependencies(l, t) |
33 | 38 | printTaskAliases(l, t) |
34 | 39 | printTaskCommands(l, t) |
@@ -118,3 +123,168 @@ func printTaskCommands(l *logger.Logger, t *ast.Task) { |
118 | 123 | } |
119 | 124 | } |
120 | 125 | } |
| 126 | + |
| 127 | +func printTaskVars(l *logger.Logger, t *ast.Task) { |
| 128 | + if t.Vars == nil || t.Vars.Len() == 0 { |
| 129 | + return |
| 130 | + } |
| 131 | + |
| 132 | + osEnvVars := getEnvVarNames() |
| 133 | + |
| 134 | + taskfileEnvVars := make(map[string]bool) |
| 135 | + if t.Env != nil { |
| 136 | + for key := range t.Env.All() { |
| 137 | + taskfileEnvVars[key] = true |
| 138 | + } |
| 139 | + } |
| 140 | + |
| 141 | + hasNonEnvVars := false |
| 142 | + for key := range t.Vars.All() { |
| 143 | + if !isEnvVar(key, osEnvVars) && !taskfileEnvVars[key] { |
| 144 | + hasNonEnvVars = true |
| 145 | + break |
| 146 | + } |
| 147 | + } |
| 148 | + |
| 149 | + if !hasNonEnvVars { |
| 150 | + return |
| 151 | + } |
| 152 | + |
| 153 | + l.Outf(logger.Default, "\n") |
| 154 | + l.Outf(logger.Default, "vars:\n") |
| 155 | + |
| 156 | + for key, value := range t.Vars.All() { |
| 157 | + // Only display variables that are not from OS environment or Taskfile env |
| 158 | + if !isEnvVar(key, osEnvVars) && !taskfileEnvVars[key] { |
| 159 | + formattedValue := formatVarValue(value) |
| 160 | + l.Outf(logger.Yellow, " %s: %s\n", key, formattedValue) |
| 161 | + } |
| 162 | + } |
| 163 | +} |
| 164 | + |
| 165 | +func printTaskEnv(l *logger.Logger, t *ast.Task) { |
| 166 | + if t.Env == nil || t.Env.Len() == 0 { |
| 167 | + return |
| 168 | + } |
| 169 | + |
| 170 | + envVars := getEnvVarNames() |
| 171 | + |
| 172 | + hasNonEnvVars := false |
| 173 | + for key := range t.Env.All() { |
| 174 | + if !isEnvVar(key, envVars) { |
| 175 | + hasNonEnvVars = true |
| 176 | + break |
| 177 | + } |
| 178 | + } |
| 179 | + |
| 180 | + if !hasNonEnvVars { |
| 181 | + return |
| 182 | + } |
| 183 | + |
| 184 | + l.Outf(logger.Default, "\n") |
| 185 | + l.Outf(logger.Default, "env:\n") |
| 186 | + |
| 187 | + for key, value := range t.Env.All() { |
| 188 | + // Only display variables that are not from OS environment |
| 189 | + if !isEnvVar(key, envVars) { |
| 190 | + formattedValue := formatVarValue(value) |
| 191 | + l.Outf(logger.Yellow, " %s: %s\n", key, formattedValue) |
| 192 | + } |
| 193 | + } |
| 194 | +} |
| 195 | + |
| 196 | +// formatVarValue formats a variable value based on its type. |
| 197 | +// Handles static values, shell commands (sh:), references (ref:), and maps. |
| 198 | +func formatVarValue(v ast.Var) string { |
| 199 | + // Shell command - check this first before Value |
| 200 | + // because dynamic vars may have both Sh and an empty Value |
| 201 | + if v.Sh != nil { |
| 202 | + return fmt.Sprintf("sh: %s", *v.Sh) |
| 203 | + } |
| 204 | + |
| 205 | + // Reference |
| 206 | + if v.Ref != "" { |
| 207 | + return fmt.Sprintf("ref: %s", v.Ref) |
| 208 | + } |
| 209 | + |
| 210 | + // Static value |
| 211 | + if v.Value != nil { |
| 212 | + // Check if it's a map or complex type |
| 213 | + if m, ok := v.Value.(map[string]any); ok { |
| 214 | + return formatMap(m, 4) |
| 215 | + } |
| 216 | + // Simple string value |
| 217 | + return fmt.Sprintf(`"%v"`, v.Value) |
| 218 | + } |
| 219 | + |
| 220 | + return `""` |
| 221 | +} |
| 222 | + |
| 223 | +// formatMap formats a map value with proper indentation for YAML. |
| 224 | +func formatMap(m map[string]any, indent int) string { |
| 225 | + if len(m) == 0 { |
| 226 | + return "{}" |
| 227 | + } |
| 228 | + |
| 229 | + var result strings.Builder |
| 230 | + result.WriteString("\n") |
| 231 | + spaces := strings.Repeat(" ", indent) |
| 232 | + |
| 233 | + for k, v := range m { |
| 234 | + result.WriteString(fmt.Sprintf("%s%s: %v\n", spaces, k, v)) |
| 235 | + } |
| 236 | + |
| 237 | + return result.String() |
| 238 | +} |
| 239 | + |
| 240 | +func printTaskRequires(l *logger.Logger, t *ast.Task) { |
| 241 | + if t.Requires == nil || len(t.Requires.Vars) == 0 { |
| 242 | + return |
| 243 | + } |
| 244 | + |
| 245 | + l.Outf(logger.Default, "\n") |
| 246 | + l.Outf(logger.Default, "requires:\n") |
| 247 | + l.Outf(logger.Default, " vars:\n") |
| 248 | + |
| 249 | + for _, v := range t.Requires.Vars { |
| 250 | + // If the variable has enum constraints, format accordingly |
| 251 | + if len(v.Enum) > 0 { |
| 252 | + l.Outf(logger.Yellow, " - %s:\n", v.Name) |
| 253 | + l.Outf(logger.Yellow, " enum:\n") |
| 254 | + for _, enumValue := range v.Enum { |
| 255 | + l.Outf(logger.Yellow, " - %s\n", enumValue) |
| 256 | + } |
| 257 | + } else { |
| 258 | + // Simple required variable |
| 259 | + l.Outf(logger.Yellow, " - %s\n", v.Name) |
| 260 | + } |
| 261 | + } |
| 262 | +} |
| 263 | + |
| 264 | +func getEnvVarNames() map[string]bool { |
| 265 | + envMap := make(map[string]bool) |
| 266 | + for _, e := range os.Environ() { |
| 267 | + parts := strings.SplitN(e, "=", 2) |
| 268 | + if len(parts) > 0 { |
| 269 | + envMap[parts[0]] = true |
| 270 | + } |
| 271 | + } |
| 272 | + return envMap |
| 273 | +} |
| 274 | + |
| 275 | +// isEnvVar checks if a variable is from OS environment or auto-generated by Task. |
| 276 | +func isEnvVar(key string, envVars map[string]bool) bool { |
| 277 | + // Filter out auto-generated Task variables |
| 278 | + if strings.HasPrefix(key, "TASK_") || |
| 279 | + strings.HasPrefix(key, "CLI_") || |
| 280 | + strings.HasPrefix(key, "ROOT_") || |
| 281 | + key == "TASK" || |
| 282 | + key == "TASKFILE" || |
| 283 | + key == "TASKFILE_DIR" || |
| 284 | + key == "USER_WORKING_DIR" || |
| 285 | + key == "ALIAS" || |
| 286 | + key == "MATCH" { |
| 287 | + return true |
| 288 | + } |
| 289 | + return envVars[key] |
| 290 | +} |
0 commit comments