github.com/pulumi/terraform@v1.4.0/pkg/terminal/stream.go (about)

     1  package terminal
     2  
     3  import (
     4  	"os"
     5  )
     6  
     7  const defaultColumns int = 78
     8  const defaultIsTerminal bool = false
     9  
    10  // OutputStream represents an output stream that might or might not be connected
    11  // to a terminal.
    12  //
    13  // There are typically two instances of this: one representing stdout and one
    14  // representing stderr.
    15  type OutputStream struct {
    16  	File *os.File
    17  
    18  	// Interacting with a terminal is typically platform-specific, so we
    19  	// factor out these into virtual functions, although we have default
    20  	// behaviors suitable for non-Terminal output if any of these isn't
    21  	// set. (We're using function pointers rather than interfaces for this
    22  	// because it allows us to mix both normal methods and virtual methods
    23  	// on the same type, without a bunch of extra complexity.)
    24  	isTerminal func(*os.File) bool
    25  	getColumns func(*os.File) int
    26  }
    27  
    28  // Columns returns a number of character cell columns that we expect will
    29  // fill the width of the terminal that stdout is connected to, or a reasonable
    30  // placeholder value of 78 if the output doesn't seem to be a terminal.
    31  //
    32  // This is a best-effort sort of function which may give an inaccurate result
    33  // in various cases. For example, callers storing the result will not react
    34  // to subsequent changes in the terminal width, and indeed this function itself
    35  // may not be able to either, depending on the constraints of the current
    36  // execution context.
    37  func (s *OutputStream) Columns() int {
    38  	if s.getColumns == nil {
    39  		return defaultColumns
    40  	}
    41  	return s.getColumns(s.File)
    42  }
    43  
    44  // IsTerminal returns true if we expect that the stream is connected to a
    45  // terminal which supports VT100-style formatting and cursor control sequences.
    46  func (s *OutputStream) IsTerminal() bool {
    47  	if s.isTerminal == nil {
    48  		return defaultIsTerminal
    49  	}
    50  	return s.isTerminal(s.File)
    51  }
    52  
    53  // InputStream represents an input stream that might or might not be a terminal.
    54  //
    55  // There is typically only one instance of this type, representing stdin.
    56  type InputStream struct {
    57  	File *os.File
    58  
    59  	// Interacting with a terminal is typically platform-specific, so we
    60  	// factor out these into virtual functions, although we have default
    61  	// behaviors suitable for non-Terminal output if any of these isn't
    62  	// set. (We're using function pointers rather than interfaces for this
    63  	// because it allows us to mix both normal methods and virtual methods
    64  	// on the same type, without a bunch of extra complexity.)
    65  	isTerminal func(*os.File) bool
    66  }
    67  
    68  // IsTerminal returns true if we expect that the stream is connected to a
    69  // terminal which can support interactive input.
    70  //
    71  // If this returns false, callers might prefer to skip elaborate input prompt
    72  // functionality like tab completion and instead just treat the input as a
    73  // raw byte stream, or perhaps skip prompting for input at all depending on the
    74  // situation.
    75  func (s *InputStream) IsTerminal() bool {
    76  	if s.isTerminal == nil {
    77  		return defaultIsTerminal
    78  	}
    79  	return s.isTerminal(s.File)
    80  }