mirror of
https://github.com/go-task/task.git
synced 2025-12-16 19:57:43 +01:00
refactor(interactive): remove sync writer now that prompts are upfront
This commit is contained in:
@@ -54,11 +54,9 @@ type (
|
|||||||
Failfast bool
|
Failfast bool
|
||||||
|
|
||||||
// I/O
|
// I/O
|
||||||
Stdin io.Reader
|
Stdin io.Reader
|
||||||
Stdout io.Writer
|
Stdout io.Writer
|
||||||
Stderr io.Writer
|
Stderr io.Writer
|
||||||
rawStdout io.Writer // unwrapped stdout for prompts
|
|
||||||
rawStderr io.Writer // unwrapped stderr for prompts
|
|
||||||
|
|
||||||
// Internal
|
// Internal
|
||||||
Taskfile *ast.Taskfile
|
Taskfile *ast.Taskfile
|
||||||
@@ -73,7 +71,6 @@ type (
|
|||||||
fuzzyModel *fuzzy.Model
|
fuzzyModel *fuzzy.Model
|
||||||
fuzzyModelOnce sync.Once
|
fuzzyModelOnce sync.Once
|
||||||
|
|
||||||
promptMutex sync.Mutex
|
|
||||||
promptedVars *ast.Vars // vars collected via interactive prompts
|
promptedVars *ast.Vars // vars collected via interactive prompts
|
||||||
concurrencySemaphore chan struct{}
|
concurrencySemaphore chan struct{}
|
||||||
taskCallCount map[string]*int32
|
taskCallCount map[string]*int32
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
package output
|
|
||||||
|
|
||||||
import (
|
|
||||||
"io"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
// SyncWriter wraps an io.Writer with a mutex to synchronize writes.
|
|
||||||
// This is used to prevent output from interleaving with interactive prompts.
|
|
||||||
type SyncWriter struct {
|
|
||||||
w io.Writer
|
|
||||||
mu *sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSyncWriter creates a new SyncWriter that uses the provided mutex.
|
|
||||||
func NewSyncWriter(w io.Writer, mu *sync.Mutex) *SyncWriter {
|
|
||||||
return &SyncWriter{
|
|
||||||
w: w,
|
|
||||||
mu: mu,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Write implements io.Writer with synchronized access.
|
|
||||||
func (sw *SyncWriter) Write(p []byte) (n int, err error) {
|
|
||||||
sw.mu.Lock()
|
|
||||||
defer sw.mu.Unlock()
|
|
||||||
return sw.w.Write(p)
|
|
||||||
}
|
|
||||||
@@ -3,7 +3,6 @@ package prompt
|
|||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
"os"
|
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/charmbracelet/bubbles/textinput"
|
"github.com/charmbracelet/bubbles/textinput"
|
||||||
@@ -31,15 +30,6 @@ type Prompter struct {
|
|||||||
Stderr io.Writer
|
Stderr io.Writer
|
||||||
}
|
}
|
||||||
|
|
||||||
// New creates a new Prompter with default stdin/stdout/stderr
|
|
||||||
func New() *Prompter {
|
|
||||||
return &Prompter{
|
|
||||||
Stdin: os.Stdin,
|
|
||||||
Stdout: os.Stdout,
|
|
||||||
Stderr: os.Stderr,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Text prompts the user for a text value
|
// Text prompts the user for a text value
|
||||||
func (p *Prompter) Text(varName string) (string, error) {
|
func (p *Prompter) Text(varName string) (string, error) {
|
||||||
m := newTextModel(varName)
|
m := newTextModel(varName)
|
||||||
|
|||||||
@@ -91,15 +91,10 @@ func (e *Executor) promptForAllVars(vars []*ast.VarsWithValidation) (*ast.Vars,
|
|||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// Lock to prevent any output during prompting
|
|
||||||
e.promptMutex.Lock()
|
|
||||||
defer e.promptMutex.Unlock()
|
|
||||||
|
|
||||||
// Use raw stderr for prompts to avoid deadlock with SyncWriter
|
|
||||||
prompter := &prompt.Prompter{
|
prompter := &prompt.Prompter{
|
||||||
Stdin: e.Stdin,
|
Stdin: e.Stdin,
|
||||||
Stdout: e.rawStdout,
|
Stdout: e.Stdout,
|
||||||
Stderr: e.rawStderr,
|
Stderr: e.Stderr,
|
||||||
}
|
}
|
||||||
|
|
||||||
result := ast.NewVars()
|
result := ast.NewVars()
|
||||||
|
|||||||
12
setup.go
12
setup.go
@@ -19,7 +19,6 @@ import (
|
|||||||
"github.com/go-task/task/v3/internal/fsext"
|
"github.com/go-task/task/v3/internal/fsext"
|
||||||
"github.com/go-task/task/v3/internal/logger"
|
"github.com/go-task/task/v3/internal/logger"
|
||||||
"github.com/go-task/task/v3/internal/output"
|
"github.com/go-task/task/v3/internal/output"
|
||||||
"github.com/go-task/task/v3/internal/term"
|
|
||||||
"github.com/go-task/task/v3/internal/version"
|
"github.com/go-task/task/v3/internal/version"
|
||||||
"github.com/go-task/task/v3/taskfile"
|
"github.com/go-task/task/v3/taskfile"
|
||||||
"github.com/go-task/task/v3/taskfile/ast"
|
"github.com/go-task/task/v3/taskfile/ast"
|
||||||
@@ -180,17 +179,6 @@ func (e *Executor) setupStdFiles() {
|
|||||||
if e.Stderr == nil {
|
if e.Stderr == nil {
|
||||||
e.Stderr = os.Stderr
|
e.Stderr = os.Stderr
|
||||||
}
|
}
|
||||||
|
|
||||||
// Keep raw references for interactive prompts
|
|
||||||
e.rawStdout = e.Stdout
|
|
||||||
e.rawStderr = e.Stderr
|
|
||||||
|
|
||||||
// Wrap with synchronized writers when interactive mode is enabled AND we have a TTY
|
|
||||||
// to prevent output from interleaving with prompts
|
|
||||||
if e.Interactive && !e.NoTTY && (e.AssumeTerm || term.IsTerminal()) {
|
|
||||||
e.Stdout = output.NewSyncWriter(e.Stdout, &e.promptMutex)
|
|
||||||
e.Stderr = output.NewSyncWriter(e.Stderr, &e.promptMutex)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (e *Executor) setupLogger() {
|
func (e *Executor) setupLogger() {
|
||||||
|
|||||||
Reference in New Issue
Block a user