Class: Planter::Prompt::Question

Inherits:
Object
  • Object
show all
Defined in:
lib/planter/prompt.rb

Overview

Class to prompt for answers

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(question) ⇒ Question

Initializes the given question.

Parameters:

  • question (Hash)

    The question with key, prompt, and type, optionally default, min and max



18
19
20
21
22
23
24
25
26
27
# File 'lib/planter/prompt.rb', line 18

def initialize(question)
  @key = question[:key].to_var
  @type = question[:type].normalize_type
  @min = question[:min]&.to_f || 1.0
  @max = question[:max]&.to_f || 10.0
  @prompt = question[:prompt] || nil
  @default = question[:default]
  @value = question[:value]
  @gum = false # TTY::Which.exist?('gum')
end

Instance Attribute Details

#conditionObject (readonly)

Returns the value of attribute condition.



8
9
10
# File 'lib/planter/prompt.rb', line 8

def condition
  @condition
end

#defaultObject (readonly)

Returns the value of attribute default.



8
9
10
# File 'lib/planter/prompt.rb', line 8

def default
  @default
end

#gumObject (readonly)

Returns the value of attribute gum.



8
9
10
# File 'lib/planter/prompt.rb', line 8

def gum
  @gum
end

#keyObject (readonly)

Returns the value of attribute key.



8
9
10
# File 'lib/planter/prompt.rb', line 8

def key
  @key
end

#maxObject (readonly)

Returns the value of attribute max.



8
9
10
# File 'lib/planter/prompt.rb', line 8

def max
  @max
end

#minObject (readonly)

Returns the value of attribute min.



8
9
10
# File 'lib/planter/prompt.rb', line 8

def min
  @min
end

#promptObject (readonly)

Returns the value of attribute prompt.



8
9
10
# File 'lib/planter/prompt.rb', line 8

def prompt
  @prompt
end

#typeObject (readonly)

Returns the value of attribute type.



8
9
10
# File 'lib/planter/prompt.rb', line 8

def type
  @type
end

Instance Method Details

#askNumber, String

Ask the question, prompting for input based on type

Returns:

  • (Number, String)

    the response based on @type



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
# File 'lib/planter/prompt.rb', line 34

def ask
  return nil if @prompt.nil?

  return @value.to_s.apply_variables.apply_regexes.coerce(@type) if @value && @type != :date

  res = case @type
        when :integer
          read_number(integer: true)
        when :float
          read_number
        when :date
          if @value
            date_default
          else
            read_date
          end
        when :class || :module
          read_line.to_class_name
        when :multiline
          read_lines
        else
          read_line
        end
  Planter.notify("{dw}#{prompt}: {dy}#{res}{x}", :debug)
  res
rescue TTY::Reader::InputInterrupt
  raise Errors::InputError('Canceled')
end

#date_defaultString (private)

Parse a date value into a date string

Returns:



91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/planter/prompt.rb', line 91

def date_default
  default = @value || @default
  return nil unless default

  case default
  when /^(no|ti)/
    Time.now.strftime('%Y-%m-%d %H:%M')
  when /^(to|da)/
    Time.now.strftime('%Y-%m-%d')
  when /^%/
    Time.now.strftime(@default)
  else
    Chronic.parse(default).strftime('%Y-%m-%d')
  end
end

#read_date(prompt: nil) ⇒ Date (private)

Accept a date string on the command line

Parameters:

  • prompt (String) (defaults to: nil)

    The prompt

Returns:

  • (Date)

    Parsed Date object



114
115
116
117
118
119
120
121
122
123
124
# File 'lib/planter/prompt.rb', line 114

def read_date(prompt: nil)
  prompt ||= @prompt
  default = date_default

  default = default ? " {bw}[#{default}]" : ''
  Planter.notify("{by}#{prompt} (natural language)#{default}")
  line = @gum ? read_line_gum : read_line_tty
  return default unless line

  Chronic.parse(line).strftime('%Y-%m-%d')
end

