1
0
mirror of https://github.com/go-task/task.git synced 2025-08-10 22:42:19 +02:00

chore: improvements on #1163 + changelog entry

This commit is contained in:
Andrey Nering
2023-06-03 22:33:22 -03:00
parent f815ce2901
commit 44aaec86a1
9 changed files with 80 additions and 41 deletions

View File

@@ -8,6 +8,9 @@
website (#1198 by @pd93).
- Deprecated `version: 2` schema. This will be removed in the next major release
(#1197, #1198, #1199 by @pd93).
- Added a new `prompt:` prop to set a warning prompt to be shown before running
a potential dangurous task (#100, #1163 by @MaxCheetham,
[Documentation](https://taskfile.dev/usage/#warning-prompts))
## v3.25.0 - 2023-05-22

View File

@@ -44,7 +44,7 @@ If `--` is given, all remaning arguments will be assigned to a special
| | `--output-group-error-only` | `bool` | `false` | Swallow command output on zero exit code. |
| `-p` | `--parallel` | `bool` | `false` | Executes tasks provided on command line in parallel. |
| `-s` | `--silent` | `bool` | `false` | Disables echoing. |
| `-y` | `--yes` | `bool` | `false` | Assume "yes" as answer to all prompts. |
| `-y` | `--yes` | `bool` | `false` | Assume "yes" as answer to all prompts. |
| | `--status` | `bool` | `false` | Exits with non-zero exit code if any of the given tasks is not up-to-date. |
| | `--summary` | `bool` | `false` | Show summary about a task. |
| `-t` | `--taskfile` | `string` | `Taskfile.yml` or `Taskfile.yaml` | |

View File

@@ -1216,7 +1216,9 @@ tasks:
Warning Prompts to prompt a user for confirmation before a task is executed.
Below is an example using `prompt` with a dangerous command, that is called between two safe commands
Below is an example using `prompt` with a dangerous command, that is called
between two safe commands:
```yaml
version: '3'
@@ -1229,46 +1231,47 @@ tasks:
not-dangerous:
cmds:
- echo 'not dangerous command.'
- echo 'not dangerous command'
another-not-dangerous:
cmds:
- echo 'another not dangerous command.'
- echo 'another not dangerous command'
dangerous:
prompt: This is a dangerous command.. Do you want to continue?
prompt: This is a dangerous command... Do you want to continue?
cmds:
- echo 'dangerous command.'
- echo 'dangerous command'
```
```bash
❯ task dangerous
task: "This is a dangerous command.. Do you want to continue?" [y/N]
task: "This is a dangerous command... Do you want to continue?" [y/N]
```
### Prompt behaviour
Warning prompts are called before executing a task. If a prompt is denied Task will exit with [Exit code](api_reference.md#exit-codes) 205. If approved, Task will continue as normal.
Warning prompts are called before executing a task. If a prompt is denied Task
will exit with [exit code](api_reference.md#exit-codes) 205. If approved, Task
will continue as normal.
```bash
❯ taskd --dir ./testdata/prompt example
task: [not-dangerous] echo 'not dangerous command.'
not dangerous command.
task: "This is a dangerous command.. Do you want to continue?" [y/N]
❯ task example
not dangerous command
task: "This is a dangerous command. Do you want to continue?" [y/N]
y
task: [dangerous] echo 'dangerous command.'
dangerous command.
task: [another-not-dangerous] echo 'another not dangerous command.'
another not dangerous command.
dangerous command
another not dangerous command
```
### Skipping Warning Prompts
To skip warning prompts automatically, you can use the [-y | --yes] option when calling the task. By including this option, all warnings, will be automatically confirmed, and no prompts will be shows.
To skip warning prompts automatically, you can use the `--yes` (alias `-y`)
option when calling the task. By including this option, all warnings, will be
automatically confirmed, and no prompts will be shown.
:::caution
Tasks with prompts always fail by default on non-terminal environments, like a
CI, where an `stdin` won't be available for the user to answer. In cases like,
use `--yes` (`-y`) to force all tasks with a prompt to run.
:::
## Silent mode

View File

@@ -99,18 +99,34 @@ func (err *TaskCalledTooManyTimesError) Code() int {
return CodeTaskCalledTooManyTimes
}
// TaskCancelledError is returned when the user does not accept an optional prompt to continue.
type TaskCancelledError struct {
// TaskCancelledByUserError is returned when the user does not accept an optional prompt to continue.
type TaskCancelledByUserError struct {
TaskName string
}
func (err *TaskCancelledError) Error() string {
func (err *TaskCancelledByUserError) Error() string {
return fmt.Sprintf(
`task: %q Cancelled by user`,
`task: Task "%q" cancelled by user`,
err.TaskName,
)
}
func (err *TaskCancelledError) Code() int {
func (err *TaskCancelledByUserError) Code() int {
return CodeTaskCancelled
}
// TaskCancelledNoTerminalError is returned when trying to run a task with a prompt in a non-terminal environment.
type TaskCancelledNoTerminalError struct {
TaskName string
}
func (err *TaskCancelledNoTerminalError) Error() string {
return fmt.Sprintf(
`task: Task "%q" cancelled because it has a prompt and the environment is not a terminal. Use --yes (-y) to run anyway.`,
err.TaskName,
)
}
func (err *TaskCancelledNoTerminalError) Code() int {
return CodeTaskCancelled
}

2
go.mod
View File

@@ -15,6 +15,7 @@ require (
github.com/stretchr/testify v1.8.4
golang.org/x/exp v0.0.0-20230212135524-a684f29349b6
golang.org/x/sync v0.2.0
golang.org/x/term v0.3.0
gopkg.in/yaml.v3 v3.0.1
mvdan.cc/sh/v3 v3.6.0
)
@@ -26,6 +27,5 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/stretchr/objx v0.5.0 // indirect
golang.org/x/sys v0.6.0 // indirect
golang.org/x/term v0.3.0 // indirect
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127 // indirect
)

11
internal/term/term.go Normal file
View File

@@ -0,0 +1,11 @@
package term
import (
"os"
"golang.org/x/term"
)
func IsTerminal() bool {
return term.IsTerminal(int(os.Stdin.Fd())) && term.IsTerminal(int(os.Stdout.Fd()))
}

10
task.go
View File

@@ -23,6 +23,7 @@ import (
"github.com/go-task/task/v3/internal/sort"
"github.com/go-task/task/v3/internal/summary"
"github.com/go-task/task/v3/internal/templater"
"github.com/go-task/task/v3/internal/term"
"github.com/go-task/task/v3/taskfile"
"github.com/sajari/fuzzy"
@@ -59,6 +60,7 @@ type Executor struct {
Color bool
Concurrency int
Interval time.Duration
AssumesTerm bool
Stdin io.Reader
Stdout io.Writer
@@ -102,7 +104,6 @@ func (e *Executor) Run(ctx context.Context, calls ...taskfile.Call) error {
}
return &errors.TaskInternalError{TaskName: call.Task}
}
}
if e.Summary {
@@ -148,10 +149,13 @@ func (e *Executor) RunTask(ctx context.Context, call taskfile.Call) error {
release := e.acquireConcurrencyLimit()
defer release()
// check if the given task has a warning prompt
if t.Prompt != "" && !e.AssumeYes {
if !e.AssumesTerm && !term.IsTerminal() {
return &errors.TaskCancelledNoTerminalError{TaskName: call.Task}
}
e.Logger.Outf(logger.Yellow, "task: %q [y/N]\n", t.Prompt)
reader := bufio.NewReader(e.Stdin)
userInput, err := reader.ReadString('\n')
if err != nil {
@@ -160,7 +164,7 @@ func (e *Executor) RunTask(ctx context.Context, call taskfile.Call) error {
userInput = strings.ToLower(strings.TrimSpace(userInput))
if !shouldPromptContinue(userInput) {
return &errors.TaskCancelledError{TaskName: call.Task}
return &errors.TaskCancelledByUserError{TaskName: call.Task}
}
}

View File

@@ -680,9 +680,10 @@ func TestPromptInSummary(t *testing.T) {
inBuff.Write([]byte(test.input))
e := task.Executor{
Dir: dir,
Stdin: &inBuff,
Stdout: &outBuff,
Dir: dir,
Stdin: &inBuff,
Stdout: &outBuff,
AssumesTerm: true,
}
require.NoError(t, e.Setup())
@@ -690,9 +691,9 @@ func TestPromptInSummary(t *testing.T) {
if test.wantError {
require.Error(t, err)
return
} else {
require.NoError(t, err)
}
require.NoError(t, err)
})
}
}
@@ -705,9 +706,10 @@ func TestPromptWithIndirectTask(t *testing.T) {
inBuff.Write([]byte("y\n"))
e := task.Executor{
Dir: dir,
Stdin: &inBuff,
Stdout: &outBuff,
Dir: dir,
Stdin: &inBuff,
Stdout: &outBuff,
AssumesTerm: true,
}
require.NoError(t, e.Setup())

View File

@@ -1,4 +1,5 @@
version: 3
tasks:
foo:
prompt: Do you want to continue?
@@ -10,7 +11,6 @@ tasks:
- task: show-prompt
show-prompt:
summary: some text for the summary
prompt: Do you want to continue?
cmds:
- echo 'show-prompt'