Module: MrMurano::Verbose

Overview

Verbose is a mixin for various terminal output features.

Constant Summary collapse

TABULARIZE_DATA_FORMAT_ERROR =

Output tabular data

data

Data to write. Preferably a Hash with :headers and :rows

ios

Output stream to write to, if nil, then use $stdout

Output is either a nice visual table or CSV.

'Unexpected data format: do not know how to tabularize.'

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.ask_yes_no(question, default) ⇒ Object



255
256
257
258
259
260
261
262
263
264
265
266
# File 'lib/MrMurano/verbosing.rb', line 255

def self.ask_yes_no(question, default)
  answer = default
  whirly_interject do
    confirm = ask(question)
    if default
      answer = !%w[n no].include?(confirm.downcase)
    else
      answer = %w[y ye yes].include?(confirm.downcase)
    end
  end
  answer
end

.assert(condition, msg = '') ⇒ Object



60
61
62
63
64
65
# File 'lib/MrMurano/verbosing.rb', line 60

def self.assert(condition, msg='')
  return if condition
  msg = "Assertion raised! #{caller(1..1)}\n" + msg
  whirly_interject { warn(HighLine.color(msg, :red)) }
  raise msg
end

.cmd_confirm_delete!(name, auto_yes, exit_msg) ⇒ Object



272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
# File 'lib/MrMurano/verbosing.rb', line 272

def self.cmd_confirm_delete!(name, auto_yes, exit_msg)
  if auto_yes
    yield true if block_given?
    return true
  end
  confirmed = MrMurano::Verbose.ask_yes_no(
    "Really delete #{MrMurano::Verbose.fancy_ticks(name)}? [y/N] ", false
  )
  MrMurano::Verbose.warning(exit_msg) if !confirmed && exit_msg
  if block_given?
    yield confirmed
  elsif !confirmed
    exit 1
  end
  confirmed
end

.debug(msg) ⇒ Object



35
36
37
# File 'lib/MrMurano/verbosing.rb', line 35

def self.debug(msg)
  whirly_interject { say msg } if $cfg['tool.debug']
end

.dump_file_json(obj, outf, pretty: false) ⇒ Object



232
233
234
235
236
237
238
# File 'lib/MrMurano/verbosing.rb', line 232

def self.dump_file_json(obj, outf, pretty: false)
  if pretty
    outf.write(JSON.pretty_generate(obj))
  else
    JSON.dump(obj, outf)
  end
end

.dump_file_plain(obj, outf) ⇒ Object



244
245
246
# File 'lib/MrMurano/verbosing.rb', line 244

def self.dump_file_plain(obj, outf)
  outf.write(obj)
end

.dump_file_yaml(obj, outf) ⇒ Object



240
241
242
# File 'lib/MrMurano/verbosing.rb', line 240

def self.dump_file_yaml(obj, outf)
  YAML.dump(obj, outf)
end

.error(msg) ⇒ Object



51
52
53
54
# File 'lib/MrMurano/verbosing.rb', line 51

def self.error(msg)
  # See also Commander::say_error
  whirly_interject { warn(HighLine.color(msg, :red)) }
end

.fancy_ticks(obj) ⇒ Object



301
302
303
304
305
306
307
# File 'lib/MrMurano/verbosing.rb', line 301

def self.fancy_ticks(obj)
  if $cfg.nil? || $cfg['tool.ascii'] || OS.windows?
    "'#{obj}'"
  else
    "‘#{obj}’"
  end
end

.outf(obj, ios = nil, pretty: false) ⇒ Object

Format and print the object Handles many of the raw ‘unpolished’ formats.



130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'lib/MrMurano/verbosing.rb', line 130

