Module: MetaModel::UserInterface

Extended by:
Config::Mixin
Defined in:
lib/metamodel/user_interface.rb

Overview

The code in this file is mainly borrowed from cocoapods/user_interface.rb which used to generate output messages to user.

Class Attribute Summary collapse

Basic methods collapse

Class Method Summary collapse

Methods included from Config::Mixin

config

Class Attribute Details

.disable_wrapBool Also known as: disable_wrap?

Returns Whether the wrapping of the strings to the width of the terminal should be disabled.

Returns:

  • (Bool)

    Whether the wrapping of the strings to the width of the terminal should be disabled.



27
28
29
# File 'lib/metamodel/user_interface.rb', line 27

def disable_wrap
  @disable_wrap
end

.indentation_levelObject

Returns the value of attribute indentation_level.



16
17
18
# File 'lib/metamodel/user_interface.rb', line 16

def indentation_level
  @indentation_level
end

.output_ioIO

Returns IO object to which UI output will be directed.

Returns:

  • (IO)

    IO object to which UI output will be directed.



22
23
24
# File 'lib/metamodel/user_interface.rb', line 22

def output_io
  @output_io
end

.title_levelObject

Returns the value of attribute title_level.



17
18
19
# File 'lib/metamodel/user_interface.rb', line 17

def title_level
  @title_level
end

.warningsObject

Returns the value of attribute warnings.



18
19
20
# File 'lib/metamodel/user_interface.rb', line 18

def warnings
  @warnings
end

Class Method Details

.choose_from_array(array, message) ⇒ Fixnum

Presents a choice among the elements of an array to the user.

