module MetaModel::UserInterface
The code in this file is mainly borrowed from cocoapods/user_interface.rb which used to generate output messages to user.
Attributes
@return [Bool] Whether the wrapping of the strings to the width of the
terminal should be disabled.
@return [Bool] Whether the wrapping of the strings to the width of the
terminal should be disabled.
@return [IO] IO object to which UI
output will be directed.
Public Class Methods
Presents a choice among the elements of an array to the user.
@param [Array<#to_s>] array
The list of the elements among which the user should make his choice.
@param [String] message
The message to display to the user.
@return [Fixnum] The index of the chosen array item.
# 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
gets input from $stdin
# File lib/metamodel/user_interface.rb, line 349 def gets $stdin.gets end
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.
@param [String] message
The message to print.
# 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
Prints a message with a label.
@param [String] label
The label to print.
@param [#to_s] value
The value to print.
@param [FixNum] justification
The justification of the label.
# 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
Prints a verbose message taking an optional verbose prefix and a relative indentation valid for the UI
action in the passed block.
@todo Clean interface.
@param [String] message
The message to print.
@param [String] verbose_prefix
See #message
@param [FixNum] relative_indentation
The indentation level relative to the current, when the message is printed.
# 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
Prints an important message to the user.
@param [String] message The message to print.
return [void]
# File lib/metamodel/user_interface.rb, line 169 def notice(message) puts("\n[!] #{message}".green) end
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.
@param [#to_str] pathname
The path to print.
# 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
Prints the textual representation of a given set.
@param [Set] set
the set that should be presented.
@param [Symbol] mode
the presentation mode, either `:normal` or `:name_and_version`.
# 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.
@param [String] message
The message to print.
# File lib/metamodel/user_interface.rb, line 339 def print(message) begin (output_io || STDOUT).print(message) rescue Errno::EPIPE exit 0 end end
Prints the stored warnings. This method is intended to be called at the end of the execution of the binary.
@return [void]
# 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
prints a message followed by a new line.
@param [String] message
The message to print.
# File lib/metamodel/user_interface.rb, line 326 def puts(message = '') begin (output_io || STDOUT).puts(message) rescue Errno::EPIPE exit 0 end end
Prints a message respecting the current indentation level and wrapping it to the terminal width if necessary.
@param [String] message
The message to print.
# File lib/metamodel/user_interface.rb, line 267 def puts_indented(message = '') indented = wrap_string(message, self.indentation_level) puts(indented) end
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.
@todo Refactor to title (for always visible titles like search)
and sections (titles that represent collapsible sections).
@param [String] title
The title to print
@param [String] verbose_prefix
See #message
@param [FixNum] relative_indentation
The indentation level relative to the current, when the message is printed.
# 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
A title opposed to a section is always visible
@param [String] title
The title to print
@param [String] verbose_prefix
See #message
@param [FixNum] relative_indentation
The indentation level relative to the current, when the message is printed.
# 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
In verbose mode it shows the sections and the contents. In normal mode it just prints the title.
@return [void]
# 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
Stores important warning to the user optionally followed by actions that the user should take. To print them use {#print_warnings}.
@param [String] message The message to print. @param [Array] actions The actions that the user should take. @param [Bool] verbose_only
Restrict the appearance of the warning to verbose mode only
return [void]
# 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
Pipes all output inside given block to a pager.
@yield Code block in which inputs to {#puts} and {#print} methods will be printed to the piper.
# 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
Private Class Methods
@return [String] Wraps a string taking into account the width of the terminal and an option indent. Adapted from blog.macromates.com/2006/wrapping-text-with-regular-expressions/
@param [String] txt The string to wrap
@param [String] indent The string to use to indent the result.
@return [String] The formatted string.
@note If MetaModel
is not being run in a terminal or the width of the terminal is too small a width of 80 is assumed.
# File lib/metamodel/user_interface.rb, line 400 def wrap_string(string, indent = 0) if disable_wrap (' ' * indent) + string else first_space = ' ' * indent indented = CLAide::Command::Banner::TextWrapper.wrap_with_indent(string, indent, 9999) first_space + indented end end