def self.outf(obj, ios=nil, pretty: false)
  fmt = $cfg['tool.outformat']
  ios = $stdout if ios.nil?
  case fmt
  when /yaml/i
    ios.puts Hash.transform_keys_to_strings(obj).to_yaml
  when /pp/
    pp obj
  when /json/i
    if pretty
      ios.puts JSON.pretty_generate(obj)
    else
      ios.puts obj.to_json
    end
  else # aka best.
    # sometime ‘best’ is only know by the caller, so block.
    if block_given?
      yield obj, ios
    elsif obj.is_a?(Array)
      obj.each { |i| ios.puts i.to_s }
    else
      ios.puts obj.to_s
    end
  end
end

.pluralize?(word, count) ⇒ Boolean

Returns:

  • (Boolean)


293
294
295
# File 'lib/MrMurano/verbosing.rb', line 293

def self.pluralize?(word, count)
  count == 1 && word || Inflecto.pluralize(word)
end

.tabularize(data, ios = nil, no_quotes: false) ⇒ Object



78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/MrMurano/verbosing.rb', line 78

def self.tabularize(data, ios=nil, no_quotes: false)
  fmt = $cfg['tool.outformat']
  ios = $stdout if ios.nil?
  cols = nil
  rows = nil
  title = nil
  if data.is_a?(Hash)
    cols = data[:headers] if data.key?(:headers)
    rows = data[:rows] if data.key?(:rows)
    title = data[:title]
  elsif data.is_a?(Array)
    rows = data
  elsif data.respond_to?(:to_a)
    rows = data.to_a
  elsif data.respond_to?(:each)
    rows = []
    # MAYBE/2017-07-02: Does shover operator work on frozen string literals?
    data.each { |i| rows << i }
  else
    error TABULARIZE_DATA_FORMAT_ERROR
    return
  end
  if fmt =~ /csv/i
    cols = [] if cols.nil?
    rows = [[]] if rows.nil?
    CSV(
      ios,
      headers: cols,
      write_headers: !cols.empty?,
      force_quotes: !no_quotes,
    ) do |csv|
      # MAYBE/2017-07-02: Does shover operator work on frozen string literals?
      rows.each { |v| csv << v }
    end
  else
    # table.
    table = Terminal::Table.new
    table.title = title unless title.nil?
    table.headings = cols unless cols.nil?
    table.rows = rows unless rows.nil?
    ios.puts table
  end
end

.verbose(msg) ⇒ Object



27
28
29
# File 'lib/MrMurano/verbosing.rb', line 27

def self.verbose(msg)
  whirly_interject { say msg } if $cfg['tool.verbose']
end

.warning(msg) ⇒ Object



43
44
45
# File 'lib/MrMurano/verbosing.rb', line 43

def self.warning(msg)
  whirly_interject { warn(HighLine.color(msg, :yellow)) }
end

.whirly_interject(&block) ⇒ Object



369
370
371
# File 'lib/MrMurano/verbosing.rb', line 369

def self.whirly_interject(&block)
  MrMurano::Progress.instance.whirly_interject(&block)
end

.whirly_lingerObject



353
354
355
# File 'lib/MrMurano/verbosing.rb', line 353

def self.whirly_linger
  MrMurano::Progress.instance.whirly_linger
end

.whirly_msg(msg) ⇒ Object



357
358
359
# File 'lib/MrMurano/verbosing.rb', line 357

def self.whirly_msg(msg)
  MrMurano::Progress.instance.whirly_msg(msg)
end

.whirly_pauseObject



361
362
363
# File 'lib/MrMurano/verbosing.rb', line 361

def self.whirly_pause
  MrMurano::Progress.instance.whirly_pause
end

.whirly_start(msg) ⇒ Object



345
346
347
# File 'lib/MrMurano/verbosing.rb', line 345

def self.whirly_start(msg)
  MrMurano::Progress.instance.whirly_start(msg)
end

.whirly_stop(force: false) ⇒ Object



349
350
351
# File 'lib/MrMurano/verbosing.rb', line 349

def self.whirly_stop(force: false)
  MrMurano::Progress.instance.whirly_stop(force: force)
end

.whirly_unpauseObject



