mirror of
https://github.com/hashicorp/packer.git
synced 2026-09-25 01:04:00 -04:00
* Updating the license from MPL to Business Source License Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at https://hashi.co/bsl-blog, FAQ at https://hashi.co/license-faq, and details of the license at www.hashicorp.com/bsl. * Update copyright file headers to BUSL-1.1 --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
86 lines
2.2 KiB
Go
86 lines
2.2 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
// STOLEN SHAMELESSLY FROM THE TERRAFORM REPO BECAUSE VENDORING OUT
|
|
// WRAPPEDREADLINE AND WRAPPEDSTREAMS FELT LIKE TOO MUCH WORK.
|
|
//
|
|
// "a little copying is better than a lot of dependency"
|
|
//
|
|
// 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/packer/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)
|
|
}
|