diff --git a/compiler.go b/compiler.go index 311fd58423..547b9ac235 100644 --- a/compiler.go +++ b/compiler.go @@ -47,6 +47,19 @@ func (c *Compiler) FastGetVariables(t *ast.Task, call *Call) (*ast.Vars, error) func (c *Compiler) getVariables(t *ast.Task, call *Call, evaluateShVars bool) (*ast.Vars, error) { result := env.GetEnviron() specialVars, err := c.getSpecialVars(t, call) + + if t != nil && t.Requires != nil { + for _, requiredVar := range t.Requires.Vars { + if requiredVar.Sh != "" { + newVar := ast.Var{ + Sh: &requiredVar.Sh, + } + static, _ := c.HandleDynamicVar(newVar, c.Dir, env.GetFromVars(result)) + requiredVar.Enum = strings.Split(static, "\n") + } + } + } + if err != nil { return nil, err } diff --git a/taskfile/ast/requires.go b/taskfile/ast/requires.go index 5a76e13fcd..2278a1356c 100644 --- a/taskfile/ast/requires.go +++ b/taskfile/ast/requires.go @@ -25,6 +25,7 @@ func (r *Requires) DeepCopy() *Requires { type VarsWithValidation struct { Name string Enum []string + Sh string } func (v *VarsWithValidation) DeepCopy() *VarsWithValidation { @@ -34,6 +35,7 @@ func (v *VarsWithValidation) DeepCopy() *VarsWithValidation { return &VarsWithValidation{ Name: v.Name, Enum: v.Enum, + Sh: v.Sh, } } @@ -53,6 +55,7 @@ func (v *VarsWithValidation) UnmarshalYAML(node *yaml.Node) error { case yaml.MappingNode: var vv struct { Name string + Sh string Enum []string } if err := node.Decode(&vv); err != nil { @@ -60,6 +63,7 @@ func (v *VarsWithValidation) UnmarshalYAML(node *yaml.Node) error { } v.Name = vv.Name v.Enum = vv.Enum + v.Sh = vv.Sh return nil } diff --git a/testdata/interactive_vars/Taskfile.yml b/testdata/interactive_vars/Taskfile.yml index 49f68a2fa1..f3c1388f9e 100644 --- a/testdata/interactive_vars/Taskfile.yml +++ b/testdata/interactive_vars/Taskfile.yml @@ -20,6 +20,15 @@ tasks: cmds: - echo "Deploying to {{.ENVIRONMENT}}..." + choose_file: + desc: Choose a file + requires: + vars: + - name: SELECTED_FILE + sh: printf "val1\nval2\nval3\n" + cmds: + - echo "You have selected {{.SELECTED_FILE}}" + # Multiple variables at once release: desc: Create a release with version and environment diff --git a/website/src/docs/guide.md b/website/src/docs/guide.md index 6c3eb912bf..31257c9257 100644 --- a/website/src/docs/guide.md +++ b/website/src/docs/guide.md @@ -1243,9 +1243,11 @@ failing, you can enable interactive mode in your `.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. +When enabled, Task will display an interactive prompt for any missing required variable. +Interactive variables can either be a simple text input or a select menu. + +The select menu presents a list of possible values to select from when a list of values is defined in an `enum` array, or dynamically with an `sh` script. +When using an `sh` script the values need to be new line delimited. ```yaml # Taskfile.yml @@ -1260,6 +1262,16 @@ tasks: - VERSION cmds: - echo "Deploying {{.VERSION}} to {{.ENVIRONMENT}}" + copy-file: + requires: + vars: + - name: SELECTED_FILE + sh: ls # will prompt to select from a list of files in your workdir + - name: ENVIRONMENT + sh: get_envs.sh # a script that returns a new line delimited list of available envs + cmds: + - echo "Deploying {{.SELECTED_FILE}} to {{.ENVIRONMENT}}" + ``` ```shell diff --git a/website/src/docs/reference/schema.md b/website/src/docs/reference/schema.md index d0d4286943..703312806d 100644 --- a/website/src/docs/reference/schema.md +++ b/website/src/docs/reference/schema.md @@ -655,7 +655,7 @@ tasks: #### `requires` - **Type**: `Requires` -- **Description**: Required variables with optional enum validation +- **Description**: Required variables with optional enum validation, or options read from `sh` script evaluation ```yaml tasks: @@ -678,6 +678,19 @@ tasks: cmds: - echo "Deploying to {{.ENVIRONMENT}} with log level {{.LOG_LEVEL}}" - ./deploy.sh + + + # Requirements with options coming from a sh script + select-file: + requires: + vars: + - name: SELECTED_FILE + sh: ls + - name: DEPLOY_ENV + sh: get_envs.sh # Script should return \n separated vals + cmds: + - echo "You have selected file: {{.SELECTED_FILE}}" + - echo "You have selected env: {{.DEPLOY_ENV}}" ``` See [Prompting for missing variables interactively](/docs/guide#prompting-for-missing-variables-interactively) diff --git a/website/src/public/schema.json b/website/src/public/schema.json index 28ae66110b..081d69f9fb 100644 --- a/website/src/public/schema.json +++ b/website/src/public/schema.json @@ -629,6 +629,18 @@ "items": { "oneOf": [ { "type": "string" }, + { + "type": "object", + "properties": { + "name": { "type": "string" }, + "sh": { + "type": "string", + "description": "The value will be treated as a command and the output assigned to the variable" + } + }, + "required": ["name"], + "additionalProperties": false + }, { "type": "object", "properties": {