mirror of
https://github.com/go-task/task.git
synced 2025-12-16 19:57:43 +01:00
refactor(interactive): move interactive setting to taskrc
This commit is contained in:
14
executor.go
14
executor.go
@@ -44,6 +44,7 @@ type (
|
||||
AssumeYes bool
|
||||
AssumeTerm bool // Used for testing
|
||||
NoTTY bool
|
||||
Interactive bool
|
||||
Dry bool
|
||||
Summary bool
|
||||
Parallel bool
|
||||
@@ -367,6 +368,19 @@ func (o *noTTYOption) ApplyToExecutor(e *Executor) {
|
||||
e.NoTTY = o.noTTY
|
||||
}
|
||||
|
||||
// WithInteractive tells the [Executor] to prompt for missing required variables.
|
||||
func WithInteractive(interactive bool) ExecutorOption {
|
||||
return &interactiveOption{interactive}
|
||||
}
|
||||
|
||||
type interactiveOption struct {
|
||||
interactive bool
|
||||
}
|
||||
|
||||
func (o *interactiveOption) ApplyToExecutor(e *Executor) {
|
||||
e.Interactive = o.interactive
|
||||
}
|
||||
|
||||
// WithDry tells the [Executor] to output the commands that would be run without
|
||||
// actually running them.
|
||||
func WithDry(dry bool) ExecutorOption {
|
||||
|
||||
@@ -80,6 +80,7 @@ var (
|
||||
Timeout time.Duration
|
||||
CacheExpiryDuration time.Duration
|
||||
NoTTY bool
|
||||
Interactive bool
|
||||
)
|
||||
|
||||
func init() {
|
||||
@@ -145,6 +146,7 @@ func init() {
|
||||
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(&Global, "global", "g", false, "Runs global Taskfile, from $HOME/{T,t}askfile.{yml,yaml}.")
|
||||
Interactive = getConfig(config, func() *bool { return config.Interactive }, false)
|
||||
pflag.BoolVar(&Experiments, "experiments", false, "Lists all the available experiments and whether or not they are enabled.")
|
||||
|
||||
// Gentle force experiment will override the force flag and add a new force-all flag
|
||||
@@ -255,6 +257,7 @@ func (o *flagsOption) ApplyToExecutor(e *task.Executor) {
|
||||
task.WithDisableFuzzy(DisableFuzzy),
|
||||
task.WithAssumeYes(AssumeYes),
|
||||
task.WithNoTTY(NoTTY),
|
||||
task.WithInteractive(Interactive),
|
||||
task.WithDry(Dry || Status),
|
||||
task.WithSummary(Summary),
|
||||
task.WithParallel(Parallel),
|
||||
|
||||
12
requires.go
12
requires.go
@@ -9,7 +9,7 @@ import (
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
)
|
||||
|
||||
// promptForInteractiveVars prompts the user for any missing interactive variables
|
||||
// promptForInteractiveVars prompts the user for any missing required variables
|
||||
// and injects them into the call's Vars. It returns true if any variables were
|
||||
// prompted for (meaning the task needs to be recompiled).
|
||||
func (e *Executor) promptForInteractiveVars(t *ast.Task, call *Call) (bool, error) {
|
||||
@@ -17,6 +17,11 @@ func (e *Executor) promptForInteractiveVars(t *ast.Task, call *Call) (bool, erro
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Don't prompt if interactive mode is disabled
|
||||
if !e.Interactive {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Don't prompt if NoTTY is set or we're not in a terminal
|
||||
if e.NoTTY || (!e.AssumeTerm && !term.IsTerminal()) {
|
||||
return false, nil
|
||||
@@ -26,11 +31,6 @@ func (e *Executor) promptForInteractiveVars(t *ast.Task, call *Call) (bool, erro
|
||||
var prompted bool
|
||||
|
||||
for _, requiredVar := range t.Requires.Vars {
|
||||
// Skip non-interactive vars
|
||||
if !requiredVar.Interactive {
|
||||
continue
|
||||
}
|
||||
|
||||
// Skip if already set
|
||||
if _, ok := t.Vars.Get(requiredVar.Name); ok {
|
||||
continue
|
||||
|
||||
@@ -25,7 +25,6 @@ func (r *Requires) DeepCopy() *Requires {
|
||||
type VarsWithValidation struct {
|
||||
Name string
|
||||
Enum []string
|
||||
Interactive bool
|
||||
}
|
||||
|
||||
func (v *VarsWithValidation) DeepCopy() *VarsWithValidation {
|
||||
@@ -35,7 +34,6 @@ func (v *VarsWithValidation) DeepCopy() *VarsWithValidation {
|
||||
return &VarsWithValidation{
|
||||
Name: v.Name,
|
||||
Enum: v.Enum,
|
||||
Interactive: v.Interactive,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -56,14 +54,12 @@ func (v *VarsWithValidation) UnmarshalYAML(node *yaml.Node) error {
|
||||
var vv struct {
|
||||
Name string
|
||||
Enum []string
|
||||
Interactive bool
|
||||
}
|
||||
if err := node.Decode(&vv); err != nil {
|
||||
return errors.NewTaskfileDecodeError(err, node)
|
||||
}
|
||||
v.Name = vv.Name
|
||||
v.Enum = vv.Enum
|
||||
v.Interactive = vv.Interactive
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -14,6 +14,7 @@ type TaskRC struct {
|
||||
Verbose *bool `yaml:"verbose"`
|
||||
DisableFuzzy *bool `yaml:"disable-fuzzy"`
|
||||
Concurrency *int `yaml:"concurrency"`
|
||||
Interactive *bool `yaml:"interactive"`
|
||||
Remote Remote `yaml:"remote"`
|
||||
Failfast bool `yaml:"failfast"`
|
||||
Experiments map[string]int `yaml:"experiments"`
|
||||
@@ -56,5 +57,6 @@ func (t *TaskRC) Merge(other *TaskRC) {
|
||||
t.Verbose = cmp.Or(other.Verbose, t.Verbose)
|
||||
t.DisableFuzzy = cmp.Or(other.DisableFuzzy, t.DisableFuzzy)
|
||||
t.Concurrency = cmp.Or(other.Concurrency, t.Concurrency)
|
||||
t.Interactive = cmp.Or(other.Interactive, t.Interactive)
|
||||
t.Failfast = cmp.Or(other.Failfast, t.Failfast)
|
||||
}
|
||||
|
||||
20
testdata/interactive_vars/Taskfile.yml
vendored
20
testdata/interactive_vars/Taskfile.yml
vendored
@@ -4,8 +4,7 @@ tasks:
|
||||
simple:
|
||||
requires:
|
||||
vars:
|
||||
- name: MY_VAR
|
||||
interactive: true
|
||||
- MY_VAR
|
||||
cmds:
|
||||
- echo "{{.MY_VAR}}"
|
||||
|
||||
@@ -13,23 +12,14 @@ tasks:
|
||||
requires:
|
||||
vars:
|
||||
- name: ENV
|
||||
interactive: true
|
||||
enum: [dev, staging, prod]
|
||||
cmds:
|
||||
- echo "{{.ENV}}"
|
||||
|
||||
non-interactive:
|
||||
multiple:
|
||||
requires:
|
||||
vars:
|
||||
- NON_INTERACTIVE_VAR
|
||||
- VAR1
|
||||
- VAR2
|
||||
cmds:
|
||||
- echo "{{.NON_INTERACTIVE_VAR}}"
|
||||
|
||||
mixed:
|
||||
requires:
|
||||
vars:
|
||||
- name: INTERACTIVE_VAR
|
||||
interactive: true
|
||||
- NON_INTERACTIVE_VAR
|
||||
cmds:
|
||||
- echo "{{.INTERACTIVE_VAR}} {{.NON_INTERACTIVE_VAR}}"
|
||||
- echo "{{.VAR1}} {{.VAR2}}"
|
||||
|
||||
@@ -1129,14 +1129,20 @@ This is supported only for string variables.
|
||||
|
||||
### Prompting for missing variables interactively
|
||||
|
||||
If you want Task to prompt users for missing variables instead of failing, you
|
||||
can mark a variable as `interactive: true`. When a variable is missing and has
|
||||
this flag, Task will display an interactive prompt to collect the value.
|
||||
|
||||
For variables with an `enum`, a selection menu is shown. For variables without
|
||||
an enum, a text input is displayed.
|
||||
If you want Task to prompt users for missing required variables instead of
|
||||
failing, you can enable interactive mode in your `.taskrc.yml`:
|
||||
|
||||
```yaml
|
||||
# ~/.taskrc.yml
|
||||
interactive: true
|
||||
```
|
||||
|
||||
When enabled, Task will display an interactive prompt for any missing required
|
||||
variable. For variables with an `enum`, a selection menu is shown. For variables
|
||||
without an enum, a text input is displayed.
|
||||
|
||||
```yaml
|
||||
# Taskfile.yml
|
||||
version: '3'
|
||||
|
||||
tasks:
|
||||
@@ -1144,10 +1150,8 @@ tasks:
|
||||
requires:
|
||||
vars:
|
||||
- name: ENVIRONMENT
|
||||
interactive: true
|
||||
enum: [dev, staging, prod]
|
||||
- name: VERSION
|
||||
interactive: true
|
||||
- VERSION
|
||||
cmds:
|
||||
- echo "Deploying {{.VERSION}} to {{.ENVIRONMENT}}"
|
||||
```
|
||||
@@ -1158,6 +1162,8 @@ $ task deploy
|
||||
❯ dev
|
||||
staging
|
||||
prod
|
||||
? Enter value for VERSION: 1.0.0
|
||||
Deploying 1.0.0 to prod
|
||||
```
|
||||
|
||||
If the variable is already set (via CLI, environment, or Taskfile), no prompt
|
||||
@@ -1168,11 +1174,14 @@ $ task deploy ENVIRONMENT=prod VERSION=1.0.0
|
||||
Deploying 1.0.0 to prod
|
||||
```
|
||||
|
||||
::: warning
|
||||
::: info
|
||||
|
||||
Interactive prompts require a TTY. In non-interactive environments like CI
|
||||
pipelines, use `--no-tty` to disable prompts (missing variables will cause an
|
||||
error as usual), or provide all required variables explicitly.
|
||||
Interactive prompts require a TTY (terminal). Task automatically detects
|
||||
non-interactive environments like GitHub Actions, GitLab CI, and other CI
|
||||
pipelines where stdin/stdout are not connected to a terminal. In these cases,
|
||||
prompts are skipped and missing variables will cause an error as usual.
|
||||
|
||||
You can also explicitly disable prompts with `--no-tty` if needed.
|
||||
|
||||
:::
|
||||
|
||||
|
||||
@@ -305,7 +305,11 @@ task deploy --yes
|
||||
|
||||
Disable interactive prompts for missing variables. When a variable is marked
|
||||
with `interactive: true` in the Taskfile and is not provided, Task will error
|
||||
instead of prompting for input. Useful in CI environments.
|
||||
instead of prompting for input.
|
||||
|
||||
Note: Task automatically detects non-TTY environments (like CI pipelines) and
|
||||
disables prompts. This flag is useful when you want to explicitly disable
|
||||
prompts even when a TTY is available.
|
||||
|
||||
```bash
|
||||
task deploy --no-tty
|
||||
|
||||
@@ -124,6 +124,20 @@ concurrency: 4
|
||||
failfast: true
|
||||
```
|
||||
|
||||
### `interactive`
|
||||
|
||||
- **Type**: `boolean`
|
||||
- **Default**: `false`
|
||||
- **Description**: Prompt for missing required variables instead of failing.
|
||||
When enabled, Task will display an interactive prompt for any missing required
|
||||
variable. Requires a TTY. Task automatically detects non-TTY environments
|
||||
(CI pipelines, etc.) and skips prompts.
|
||||
- **CLI override**: [`--no-tty`](./cli.md#--no-tty) to disable prompts
|
||||
|
||||
```yaml
|
||||
interactive: true
|
||||
```
|
||||
|
||||
## Example Configuration
|
||||
|
||||
Here's a complete example of a `.taskrc.yml` file with all available options:
|
||||
|
||||
@@ -632,7 +632,7 @@ tasks:
|
||||
#### `requires`
|
||||
|
||||
- **Type**: `Requires`
|
||||
- **Description**: Required variables with optional enums and interactive prompting
|
||||
- **Description**: Required variables with optional enum validation
|
||||
|
||||
```yaml
|
||||
tasks:
|
||||
@@ -655,23 +655,10 @@ tasks:
|
||||
cmds:
|
||||
- echo "Deploying to {{.ENVIRONMENT}} with log level {{.LOG_LEVEL}}"
|
||||
- ./deploy.sh
|
||||
|
||||
# Interactive prompts for missing variables
|
||||
interactive-deploy:
|
||||
requires:
|
||||
vars:
|
||||
- name: ENVIRONMENT
|
||||
interactive: true
|
||||
enum: [development, staging, production]
|
||||
- name: API_KEY
|
||||
interactive: true
|
||||
cmds:
|
||||
- ./deploy.sh
|
||||
```
|
||||
|
||||
When `interactive: true` is set, Task will prompt the user for the variable value
|
||||
if it is not already defined. For variables with `enum`, a selection menu is shown.
|
||||
Use `--no-tty` to disable interactive prompts (useful for CI environments).
|
||||
See [Prompting for missing variables interactively](/docs/guide#prompting-for-missing-variables-interactively)
|
||||
for information on enabling interactive prompts for missing required variables.
|
||||
|
||||
#### `watch`
|
||||
|
||||
|
||||
@@ -70,6 +70,11 @@
|
||||
"description": "When running tasks in parallel, stop all tasks if one fails.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
},
|
||||
"interactive": {
|
||||
"description": "Prompt for missing required variables instead of failing. Requires a TTY.",
|
||||
"type": "boolean",
|
||||
"default": false
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
|
||||
@@ -598,12 +598,7 @@
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"name": { "type": "string" },
|
||||
"enum": { "type": "array", "items": { "type": "string" } },
|
||||
"interactive": {
|
||||
"type": "boolean",
|
||||
"description": "If true, prompt the user for this variable if it is not set",
|
||||
"default": false
|
||||
}
|
||||
"enum": { "type": "array", "items": { "type": "string" } }
|
||||
},
|
||||
"required": ["name"],
|
||||
"additionalProperties": false
|
||||
|
||||
Reference in New Issue
Block a user