365
366
367
# File 'lib/MrMurano/verbosing.rb', line 365

def self.whirly_unpause
  MrMurano::Progress.instance.whirly_unpause
end

Instance Method Details

#ask_yes_no(question, default) ⇒ Object



268
269
270
# File 'lib/MrMurano/verbosing.rb', line 268

def ask_yes_no(question, default)
  MrMurano::Verbose.ask_yes_no(question, default)
end

#assert(condition, msg = '') ⇒ Object



56
57
58
# File 'lib/MrMurano/verbosing.rb', line 56

def assert(condition, msg='')
  MrMurano::Verbose.assert(condition, msg)
end

#cmd_confirm_delete!(name, auto_yes, exit_msg) ⇒ Object



289
290
291
# File 'lib/MrMurano/verbosing.rb', line 289

def cmd_confirm_delete!(name, auto_yes, exit_msg)
  MrMurano::Verbose.cmd_confirm_delete!(name, auto_yes, exit_msg)
end

#debug(msg) ⇒ Object



31
32
33
# File 'lib/MrMurano/verbosing.rb', line 31

def debug(msg)
  MrMurano::Verbose.debug(msg)
end

#dump_output_file(obj, outf, fmt, **opts) ⇒ Object



218
219
220
221
222
223
224
225
226
227
228
229
230
# File 'lib/MrMurano/verbosing.rb', line 218

def dump_output_file(obj, outf, fmt, **opts)
  case fmt
  when :json
    MrMurano::Verbose.dump_file_json(obj, outf, **opts)
  when :yaml
    MrMurano::Verbose.dump_file_yaml(obj, outf)
  when :plain
    MrMurano::Verbose.dump_file_plain(obj, outf)
  else
    error_file_format!(fmt)
  end
  outf.flush
end

#error(msg) ⇒ Object



47
48
49
# File 'lib/MrMurano/verbosing.rb', line 47

def error(msg)
  MrMurano::Verbose.error(msg)
end

#error_file_format!(fmt) ⇒ Object



248
249
250
251
252
253
# File 'lib/MrMurano/verbosing.rb', line 248

