Module: Philiprehberger::CliKit::Prompt

Defined in:
lib/philiprehberger/cli_kit/prompt.rb

Overview

Interactive prompt utilities for CLI applications.

Class Method Summary collapse

Class Method Details

.ask(message, error: 'Invalid input, please try again.', input: $stdin, output: $stdout) {|answer| ... } ⇒ String

Display a prompt and read input, repeating until it passes validation.

The block is called with the stripped input; when it returns a truthy value the input is accepted and returned. When it returns a falsy value an optional error message is printed and the user is prompted again. When no block is given, any non-empty input is accepted.

Parameters:

  • message (String)

    the prompt message

  • error (String) (defaults to: 'Invalid input, please try again.')

    the message shown on invalid input

  • input (IO) (defaults to: $stdin)

    input stream (default: $stdin)

  • output (IO) (defaults to: $stdout)

    output stream (default: $stdout)

Yield Parameters:

  • answer (String)

    the stripped user input

Yield Returns:

  • (Boolean)

    whether the answer is acceptable

Returns:

  • (String)

    the accepted user input



76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/philiprehberger/cli_kit/prompt.rb', line 76

def self.ask(message, error: 'Invalid input, please try again.', input: $stdin, output: $stdout, &block)
  validator = block || ->(answer) { !answer.empty? }

  loop do
    output.print "#{message} "
    output.flush
    raw = input.gets
    return '' if raw.nil?

    answer = raw.strip
    return answer if validator.call(answer)

    output.puts error
  end
end

.confirm(message, input: $stdin, output: $stdout) ⇒ Boolean

Display a yes/no confirmation prompt.

Parameters:

  • message (String)

    the confirmation message

  • input (IO) (defaults to: $stdin)

    input stream (default: $stdin)

  • output (IO) (defaults to: $stdout)

    output stream (default: $stdout)

Returns:

  • (Boolean)

    true if user answered yes



25
26
27
28
29
30
# File 'lib/philiprehberger/cli_kit/prompt.rb', line 25

def self.confirm(message, input: $stdin, output: $stdout)
  output.print "#{message} [y/n] "
  output.flush
  answer = input.gets&.strip&.downcase || ''
  %w[y yes].include?(answer)
end

.password(message, input: $stdin, output: $stdout) ⇒ String

Display a prompt and read input without echoing characters to the terminal.

When the input stream responds to noecho (a real TTY), echo is disabled for the duration of the read. When it does not (e.g. a StringIO during tests), input is read normally. A trailing newline is printed to the output after the read so the next prompt starts on its own line.

Parameters:

  • message (String)

    the prompt message

  • input (IO) (defaults to: $stdin)

    input stream (default: $stdin)

  • output (IO) (defaults to: $stdout)

    output stream (default: $stdout)

Returns:

  • (String)

    the user’s input, stripped of whitespace



43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/philiprehberger/cli_kit/prompt.rb', line 43

def self.password(message, input: $stdin, output: $stdout)
  output.print "#{message} "
  output.flush

  raw = if input.respond_to?(:noecho)
          begin
            input.noecho(&:gets)
          rescue IOError, Errno::ENOTTY
            input.gets
          end
        else
          input.gets
        end

  output.print "\n"
  output.flush
  raw&.strip || ''
end

.prompt(message, input: $stdin, output: $stdout) ⇒ String

Display a prompt and read user input.

Parameters:

  • message (String)

    the prompt message

  • input (IO) (defaults to: $stdin)

    input stream (default: $stdin)

  • output (IO) (defaults to: $stdout)

    output stream (default: $stdout)

Returns:

  • (String)

    the user’s input, stripped of whitespace



13
14
15
16
17
# File 'lib/philiprehberger/cli_kit/prompt.rb', line 13

def self.prompt(message, input: $stdin, output: $stdout)
  output.print "#{message} "
  output.flush
  input.gets&.strip || ''
end