Rename getCmdHandler to getCmdHandlerPty, and add getCmdHandlerNonPty

getCmdHandlerNonPty is defined for all platforms.
This commit is contained in:
Stefan Haller 2025-04-30 11:35:34 +02:00
parent a400ef0079
commit 8cf617b683
3 changed files with 42 additions and 43 deletions

View file

@ -4,6 +4,7 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"io" "io"
"os/exec"
"regexp" "regexp"
"strings" "strings"
"time" "time"
@ -11,6 +12,7 @@ import (
"github.com/go-errors/errors" "github.com/go-errors/errors"
"github.com/jesseduffield/gocui" "github.com/jesseduffield/gocui"
"github.com/jesseduffield/lazygit/pkg/utils" "github.com/jesseduffield/lazygit/pkg/utils"
"github.com/sasha-s/go-deadlock"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
@ -236,7 +238,7 @@ func (self *cmdObjRunner) runAndStreamAux(
var stderr bytes.Buffer var stderr bytes.Buffer
cmd.Stderr = io.MultiWriter(cmdWriter, &stderr) cmd.Stderr = io.MultiWriter(cmdWriter, &stderr)
handler, err := self.getCmdHandler(cmd) handler, err := self.getCmdHandlerPty(cmd)
if err != nil { if err != nil {
return err return err
} }
@ -410,3 +412,38 @@ func (self *cmdObjRunner) getCheckForCredentialRequestFunc() func([]byte) (Crede
return 0, false return 0, false
} }
} }
type Buffer struct {
b bytes.Buffer
m deadlock.Mutex
}
func (b *Buffer) Read(p []byte) (n int, err error) {
b.m.Lock()
defer b.m.Unlock()
return b.b.Read(p)
}
func (b *Buffer) Write(p []byte) (n int, err error) {
b.m.Lock()
defer b.m.Unlock()
return b.b.Write(p)
}
func (self *cmdObjRunner) getCmdHandlerNonPty(cmd *exec.Cmd) (*cmdHandler, error) {
stdoutReader, stdoutWriter := io.Pipe()
cmd.Stdout = stdoutWriter
buf := &Buffer{}
cmd.Stdin = buf
if err := cmd.Start(); err != nil {
return nil, err
}
return &cmdHandler{
stdoutPipe: stdoutReader,
stdinPipe: buf,
close: func() error { return nil },
}, nil
}

View file

@ -11,7 +11,7 @@ import (
// we define this separately for windows and non-windows given that windows does // we define this separately for windows and non-windows given that windows does
// not have great PTY support and we need a PTY to handle a credential request // not have great PTY support and we need a PTY to handle a credential request
func (self *cmdObjRunner) getCmdHandler(cmd *exec.Cmd) (*cmdHandler, error) { func (self *cmdObjRunner) getCmdHandlerPty(cmd *exec.Cmd) (*cmdHandler, error) {
ptmx, err := pty.Start(cmd) ptmx, err := pty.Start(cmd)
if err != nil { if err != nil {
return nil, err return nil, err

View file

@ -4,48 +4,10 @@
package oscommands package oscommands
import ( import (
"bytes"
"io"
"os/exec" "os/exec"
"github.com/sasha-s/go-deadlock"
) )
type Buffer struct { func (self *cmdObjRunner) getCmdHandlerPty(cmd *exec.Cmd) (*cmdHandler, error) {
b bytes.Buffer // We don't have PTY support on Windows yet, so we just return a non-PTY handler.
m deadlock.Mutex return self.getCmdHandlerNonPty(cmd)
}
func (b *Buffer) Read(p []byte) (n int, err error) {
b.m.Lock()
defer b.m.Unlock()
return b.b.Read(p)
}
func (b *Buffer) Write(p []byte) (n int, err error) {
b.m.Lock()
defer b.m.Unlock()
return b.b.Write(p)
}
// TODO: Remove this hack and replace it with a proper way to run commands live on windows. We still have an issue where if a password is requested, the request for a password is written straight to stdout because we can't control the stdout of a subprocess of a subprocess. Keep an eye on https://github.com/creack/pty/pull/109
func (self *cmdObjRunner) getCmdHandler(cmd *exec.Cmd) (*cmdHandler, error) {
stdoutReader, stdoutWriter := io.Pipe()
cmd.Stdout = stdoutWriter
buf := &Buffer{}
cmd.Stdin = buf
if err := cmd.Start(); err != nil {
return nil, err
}
// because we don't yet have windows support for a pty, we instead just
// pass our standard stream handlers and because there's no pty to close
// we pass a no-op function for that.
return &cmdHandler{
stdoutPipe: stdoutReader,
stdinPipe: buf,
close: func() error { return nil },
}, nil
} }