terminal

package
v0.15.0-alpha20210210 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Feb 10, 2021 License: MPL-2.0 Imports: 2 Imported by: 0

Documentation

Overview

Package terminal encapsulates some platform-specific logic for detecting if we're running in a terminal and, if so, properly configuring that terminal to meet the assumptions that the rest of Terraform makes.

Specifically, Terraform requires a Terminal which supports virtual terminal sequences and which accepts UTF-8-encoded text.

This is an abstraction only over the platform-specific detection of and possibly initialization of terminals. It's not intended to provide higher-level abstractions of the sort provided by packages like termcap or curses; ultimately we just assume that terminals are "standard" VT100-like terminals and use a subset of control codes that works across the various platforms we support. Our approximate target is "xterm-compatible" virtual terminals.

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type InputStream

type InputStream struct {
	File *os.File
	// contains filtered or unexported fields
}

InputStream represents an input stream that might or might not be a terminal.

There is typically only one instance of this type, representing stdin.

func (*InputStream) IsTerminal

func (s *InputStream) IsTerminal() bool

IsTerminal returns true if we expect that the stream is connected to a terminal which can support interactive input.

If this returns false, callers might prefer to skip elaborate input prompt functionality like tab completion and instead just treat the input as a raw byte stream, or perhaps skip prompting for input at all depending on the situation.

type OutputStream

type OutputStream struct {
	File *os.File
	// contains filtered or unexported fields
}

OutputStream represents an output stream that might or might not be connected to a terminal.

There are typically two instances of this: one representing stdout and one representing stderr.

func (*OutputStream) Columns

func (s *OutputStream) Columns() int

Columns returns a number of character cell columns that we expect will fill the width of the terminal that stdout is connected to, or a reasonable placeholder value of 78 if the output doesn't seem to be a terminal.

This is a best-effort sort of function which may give an inaccurate result in various cases. For example, callers storing the result will not react to subsequent changes in the terminal width, and indeed this function itself may not be able to either, depending on the constraints of the current execution context.

func (*OutputStream) IsTerminal

func (s *OutputStream) IsTerminal() bool

IsTerminal returns true if we expect that the stream is connected to a terminal which supports VT100-style formatting and cursor control sequences.

type PrePanicwrapState

type PrePanicwrapState struct {
	StderrIsTerminal bool
	StderrWidth      int
}

PrePanicwrapState is a horrible thing we use to work around panicwrap, related to both Streams.StateForAfterPanicWrap and ReinitInsidePanicwrap.

type Streams

type Streams struct {
	Stdout *OutputStream
	Stderr *OutputStream
	Stdin  *InputStream
}

Streams represents a collection of three streams that each may or may not be connected to a terminal.

If a stream is connected to a terminal then there are more possibilities available, such as detecting the current terminal width. If we're connected to something else, such as a pipe or a file on disk, the stream will typically provide placeholder values or do-nothing stubs for terminal-requiring operatons.

Note that it's possible for only a subset of the streams to be connected to a terminal. For example, this happens if the user runs Terraform with I/O redirection where Stdout might refer to a regular disk file while Stderr refers to a terminal, or various other similar combinations.

func Init

func Init() (*Streams, error)

Init tries to initialize a terminal, if Terraform is running in one, and returns an object describing what it was able to set up.

An error for this function indicates that the current execution context can't meet Terraform's assumptions. For example, on Windows Init will return an error if Terraform is running in a Windows Console that refuses to activate UTF-8 mode, which can happen if we're running on an unsupported old version of Windows.

Note that the success of this function doesn't mean that we're actually running in a terminal. It could also represent successfully detecting that one or more of the input/output streams is not a terminal.

func ReinitInsidePanicwrap

func ReinitInsidePanicwrap(state *PrePanicwrapState) (*Streams, error)

ReinitInsidePanicwrap is part of the workaround for panicwrap that produces a Streams containing a potentially-lying Stderr that might claim to be a terminal even if it's actually a pipe connected to the parent process.

That's an okay lie in practice because the parent process will copy any data it recieves via that pipe verbatim to the real stderr anyway. (The original call to Init in the parent process should've already done any necessary modesetting on the Stderr terminal, if any.)

The state argument can be nil if we're not running in panicwrap mode, in which case this function behaves exactly the same as Init.

func (*Streams) StateForAfterPanicWrap

func (s *Streams) StateForAfterPanicWrap() *PrePanicwrapState

StateForAfterPanicWrap is part of the workaround for panicwrap that captures some characteristics of stderr that the caller can pass to the panicwrap child process somehow and then use ReinitInsidePanicWrap.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL