feat: auto-detect color output in CI environments (#2569)

This commit is contained in:
Valentin Maerten
2025-12-18 08:40:37 +01:00
committed by GitHub
parent b710259bfa
commit 6660afc8d2
6 changed files with 49 additions and 6 deletions

View File

@@ -54,6 +54,11 @@
customize the cache directory for Remote Taskfiles (#2572 by @vmaerten).
- Zsh completion now supports zstyle verbose option to show or hide task
descriptions (#2571 by @vmaerten).
- Task now automatically enables colored output in CI environments (GitHub
Actions, GitLab CI, etc.) without requiring FORCE_COLOR=1 (#2569 by
@vmaerten).
- Added color taskrc option to explicitly enable or disable colored output
globally (#2569 by @vmaerten).
## v3.45.5 - 2025-11-11

View File

@@ -5,8 +5,10 @@ import (
"log"
"os"
"path/filepath"
"strconv"
"time"
"github.com/fatih/color"
"github.com/spf13/pflag"
"github.com/go-task/task/v3"
@@ -140,7 +142,7 @@ func init() {
pflag.StringVar(&Output.Group.Begin, "output-group-begin", "", "Message template to print before a task's grouped output.")
pflag.StringVar(&Output.Group.End, "output-group-end", "", "Message template to print after a task's grouped output.")
pflag.BoolVar(&Output.Group.ErrorOnly, "output-group-error-only", false, "Swallow output from successful tasks.")
pflag.BoolVarP(&Color, "color", "c", true, "Colored output. Enabled by default. Set flag to false or use NO_COLOR=1 to disable.")
pflag.BoolVarP(&Color, "color", "c", getConfig(config, func() *bool { return config.Color }, true), "Colored output. Enabled by default. Set flag to false or use NO_COLOR=1 to disable.")
pflag.IntVarP(&Concurrency, "concurrency", "C", getConfig(config, func() *int { return config.Concurrency }, 0), "Limit number of tasks to run concurrently.")
pflag.DurationVarP(&Interval, "interval", "I", 0, "Interval to watch for changes.")
pflag.BoolVarP(&Failfast, "failfast", "F", getConfig(config, func() *bool { return &config.Failfast }, false), "When running tasks in parallel, stop all tasks if one fails.")
@@ -166,6 +168,29 @@ func init() {
pflag.StringVar(&RemoteCacheDir, "remote-cache-dir", getConfig(config, func() *string { return config.Remote.CacheDir }, env.GetTaskEnv("REMOTE_DIR")), "Directory to cache remote Taskfiles.")
}
pflag.Parse()
// Auto-detect color based on environment when not explicitly configured
// Priority: CLI flag > taskrc config > NO_COLOR > FORCE_COLOR/CI > default
colorExplicitlySet := pflag.Lookup("color").Changed || (config != nil && config.Color != nil)
if !colorExplicitlySet {
if os.Getenv("NO_COLOR") != "" {
Color = false
color.NoColor = true
} else if os.Getenv("FORCE_COLOR") != "" || isCI() {
Color = true
color.NoColor = false // Force colors even without TTY
}
// Otherwise, let fatih/color auto-detect TTY
} else {
// Explicit config: sync with fatih/color
color.NoColor = !Color
}
}
// isCI returns true if running in a CI environment
func isCI() bool {
ci, _ := strconv.ParseBool(os.Getenv("CI"))
return ci
}
func Validate() error {

View File

@@ -3,7 +3,6 @@ package logger
import (
"bufio"
"io"
"os"
"slices"
"strconv"
"strings"
@@ -96,10 +95,6 @@ func BrightRed() PrintFunc {
}
func envColor(name string, defaultColor color.Attribute) []color.Attribute {
if os.Getenv("FORCE_COLOR") != "" {
color.NoColor = false
}
// Fetch the environment variable
override := env.GetTaskEnv(name)

View File

@@ -12,6 +12,7 @@ import (
type TaskRC struct {
Version *semver.Version `yaml:"version"`
Verbose *bool `yaml:"verbose"`
Color *bool `yaml:"color"`
DisableFuzzy *bool `yaml:"disable-fuzzy"`
Concurrency *int `yaml:"concurrency"`
Remote Remote `yaml:"remote"`
@@ -55,6 +56,7 @@ func (t *TaskRC) Merge(other *TaskRC) {
}
t.Verbose = cmp.Or(other.Verbose, t.Verbose)
t.Color = cmp.Or(other.Color, t.Color)
t.DisableFuzzy = cmp.Or(other.DisableFuzzy, t.DisableFuzzy)
t.Concurrency = cmp.Or(other.Concurrency, t.Concurrency)
t.Failfast = cmp.Or(other.Failfast, t.Failfast)

View File

@@ -91,6 +91,17 @@ experiments:
verbose: true
```
### `color`
- **Type**: `boolean`
- **Default**: `true`
- **Description**: Enable colored output. Colors are automatically enabled in CI environments (`CI=true`).
- **CLI equivalent**: [`-c, --color`](./cli.md#-c---color)
```yaml
color: false
```
### `disable-fuzzy`
- **Type**: `boolean`
@@ -131,6 +142,7 @@ Here's a complete example of a `.taskrc.yml` file with all available options:
```yaml
# Global settings
verbose: true
color: true
disable-fuzzy: false
concurrency: 2

View File

@@ -57,6 +57,10 @@
"type": "boolean",
"description": "Enable verbose output"
},
"color": {
"type": "boolean",
"description": "Enable colored output"
},
"disable-fuzzy": {
"type": "boolean",
"description": "Disable fuzzy matching for task names"