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
|
||||
|
||||
// I/O
|
||||
Stdin io.Reader
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
rawStdout io.Writer // unwrapped stdout for prompts
|
||||
rawStderr io.Writer // unwrapped stderr for prompts
|
||||
Stdin io.Reader
|
||||
Stdout io.Writer
|
||||
Stderr io.Writer
|
||||
|
||||
// Internal
|
||||
Taskfile *ast.Taskfile
|
||||
@@ -73,7 +71,6 @@ type (
|
||||
fuzzyModel *fuzzy.Model
|
||||
fuzzyModelOnce sync.Once
|
||||
|
||||
promptMutex sync.Mutex
|
||||
promptedVars *ast.Vars // vars collected via interactive prompts
|
||||
concurrencySemaphore chan struct{}
|
||||
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 (
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"strings"
|
||||
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
@@ -31,15 +30,6 @@ type Prompter struct {
|
||||
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
|
||||
func (p *Prompter) Text(varName string) (string, error) {
|
||||
m := newTextModel(varName)
|
||||
|
||||
@@ -91,15 +91,10 @@ func (e *Executor) promptForAllVars(vars []*ast.VarsWithValidation) (*ast.Vars,
|
||||
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{
|
||||
Stdin: e.Stdin,
|
||||
Stdout: e.rawStdout,
|
||||
Stderr: e.rawStderr,
|
||||
Stdout: e.Stdout,
|
||||
Stderr: e.Stderr,
|
||||
}
|
||||
|
||||
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/logger"
|
||||
"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/taskfile"
|
||||
"github.com/go-task/task/v3/taskfile/ast"
|
||||
@@ -180,17 +179,6 @@ func (e *Executor) setupStdFiles() {
|
||||
if e.Stderr == nil {
|
||||
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() {
|
||||
|
||||
Reference in New Issue
Block a user