mirror of
https://github.com/go-task/task.git
synced 2025-12-29 00:24:50 +01:00
feat: auto-detect color output in CI environments (#2569)
This commit is contained in:
@@ -54,6 +54,11 @@
|
|||||||
customize the cache directory for Remote Taskfiles (#2572 by @vmaerten).
|
customize the cache directory for Remote Taskfiles (#2572 by @vmaerten).
|
||||||
- Zsh completion now supports zstyle verbose option to show or hide task
|
- Zsh completion now supports zstyle verbose option to show or hide task
|
||||||
descriptions (#2571 by @vmaerten).
|
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
|
## v3.45.5 - 2025-11-11
|
||||||
|
|
||||||
|
|||||||
@@ -5,8 +5,10 @@ import (
|
|||||||
"log"
|
"log"
|
||||||
"os"
|
"os"
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/fatih/color"
|
||||||
"github.com/spf13/pflag"
|
"github.com/spf13/pflag"
|
||||||
|
|
||||||
"github.com/go-task/task/v3"
|
"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.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.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.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.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.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.")
|
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.StringVar(&RemoteCacheDir, "remote-cache-dir", getConfig(config, func() *string { return config.Remote.CacheDir }, env.GetTaskEnv("REMOTE_DIR")), "Directory to cache remote Taskfiles.")
|
||||||
}
|
}
|
||||||
pflag.Parse()
|
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 {
|
func Validate() error {
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ package logger
|
|||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
"slices"
|
"slices"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -96,10 +95,6 @@ func BrightRed() PrintFunc {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func envColor(name string, defaultColor color.Attribute) []color.Attribute {
|
func envColor(name string, defaultColor color.Attribute) []color.Attribute {
|
||||||
if os.Getenv("FORCE_COLOR") != "" {
|
|
||||||
color.NoColor = false
|
|
||||||
}
|
|
||||||
|
|
||||||
// Fetch the environment variable
|
// Fetch the environment variable
|
||||||
override := env.GetTaskEnv(name)
|
override := env.GetTaskEnv(name)
|
||||||
|
|
||||||
|
|||||||
@@ -12,6 +12,7 @@ import (
|
|||||||
type TaskRC struct {
|
type TaskRC struct {
|
||||||
Version *semver.Version `yaml:"version"`
|
Version *semver.Version `yaml:"version"`
|
||||||
Verbose *bool `yaml:"verbose"`
|
Verbose *bool `yaml:"verbose"`
|
||||||
|
Color *bool `yaml:"color"`
|
||||||
DisableFuzzy *bool `yaml:"disable-fuzzy"`
|
DisableFuzzy *bool `yaml:"disable-fuzzy"`
|
||||||
Concurrency *int `yaml:"concurrency"`
|
Concurrency *int `yaml:"concurrency"`
|
||||||
Remote Remote `yaml:"remote"`
|
Remote Remote `yaml:"remote"`
|
||||||
@@ -55,6 +56,7 @@ func (t *TaskRC) Merge(other *TaskRC) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
t.Verbose = cmp.Or(other.Verbose, t.Verbose)
|
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.DisableFuzzy = cmp.Or(other.DisableFuzzy, t.DisableFuzzy)
|
||||||
t.Concurrency = cmp.Or(other.Concurrency, t.Concurrency)
|
t.Concurrency = cmp.Or(other.Concurrency, t.Concurrency)
|
||||||
t.Failfast = cmp.Or(other.Failfast, t.Failfast)
|
t.Failfast = cmp.Or(other.Failfast, t.Failfast)
|
||||||
|
|||||||
@@ -91,6 +91,17 @@ experiments:
|
|||||||
verbose: true
|
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`
|
### `disable-fuzzy`
|
||||||
|
|
||||||
- **Type**: `boolean`
|
- **Type**: `boolean`
|
||||||
@@ -131,6 +142,7 @@ Here's a complete example of a `.taskrc.yml` file with all available options:
|
|||||||
```yaml
|
```yaml
|
||||||
# Global settings
|
# Global settings
|
||||||
verbose: true
|
verbose: true
|
||||||
|
color: true
|
||||||
disable-fuzzy: false
|
disable-fuzzy: false
|
||||||
concurrency: 2
|
concurrency: 2
|
||||||
|
|
||||||
|
|||||||
@@ -57,6 +57,10 @@
|
|||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Enable verbose output"
|
"description": "Enable verbose output"
|
||||||
},
|
},
|
||||||
|
"color": {
|
||||||
|
"type": "boolean",
|
||||||
|
"description": "Enable colored output"
|
||||||
|
},
|
||||||
"disable-fuzzy": {
|
"disable-fuzzy": {
|
||||||
"type": "boolean",
|
"type": "boolean",
|
||||||
"description": "Disable fuzzy matching for task names"
|
"description": "Disable fuzzy matching for task names"
|
||||||
|
|||||||
Reference in New Issue
Block a user