Module: Babushka::Prompt

Defined in:
lib/babushka/prompt.rb

Class Method Summary collapse

Class Method Details

.confirm(message, opts = {}, &block) ⇒ Object


19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/babushka/prompt.rb', line 19

def confirm message, opts = {}, &block
  answer = get_value(message,
    :message => message,
    :confirmation => true,
    :default => (opts[:default] || 'y')
  ).starts_with?('y')

  if block.nil?
    answer
  elsif answer
    block.call
  elsif opts[:otherwise]
    LogHelpers.log opts[:otherwise]
  end
end

.get_value(message, opts = {}, &block) ⇒ Object


35
36
37
38
39
40
41
42
43
44
45
46
# File 'lib/babushka/prompt.rb', line 35

def get_value message, opts = {}, &block
  if opts[:choices] && opts[:choice_descriptions]
    raise ArgumentError, "You can't use the :choices and :choice_descriptions options together."
  elsif opts[:choice_descriptions]
    opts[:choices] = opts[:choice_descriptions].keys
  end
  if opts[:choices] && opts[:choices].any? {|c| !c.is_a?(String) }
    raise ArgumentError, "Choices must be passed as strings."
  end
  opts = {:prompt => '? '}.merge(opts)
  prompt_and_read_value prompt_message(message, opts), opts.merge(:ask => !Base.task.opt(:defaults)), &block
end

.log_choice_descriptions(descriptions) ⇒ Object


56
57
58
59
60
61
62
63
64
# File 'lib/babushka/prompt.rb', line 56

def log_choice_descriptions descriptions
  unless descriptions.nil?
    max_length = descriptions.keys.map(&:length).max
    LogHelpers.log "There are #{descriptions.length} choices:"
    descriptions.each_pair {|choice,description|
      LogHelpers.log "#{choice.ljust(max_length)} - #{description}"
    }
  end
end

.prompt_and_read_value(message, opts, &block) ⇒ Object


66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
# File 'lib/babushka/prompt.rb', line 66

def prompt_and_read_value message, opts, &block
  if !opts[:default] && !opts[:ask]
    raise DefaultUnavailable.new(message)
  elsif opts[:ask] && !STDIN.tty?
    raise PromptUnavailable.new(message)
  else
    log_choice_descriptions opts[:choice_descriptions]
    LogHelpers.log message, :newline => false

    if opts[:default] && !opts[:ask]
      puts '.'
      opts[:default]
    else
      read_value_from_prompt message, opts, &block
    end
  end
end

.prompt_message(message, opts) ⇒ Object


48
49
50
51
52
53
54
# File 'lib/babushka/prompt.rb', line 48

def prompt_message message, opts
  if opts[:choices] && opts[:choice_descriptions].nil?
    "#{message.chomp '?'} (#{opts[:choices] * ','})"
  else
    message.chomp '?'
  end + (opts[:default] ? " [#{opts[:default]}]" : '')
end

.read_value_from_prompt(message, opts, &block) ⇒ Object


84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
# File 'lib/babushka/prompt.rb', line 84

def read_value_from_prompt message, opts, &block
  value = nil

  value = read_from_prompt(opts[:prompt].end_with(' '), opts[:choices]).chomp
  value = opts[:default].to_s if value.empty? && !(opts[:default] && opts[:default].to_s.empty?)

  error = if opts[:choices] && !opts[:choices].include?(value)
    "That's not a valid choice"
  elsif block_given? && !yield(value)
    opts[:retry] || "That wasn't valid"
  elsif value.empty? && !(opts[:default] && opts[:default].empty?)
    "That was blank"
  elsif !opts[:confirmation] && %w[y yes].include?(value) && !confirm("Wait, do you mean the literal value '#{value}'?", :default => 'n')
    "Thought so :) Hit enter for the [default]"
  end

  if error
    LogHelpers.log "#{error.end_with('.')} #{message}", :newline => false
    read_value_from_prompt message, opts, &block
  else
    value
  end
end