remove wrapped streams and readline
This commit is contained in:
parent
622c4df14c
commit
42742c173d
|
@ -3,11 +3,11 @@ package command
|
||||||
import (
|
import (
|
||||||
"bufio"
|
"bufio"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"os"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/internal/addrs"
|
"github.com/hashicorp/terraform/internal/addrs"
|
||||||
"github.com/hashicorp/terraform/internal/backend"
|
"github.com/hashicorp/terraform/internal/backend"
|
||||||
"github.com/hashicorp/terraform/internal/helper/wrappedstreams"
|
|
||||||
"github.com/hashicorp/terraform/internal/repl"
|
"github.com/hashicorp/terraform/internal/repl"
|
||||||
"github.com/hashicorp/terraform/internal/terraform"
|
"github.com/hashicorp/terraform/internal/terraform"
|
||||||
"github.com/hashicorp/terraform/internal/tfdiags"
|
"github.com/hashicorp/terraform/internal/tfdiags"
|
||||||
|
@ -113,8 +113,8 @@ func (c *ConsoleCommand) Run(args []string) int {
|
||||||
|
|
||||||
// Set up the UI so we can output directly to stdout
|
// Set up the UI so we can output directly to stdout
|
||||||
ui := &cli.BasicUi{
|
ui := &cli.BasicUi{
|
||||||
Writer: wrappedstreams.Stdout(),
|
Writer: os.Stdout,
|
||||||
ErrorWriter: wrappedstreams.Stderr(),
|
ErrorWriter: os.Stderr,
|
||||||
}
|
}
|
||||||
|
|
||||||
evalOpts := &terraform.EvalOpts{}
|
evalOpts := &terraform.EvalOpts{}
|
||||||
|
@ -164,7 +164,7 @@ func (c *ConsoleCommand) Run(args []string) int {
|
||||||
|
|
||||||
func (c *ConsoleCommand) modePiped(session *repl.Session, ui cli.Ui) int {
|
func (c *ConsoleCommand) modePiped(session *repl.Session, ui cli.Ui) int {
|
||||||
var lastResult string
|
var lastResult string
|
||||||
scanner := bufio.NewScanner(wrappedstreams.Stdin())
|
scanner := bufio.NewScanner(os.Stdin)
|
||||||
for scanner.Scan() {
|
for scanner.Scan() {
|
||||||
result, exit, diags := session.Handle(strings.TrimSpace(scanner.Text()))
|
result, exit, diags := session.Handle(strings.TrimSpace(scanner.Text()))
|
||||||
if diags.HasErrors() {
|
if diags.HasErrors() {
|
||||||
|
|
|
@ -9,6 +9,7 @@ package command
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
"io"
|
||||||
|
"os"
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/internal/repl"
|
"github.com/hashicorp/terraform/internal/repl"
|
||||||
|
|
||||||
|
@ -23,6 +24,9 @@ func (c *ConsoleCommand) modeInteractive(session *repl.Session, ui cli.Ui) int {
|
||||||
InterruptPrompt: "^C",
|
InterruptPrompt: "^C",
|
||||||
EOFPrompt: "exit",
|
EOFPrompt: "exit",
|
||||||
HistorySearchFold: true,
|
HistorySearchFold: true,
|
||||||
|
Stdin: os.Stdin,
|
||||||
|
Stdout: os.Stdout,
|
||||||
|
Stderr: os.Stderr,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Ui.Error(fmt.Sprintf(
|
c.Ui.Error(fmt.Sprintf(
|
||||||
|
|
|
@ -1,77 +0,0 @@
|
||||||
// wrappedreadline is a package that has helpers for interacting with
|
|
||||||
// readline from a panicwrap executable.
|
|
||||||
//
|
|
||||||
// panicwrap overrides the standard file descriptors so that the child process
|
|
||||||
// no longer looks like a TTY. The helpers here access the extra file descriptors
|
|
||||||
// passed by panicwrap to fix that.
|
|
||||||
//
|
|
||||||
// panicwrap should be checked for with panicwrap.Wrapped before using this
|
|
||||||
// librar, since this library won't adapt if the binary is not wrapped.
|
|
||||||
package wrappedreadline
|
|
||||||
|
|
||||||
import (
|
|
||||||
"runtime"
|
|
||||||
|
|
||||||
"github.com/chzyer/readline"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/internal/helper/wrappedstreams"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Override overrides the values in readline.Config that need to be
|
|
||||||
// set with wrapped values.
|
|
||||||
func Override(cfg *readline.Config) *readline.Config {
|
|
||||||
cfg.Stdin = wrappedstreams.Stdin()
|
|
||||||
cfg.Stdout = wrappedstreams.Stdout()
|
|
||||||
cfg.Stderr = wrappedstreams.Stderr()
|
|
||||||
|
|
||||||
cfg.FuncGetWidth = TerminalWidth
|
|
||||||
cfg.FuncIsTerminal = IsTerminal
|
|
||||||
|
|
||||||
rm := RawMode{StdinFd: int(wrappedstreams.Stdin().Fd())}
|
|
||||||
cfg.FuncMakeRaw = rm.Enter
|
|
||||||
cfg.FuncExitRaw = rm.Exit
|
|
||||||
|
|
||||||
return cfg
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsTerminal determines if this process is attached to a TTY.
|
|
||||||
func IsTerminal() bool {
|
|
||||||
// Windows is always a terminal
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// Same implementation as readline but with our custom fds
|
|
||||||
return readline.IsTerminal(int(wrappedstreams.Stdin().Fd())) &&
|
|
||||||
(readline.IsTerminal(int(wrappedstreams.Stdout().Fd())) ||
|
|
||||||
readline.IsTerminal(int(wrappedstreams.Stderr().Fd())))
|
|
||||||
}
|
|
||||||
|
|
||||||
// TerminalWidth gets the terminal width in characters.
|
|
||||||
func TerminalWidth() int {
|
|
||||||
if runtime.GOOS == "windows" {
|
|
||||||
return readline.GetScreenWidth()
|
|
||||||
}
|
|
||||||
|
|
||||||
return getWidth()
|
|
||||||
}
|
|
||||||
|
|
||||||
// RawMode is a helper for entering and exiting raw mode.
|
|
||||||
type RawMode struct {
|
|
||||||
StdinFd int
|
|
||||||
|
|
||||||
state *readline.State
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *RawMode) Enter() (err error) {
|
|
||||||
r.state, err = readline.MakeRaw(r.StdinFd)
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *RawMode) Exit() error {
|
|
||||||
if r.state == nil {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return readline.Restore(r.StdinFd, r.state)
|
|
||||||
}
|
|
|
@ -1,47 +0,0 @@
|
||||||
//go:build darwin || dragonfly || freebsd || (linux && !appengine) || netbsd || openbsd
|
|
||||||
// +build darwin dragonfly freebsd linux,!appengine netbsd openbsd
|
|
||||||
|
|
||||||
package wrappedreadline
|
|
||||||
|
|
||||||
import (
|
|
||||||
"syscall"
|
|
||||||
"unsafe"
|
|
||||||
|
|
||||||
"github.com/hashicorp/terraform/internal/helper/wrappedstreams"
|
|
||||||
)
|
|
||||||
|
|
||||||
// getWidth impl for Unix
|
|
||||||
func getWidth() int {
|
|
||||||
stdoutFd := int(wrappedstreams.Stdout().Fd())
|
|
||||||
stderrFd := int(wrappedstreams.Stderr().Fd())
|
|
||||||
|
|
||||||
w := getWidthFd(stdoutFd)
|
|
||||||
if w < 0 {
|
|
||||||
w = getWidthFd(stderrFd)
|
|
||||||
}
|
|
||||||
|
|
||||||
return w
|
|
||||||
}
|
|
||||||
|
|
||||||
type winsize struct {
|
|
||||||
Row uint16
|
|
||||||
Col uint16
|
|
||||||
Xpixel uint16
|
|
||||||
Ypixel uint16
|
|
||||||
}
|
|
||||||
|
|
||||||
// get width of the terminal
|
|
||||||
func getWidthFd(stdoutFd int) int {
|
|
||||||
ws := &winsize{}
|
|
||||||
retCode, _, errno := syscall.Syscall(syscall.SYS_IOCTL,
|
|
||||||
uintptr(stdoutFd),
|
|
||||||
uintptr(syscall.TIOCGWINSZ),
|
|
||||||
uintptr(unsafe.Pointer(ws)))
|
|
||||||
|
|
||||||
if int(retCode) == -1 {
|
|
||||||
_ = errno
|
|
||||||
return -1
|
|
||||||
}
|
|
||||||
|
|
||||||
return int(ws.Col)
|
|
||||||
}
|
|
|
@ -1,9 +0,0 @@
|
||||||
//go:build windows
|
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package wrappedreadline
|
|
||||||
|
|
||||||
// getWidth impl for other
|
|
||||||
func getWidth() int {
|
|
||||||
return 0
|
|
||||||
}
|
|
|
@ -1,44 +0,0 @@
|
||||||
// Package wrappedstreams provides access to the standard OS streams
|
|
||||||
// (stdin, stdout, stderr) even if wrapped under panicwrap.
|
|
||||||
package wrappedstreams
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
|
|
||||||
"github.com/mitchellh/panicwrap"
|
|
||||||
)
|
|
||||||
|
|
||||||
// Stdin returns the true stdin of the process.
|
|
||||||
func Stdin() *os.File {
|
|
||||||
stdin, _, _ := fds()
|
|
||||||
return stdin
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stdout returns the true stdout of the process.
|
|
||||||
func Stdout() *os.File {
|
|
||||||
_, stdout, _ := fds()
|
|
||||||
return stdout
|
|
||||||
}
|
|
||||||
|
|
||||||
// Stderr returns the true stderr of the process.
|
|
||||||
func Stderr() *os.File {
|
|
||||||
_, _, stderr := fds()
|
|
||||||
return stderr
|
|
||||||
}
|
|
||||||
|
|
||||||
func fds() (stdin, stdout, stderr *os.File) {
|
|
||||||
stdin, stdout, stderr = os.Stdin, os.Stdout, os.Stderr
|
|
||||||
if panicwrap.Wrapped(nil) {
|
|
||||||
initPlatform()
|
|
||||||
stdin, stdout, stderr = wrappedStdin, wrappedStdout, wrappedStderr
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// These are the wrapped standard streams. These are set up by the
|
|
||||||
// platform specific code in initPlatform.
|
|
||||||
var (
|
|
||||||
wrappedStdin *os.File
|
|
||||||
wrappedStdout *os.File
|
|
||||||
wrappedStderr *os.File
|
|
||||||
)
|
|
|
@ -1,22 +0,0 @@
|
||||||
//go:build !windows
|
|
||||||
// +build !windows
|
|
||||||
|
|
||||||
package wrappedstreams
|
|
||||||
|
|
||||||
import (
|
|
||||||
"os"
|
|
||||||
"sync"
|
|
||||||
)
|
|
||||||
|
|
||||||
var initOnce sync.Once
|
|
||||||
|
|
||||||
func initPlatform() {
|
|
||||||
// These must be initialized lazily, once it's been determined that this is
|
|
||||||
// a wrapped process.
|
|
||||||
initOnce.Do(func() {
|
|
||||||
// The standard streams are passed in via extra file descriptors.
|
|
||||||
wrappedStdin = os.NewFile(uintptr(3), "stdin")
|
|
||||||
wrappedStdout = os.NewFile(uintptr(4), "stdout")
|
|
||||||
wrappedStderr = os.NewFile(uintptr(5), "stderr")
|
|
||||||
})
|
|
||||||
}
|
|
|
@ -1,53 +0,0 @@
|
||||||
//go:build windows
|
|
||||||
// +build windows
|
|
||||||
|
|
||||||
package wrappedstreams
|
|
||||||
|
|
||||||
import (
|
|
||||||
"log"
|
|
||||||
"os"
|
|
||||||
"syscall"
|
|
||||||
)
|
|
||||||
|
|
||||||
func initPlatform() {
|
|
||||||
wrappedStdin = openConsole("CONIN$", os.Stdin)
|
|
||||||
wrappedStdout = openConsole("CONOUT$", os.Stdout)
|
|
||||||
wrappedStderr = wrappedStdout
|
|
||||||
}
|
|
||||||
|
|
||||||
// openConsole opens a console handle, using a backup if it fails.
|
|
||||||
// This is used to get the exact console handle instead of the redirected
|
|
||||||
// handles from panicwrap.
|
|
||||||
func openConsole(name string, backup *os.File) *os.File {
|
|
||||||
// Convert to UTF16
|
|
||||||
path, err := syscall.UTF16PtrFromString(name)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("[ERROR] wrappedstreams: %s", err)
|
|
||||||
return backup
|
|
||||||
}
|
|
||||||
|
|
||||||
// Determine the share mode
|
|
||||||
var shareMode uint32
|
|
||||||
switch name {
|
|
||||||
case "CONIN$":
|
|
||||||
shareMode = syscall.FILE_SHARE_READ
|
|
||||||
case "CONOUT$":
|
|
||||||
shareMode = syscall.FILE_SHARE_WRITE
|
|
||||||
}
|
|
||||||
|
|
||||||
// Get the file
|
|
||||||
h, err := syscall.CreateFile(
|
|
||||||
path,
|
|
||||||
syscall.GENERIC_READ|syscall.GENERIC_WRITE,
|
|
||||||
shareMode,
|
|
||||||
nil,
|
|
||||||
syscall.OPEN_EXISTING,
|
|
||||||
0, 0)
|
|
||||||
if err != nil {
|
|
||||||
log.Printf("[ERROR] wrappedstreams: %s", err)
|
|
||||||
return backup
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create the Go file
|
|
||||||
return os.NewFile(uintptr(h), name)
|
|
||||||
}
|
|
Loading…
Reference in New Issue