Parameters:

  • array (Array<#to_s>)

    The list of the elements among which the user should make his choice.

  • message (String)

    The message to display to the user.

Returns:

  • (Fixnum)

    The index of the chosen array item.



301
302
303
304
305
306
307
308
309
310
311
312
313
314
# File 'lib/metamodel/user_interface.rb', line 301

def choose_from_array(array, message)
  array.each_with_index do |item, index|
    UI.puts "#{index + 1}: #{item}"
  end

  UI.puts message

  index = UI.gets.chomp.to_i - 1
  if index < 0 || index > array.count - 1
    raise Informative, "#{index + 1} is invalid [1-#{array.count}]"
  else
    index
  end
end

.getsObject

gets input from $stdin



349
350
351
# File 'lib/metamodel/user_interface.rb', line 349

def gets
  $stdin.gets
end

.info(message) ⇒ Object

Prints an info to the user. The info is always displayed. It respects the current indentation level only in verbose mode.

Any title printed in the optional block is treated as a message.

Parameters:

  • message (String)

    The message to print.



151
152
153
154
155
156
157
158
159
160
161
# File 'lib/metamodel/user_interface.rb', line 151

def info(message)
  indentation = config.verbose? ? self.indentation_level : 0
  indented = wrap_string(message, indentation)
  puts(indented)

  self.indentation_level += 2
  @treat_titles_as_messages = true
  yield if block_given?
  @treat_titles_as_messages = false
  self.indentation_level -= 2
end

.labeled(label, value, justification = 12) ⇒ Object

Prints a message with a label.

Parameters:

  • label (String)

    The label to print.

  • value (#to_s)

    The value to print.

  • justification (FixNum) (defaults to: 12)

    The justification of the label.



246
247
248
249
250
251
252
253
254
255
256
257
258
259
# File 'lib/metamodel/user_interface.rb', line 246

def labeled(label, value, justification = 12)
  if value
    title = "- #{label}:"
    if value.is_a?(Array)
      lines = [wrap_string(title, self.indentation_level)]
      value.each do |v|
        lines << wrap_string("- #{v}", self.indentation_level + 2)
      end
      puts lines.join("\n")
    else
      puts wrap_string(title.ljust(justification) + "#{value}", self.indentation_level)
    end
  end
end

.message(message, verbose_prefix = '', relative_indentation = 2) ⇒ Object

TODO:

Clean interface.

Prints a verbose message taking an optional verbose prefix and a relative indentation valid for the UI action in the passed block.

Parameters:

  • message (String)

    The message to print.

  • verbose_prefix (String) (defaults to: '')

    See #message

  • relative_indentation (FixNum) (defaults to: 2)

    The indentation level relative to the current, when the message is printed.



133
134
135
136
137
138
139
140
# File 'lib/metamodel/user_interface.rb', line 133

def message(message, verbose_prefix = '', relative_indentation = 2)
  message = verbose_prefix + message if config.verbose?
  puts_indented message if config.verbose?

  self.indentation_level += relative_indentation
  yield if block_given?
  self.indentation_level -= relative_indentation
end

.notice(message) ⇒ Object

Prints an important message to the user.

return [void]

Parameters:

  • message (String)

    The message to print.



169
170
171
# File 'lib/metamodel/user_interface.rb', line 169

def notice(message)
  puts("\n[!] #{message}".green)
end

.path(pathname) ⇒ Object

Returns a string containing relative location of a path from the Podfile. The returned path is quoted. If the argument is nil it returns the empty string.

Parameters:

  • pathname (#to_str)

    The path to print.



180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/metamodel/user_interface.rb', line 180

def path(pathname)
  if pathname
    from_path = config.podfile_path.dirname if config.podfile_path
    from_path ||= Pathname.pwd
    path = begin
             Pathname(pathname).relative_path_from(from_path)
           rescue
             pathname
           end
    "`#{path}`"
  else
    ''
  end
end

.pod(set, mode = :normal) ⇒ Object

Prints the textual representation of a given set.

Parameters:

  • set (Set)

    the set that should be presented.

  • mode (Symbol) (defaults to: :normal)

    the presentation mode, either ‘:normal` or `:name_and_version`.



203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
# File 'lib/metamodel/user_interface.rb', line 203

def pod(set, mode = :normal)
  if mode == :name_and_version
    puts_indented "#{set.name} #{set.versions.first.version}"
  else
    pod = Specification::Set::Presenter.new(set)
    title = "-> #{pod.name} (#{pod.version})"
    if pod.spec.deprecated?
      title += " #{pod.deprecation_description}"
      colored_title = title.red
    else
      colored_title = title.green
    end

    title(colored_title, '', 1) do
      puts_indented pod.summary if pod.summary
      puts_indented "pod '#{pod.name}', '~> #{pod.version}'"
      labeled('Homepage', pod.homepage)
      labeled('Source',   pod.source_url)
      labeled('Versions', pod.versions_by_source)
      if mode == :stats
        labeled('Authors',  pod.authors) if pod.authors =~ /,/
        labeled('Author',   pod.authors) if pod.authors !~ /,/
        labeled('License',  pod.license)
        labeled('Platform', pod.platform)
        labeled('Stars',    pod.github_stargazers)
        labeled('Forks',    pod.github_forks)
      end
      labeled('Subspecs', pod.subspecs)
    end
  end
end

prints a message followed by a new line.

Parameters:

  • message (String)

    The message to print.



339
340
341
342
343
344
345
# File 'lib/metamodel/user_interface.rb', line 339

def print(message)
  begin
    (output_io || STDOUT).print(message)
  rescue Errno::EPIPE
    exit 0
  end
end

This method returns an undefined value.

Prints the stored warnings. This method is intended to be called at the end of the execution of the binary.



277
278
279
280
281
282
283
284
285
286
287
288
# File 'lib/metamodel/user_interface.rb', line 277

def print_warnings
  STDOUT.flush
  warnings.each do |warning|
    next if warning[:verbose_only] && !config.verbose?
    STDERR.puts("\n[!] #{warning[:message]}".yellow)
    warning[:actions].each do |action|
      string = "- #{action}"
      string = wrap_string(string, 4)
      puts(string)
    end
  end
end

.puts(message = '') ⇒ Object

prints a message followed by a new line.

Parameters:

  • message (String) (defaults to: '')

    The message to print.



326
327
328
329
330
331
332
# File 'lib/metamodel/user_interface.rb', line 326

def puts(message = '')
  begin
    (output_io || STDOUT).puts(message)
  rescue Errno::EPIPE
    exit 0
  end
end

.puts_indented(message = '') ⇒ Object

Prints a message respecting the current indentation level and wrapping it to the terminal width if necessary.

Parameters:

  • message (String) (defaults to: '')

    The message to print.



267
268
269
270
# File 'lib/metamodel/user_interface.rb', line 267

def puts_indented(message = '')
  indented = wrap_string(message, self.indentation_level)
  puts(indented)
end

.section(title, verbose_prefix = '', relative_indentation = 0) ⇒ Object

TODO:

Refactor to title (for always visible titles like search) and sections (titles that represent collapsible sections).

Prints a title taking an optional verbose prefix and a relative indentation valid for the UI action in the passed block.

In verbose mode titles are printed with a color according to their level. In normal mode titles are printed only if they have nesting level smaller than 2.

Parameters:

  • title (String)

    The title to print

  • verbose_prefix (String) (defaults to: '')

    See #message

  • relative_indentation (FixNum) (defaults to: 0)

    The indentation level relative to the current, when the message is printed.



51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/metamodel/user_interface.rb', line 51

def section(title, verbose_prefix = '', relative_indentation = 0)
  if config.verbose?
    title(title, verbose_prefix, relative_indentation)
  elsif title_level < 1
    puts title
  end

  self.indentation_level += relative_indentation
  self.title_level += 1
  yield if block_given?
  self.indentation_level -= relative_indentation
  self.title_level -= 1
end

.title(title, verbose_prefix = '', relative_indentation = 2) ⇒ Object

A title opposed to a section is always visible

Parameters:

  • title (String)

    The title to print

  • verbose_prefix (String) (defaults to: '')

    See #message

  • relative_indentation (FixNum) (defaults to: 2)

    The indentation level relative to the current, when the message is printed.



98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
# File 'lib/metamodel/user_interface.rb', line 98

def title(title, verbose_prefix = '', relative_indentation = 2)
  if @treat_titles_as_messages
    message(title, verbose_prefix)
  else
    title = verbose_prefix + title if config.verbose?
    title = "\n#{title}" if @title_level < 2
    if (color = @title_colors[@title_level])
      title = title.send(color)
    end
    puts "#{title}"
  end

  self.indentation_level += relative_indentation
  self.title_level += 1
  yield if block_given?
  self.indentation_level -= relative_indentation
  self.title_level -= 1
end

.titled_section(title, options = {}) ⇒ void

This method returns an undefined value.

In verbose mode it shows the sections and the contents. In normal mode it just prints the title.



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/metamodel/user_interface.rb', line 70

def titled_section(title, options = {})
  relative_indentation = options[:relative_indentation] || 0
  verbose_prefix = options[:verbose_prefix] || ''
  if config.verbose?
    title(title, verbose_prefix, relative_indentation)
  else
    puts title
  end

  self.indentation_level += relative_indentation
  self.title_level += 1
  yield if block_given?
  self.indentation_level -= relative_indentation
  self.title_level -= 1
end

.warn(message, actions = [], verbose_only = false) ⇒ Object

Stores important warning to the user optionally followed by actions that the user should take. To print them use #print_warnings.

return [void]

Parameters:

  • message (String)

    The message to print.

  • actions (Array) (defaults to: [])

    The actions that the user should take.

  • verbose_only (Bool) (defaults to: false)

    Restrict the appearance of the warning to verbose mode only



363
364
365
# File 'lib/metamodel/user_interface.rb', line 363

def warn(message, actions = [], verbose_only = false)
  warnings << { :message => message, :actions => actions, :verbose_only => verbose_only }
end

.with_pager { ... } ⇒ Object

Pipes all output inside given block to a pager.

Yields:

  • Code block in which inputs to #puts and #print methods will be printed to the piper.



371
372
373
374
375
376
377
378
379
380
# File 'lib/metamodel/user_interface.rb', line 371

def with_pager
  prev_handler = Signal.trap('INT', 'IGNORE')
  IO.popen((ENV['PAGER'] || 'less -R'), 'w') do |io|
    UI.output_io = io
    yield
  end
ensure
  Signal.trap('INT', prev_handler)
  UI.output_io = nil
end