def error_file_format!(fmt)
  pfmt = fancy_ticks(fmt)
  error %(Specified format is not a valid format: #{pfmt})
  error %(Try one of: --json, or --yaml)
  exit 2
end

#fancy_ticks(obj) ⇒ Object



309
310
311
# File 'lib/MrMurano/verbosing.rb', line 309

def fancy_ticks(obj)
  MrMurano::Verbose.fancy_ticks(obj)
end

#load_file_json(inpf) ⇒ Object



198
199
200
201
202
# File 'lib/MrMurano/verbosing.rb', line 198

def load_file_json(inpf)
  # (lb) Why doesn't rubocop like JSON.load(inpf)? Whatever.
  #   NOPE: JSON.load(inpf)
  JSON.parse(inpf.read)
end

#load_file_plain(inpf) ⇒ Object



214
215
216
# File 'lib/MrMurano/verbosing.rb', line 214

def load_file_plain(inpf)
  inpf.read
end

#load_file_yaml(inpf) ⇒ Object



204
205
206
207
208
209
210
211
212
# File 'lib/MrMurano/verbosing.rb', line 204

def load_file_yaml(inpf)
  begin
    path = inpf.path
  rescue NoMethodError
    path = inpf.to_s
  end
  # The @data is false if the file exists but is empty.
  YAML.load_file(path) || {}
end

#load_input_file(inpf, fmt) ⇒ Object



185
186
187
188
189
190
191
192
193
194
195
196
# File 'lib/MrMurano/verbosing.rb', line 185

def load_input_file(inpf, fmt)
  case fmt
  when :json
    load_file_json(inpf)
  when :yaml
    load_file_yaml(inpf)
  when :plain
    load_file_plain(inpf)
  else
    error_file_format!(fmt)
  end
end

#outf(obj, ios = nil, pretty: false, &block) ⇒ Object



156
157
158
# File 'lib/MrMurano/verbosing.rb', line 156

def outf(obj, ios=nil, pretty: false, &block)
  MrMurano::Verbose.outf(obj, ios, pretty: pretty, &block)
end

#outformat_engine(fext) ⇒ Object



170
171
172
173
174
175
176
177
178
179
180
181
182
183
# File 'lib/MrMurano/verbosing.rb', line 170

def outformat_engine(fext)
  case fext
  when /\.?csv$/i
    :csv
  when /\.?json$/i
    :json
  when /\.?ya?ml$/i
    :yaml
  when /\.?te?xt$/i
    :plain
  else
    :json
  end
end

#pluralize?(word, count) ⇒ Boolean

Returns:

  • (Boolean)


297
298
299
# File 'lib/MrMurano/verbosing.rb', line 297

def pluralize?(word, count)
  MrMurano::Verbose.pluralize?(word, count)
end

#prepare_hash_csv(elem) ⇒ Object



122
123
124
125
126
# File 'lib/MrMurano/verbosing.rb', line 122

def prepare_hash_csv(elem)
  headers = elem.keys
  row_lkup = [elem.values]
  [headers, row_lkup]
end

#read_hashf!(path, fmt = nil) ⇒ Object



160
161
162
163
164
165
166
167
168
# File 'lib/MrMurano/verbosing.rb', line 160

def read_hashf!(path, fmt=nil)
  fmt = outformat_engine(path.extname.downcase) if fmt.nil?
  load_input_file(path, fmt)
rescue StandardError => err
  type = fancy_ticks(fmt)
  warning %(Could not load input file of type #{type} at: #{path})
  error err.message
  exit 2
end

#tabularize(data, ios = nil) ⇒ Object



74
75
76
# File 'lib/MrMurano/verbosing.rb', line 74

def tabularize(data, ios=nil)
  MrMurano::Verbose.tabularize(data, ios)
end

#verbose(msg) ⇒ Object



23
24
25
# File 'lib/MrMurano/verbosing.rb', line 23

def verbose(msg)
  MrMurano::Verbose.verbose(msg)
end

#warning(msg) ⇒ Object



39
40
41
# File 'lib/MrMurano/verbosing.rb', line 39

def warning(msg)
  MrMurano::Verbose.warning(msg)
end

#whirly_interject(&block) ⇒ Object



341
342
343
# File 'lib/MrMurano/verbosing.rb', line 341

def whirly_interject(&block)
  MrMurano::Progress.instance.whirly_interject(&block)
end

#whirly_lingerObject



325
326
327
# File 'lib/MrMurano/verbosing.rb', line 325

def whirly_linger
  MrMurano::Progress.instance.whirly_linger
end

#whirly_msg(msg) ⇒ Object



329
330
331
# File 'lib/MrMurano/verbosing.rb', line 329

def whirly_msg(msg)
  MrMurano::Progress.instance.whirly_msg(msg)
end

#whirly_pauseObject



333
334
335
# File 'lib/MrMurano/verbosing.rb', line 333

def whirly_pause
  MrMurano::Progress.instance.whirly_pause
end

#whirly_start(msg) ⇒ Object

2017-07-01: Whirly wrappers. Maybe delete someday

(after replacing all MrMurano::Verbose.whirly_*
with MrMurano::Progress.whirly_*).


317
318
319
# File 'lib/MrMurano/verbosing.rb', line 317

def whirly_start(msg)
  MrMurano::Progress.instance.whirly_start(msg)
end

#whirly_stop(force: false) ⇒ Object



321
322
323
# File 'lib/MrMurano/verbosing.rb', line 321

def whirly_stop(force: false)
  MrMurano::Progress.instance.whirly_stop(force: force)
end

#whirly_unpauseObject



337
338
339
# File 'lib/MrMurano/verbosing.rb', line 337

def whirly_unpause
  MrMurano::Progress.instance.whirly_unpause
end