#read_line(prompt: nil) ⇒ String (private)

Reads a line.

Parameters:

  • prompt (String) (defaults to: nil)

    If not nil, will trigger asking for a secondary response until a blank entry is given

Returns:

  • (String)

    the single-line response



135
136
137
138
139
140
141
142
143
144
145
# File 'lib/planter/prompt.rb', line 135

def read_line(prompt: nil)
  prompt ||= @prompt
  default = @default ? " {bw}[#{@default}]" : ''
  Planter.notify("{by}#{prompt}#{default}")

  res = @gum ? read_line_gum : read_line_tty

  return @default unless res

  res
end

#read_line_gumString (private)

Read a single line entry using gum

Returns:

  • (String)

    String response



199
200
201
202
203
204
205
# File 'lib/planter/prompt.rb', line 199

def read_line_gum
  trap('SIGINT') { exit! }
  res = `gum input --placeholder "(blank to use default)"`.strip
  return nil if res.empty?

  res
end

#read_line_ttyString (private)

Read a single line entry using TTY::Reader

Returns:

  • (String)

    String response



185
186
187
188
189
190
191
192
# File 'lib/planter/prompt.rb', line 185

def read_line_tty
  trap('SIGINT') { exit! }
  reader = TTY::Reader.new
  res = reader.read_line('>> ').strip
  return nil if res.empty?

  res
end

#read_lines(prompt: nil) ⇒ String (private)

Reads multiple lines.

Parameters:

  • prompt (String) (defaults to: nil)

    if not nil, will trigger asking for a secondary response until a blank entry is given

Returns:

  • (String)

    the multi-line response



156
157
158
159
160
161
162
163
164
165
# File 'lib/planter/prompt.rb', line 156

def read_lines(prompt: nil)
  prompt ||= @prompt
  save = @gum ? 'Ctrl-J for newline, Enter' : 'Ctrl-D'
  Planter.notify("{by}#{prompt} {xc}({bw}#{save}{xc} to save)'")
  res = @gum ? read_multiline_gum(prompt) : read_mutliline_tty

  return @default unless res

  res.strip
end

#read_multiline_gum(prompt) ⇒ string (private)

Read a multiline entry using gum

Returns:

  • (string)

    multiline input



224
225
226
227
228
# File 'lib/planter/prompt.rb', line 224

def read_multiline_gum(prompt)
  trap('SIGINT') { exit! }
  width = TTY::Screen.cols > 80 ? 80 : TTY::Screen.cols
  `gum write --placeholder "#{prompt}" --width #{width} --char-limit 0`.strip
end

#read_mutliline_ttystring (private)

Read a multiline entry using TTY::Reader

Returns:

  • (string)

    multiline input



212
213
214
215
216
217
# File 'lib/planter/prompt.rb', line 212

def read_mutliline_tty
  trap('SIGINT') { exit! }
  reader = TTY::Reader.new
  res = reader.read_multiline
  res.join("\n").strip
end

#read_number(integer: false) ⇒ Number (private)

Read a numeric entry using gum or TTY::Reader

Parameters:

  • integer (Boolean) (defaults to: false)

    Round result to nearest integer

Returns:

  • (Number)

    numeric response



72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/planter/prompt.rb', line 72

def read_number(integer: false)
  default = @default ? " {bw}[#{@default}]" : ''
  Planter.notify("{by}#{@prompt} {xc}({bw}#{@min}{xc}-{bw}#{@max}{xc})#{default}")

  res = @gum ? read_number_gum : read_line_tty

  return @default unless res

  res = integer ? res.to_f.round : res.to_f

  res = read_number if res < @min || res > @max
  res
end

#read_number_gumString (private)

Read a numeric entry using gum

Returns:

  • (String)

    String response



172
173
174
175
176
177
178
# File 'lib/planter/prompt.rb', line 172

def read_number_gum
  trap('SIGINT') { exit! }
  res = `gum input --placeholder "#{@min}-#{@max}"`.strip
  return nil if res.strip.empty?

  res
end