# class Bundler::Thor::Shell::Basic

### Constants

DEFAULT_TERMINAL_WIDTH

### Attributes

base[RW]
padding[R]

### Public Instance Methods

ask(statement, *args) click to toggle source

Asks something to the user and receives a response.

If a default value is specified it will be presented to the user and allows them to select that value with an empty response. This option is ignored when limited answers are supplied.

If asked to limit the correct responses, you can pass in an array of acceptable answers. If one of those is not supplied, they will be shown a message stating that one of those answers must be given and re-asked the question.

If asking for sensitive information, the :echo option can be set to false to mask user input from $stdin.

If the required input is a path, then set the path option to true. This will enable tab completion for file paths relative to the current working directory on systems that support `Readline`.

#### Example¶ ↑

ask(“What is your name?”)

ask(“What is the planet furthest from the sun?”, :default => “Pluto”)

ask(“What is your favorite Neopolitan flavor?”, :limited_to => [“strawberry”, “chocolate”, “vanilla”])

ask(“What is your password?”, :echo => false)

ask(“Where should the file be saved?”, :path => true)

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 78
    def ask(statement, *args)
      options = args.last.is_a?(Hash) ? args.pop : {}
      color = args.first

      if options[:limited_to]
        ask_filtered(statement, color, options)
      else
        ask_simply(statement, color, options)
      end
    end

error(statement) click to toggle source

Called if something goes wrong during the execution. This is used by Bundler::Thor internally and should not be used inside your scripts. If something went wrong, you can always raise an exception. If you raise a Bundler::Thor::Error, it will be rescued and wrapped in the method below.

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 321
    def error(statement)
      stderr.puts statement
    end

file_collision(destination) { || ... } click to toggle source

Deals with file collision and returns true if the file should be overwritten and false otherwise. If a block is given, it uses the block response as the content for the diff.

#### Parameters¶ ↑

destination<String>

  the destination file to solve conflicts

block<Proc>

  an optional block that returns the value to be used in diff and merge

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 264
    def file_collision(destination)
      return true if @always_force
      options = block_given? ? "[Ynaqdhm]" : "[Ynaqh]"

      loop do
        answer = ask(
          %[Overwrite #{destination}? (enter "h" for help) #{options}],
          :add_to_history => false
        )

        case answer
        when nil
          say ""
          return true
        when is?(:yes), is?(:force), ""
          return true
        when is?(:no), is?(:skip)
          return false
        when is?(:always)
          return @always_force = true
        when is?(:quit)
          say "Aborting..."
          raise SystemExit
        when is?(:diff)
          show_diff(destination, yield) if block_given?
          say "Retrying..."
        when is?(:merge)
          if block_given? && !merge_tool.empty?
            merge(destination, yield)
            return nil
          end

          say "Please specify merge tool to `THOR_MERGE` env."
        else
          say file_collision_help
        end
      end
    end

indent(count = 1) { || ... } click to toggle source

Sets the output padding while executing a block and resets it.

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 41
    def indent(count = 1)
      orig_padding = padding
      self.padding = padding + count
      yield
      self.padding = orig_padding
    end

mute() { || ... } click to toggle source

Mute everything that's inside given block

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 20
    def mute
      @mute = true
      yield
    ensure
      @mute = false
    end

mute?() click to toggle source

Check if base is muted

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 29
    def mute?
      @mute
    end

no?(statement, color = nil) click to toggle source

Make a question the to user and returns true if the user replies “n” or “no”.

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 134
    def no?(statement, color = nil)
      !!(ask(statement, color, :add_to_history => false) =~ is?(:no))
    end

padding=(value) click to toggle source

Sets the output padding, not allowing less than zero values.

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 35
    def padding=(value)
      @padding = [0, value].max
    end

print_in_columns(array) click to toggle source

Prints values in columns

#### Parameters¶ ↑

Array[String, `String`, …]

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 143
    def print_in_columns(array)
      return if array.empty?
      colwidth = (array.map { |el| el.to_s.size }.max || 0) + 2
      array.each_with_index do |value, index|
        # Don't output trailing spaces when printing the last column
        if ((((index + 1) % (terminal_width / colwidth))).zero? && !index.zero?) || index + 1 == array.length
          stdout.puts value
        else
          stdout.printf("%-#{colwidth}s", value)
        end
      end
    end

print_table(array, options = {}) click to toggle source

Prints a table.

#### Parameters¶ ↑

Array[Array[String, `String`, …]]

#### Options¶ ↑

indent<Integer>

  Indent the first column by indent value.

colwidth<Integer>

  Force the first column to colwidth spaces wide.

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 165
    def print_table(array, options = {}) # rubocop:disable MethodLength
      return if array.empty?

      formats = []
      indent = options[:indent].to_i
      colwidth = options[:colwidth]
      options[:truncate] = terminal_width if options[:truncate] == true

      formats << "%-#{colwidth + 2}s".dup if colwidth
      start = colwidth ? 1 : 0

      colcount = array.max { |a, b| a.size <=> b.size }.size

      maximas = []

      start.upto(colcount - 1) do |index|
        maxima = array.map { |row| row[index] ? row[index].to_s.size : 0 }.max
        maximas << maxima
        formats << if index == colcount - 1
                     # Don't output 2 trailing spaces when printing the last column
                     "%-s".dup
                   else
                     "%-#{maxima + 2}s".dup
                   end
      end

      formats[0] = formats[0].insert(0, " " * indent)
      formats << "%s"

      array.each do |row|
        sentence = "".dup

        row.each_with_index do |column, index|
          maxima = maximas[index]

          f = if column.is_a?(Numeric)
            if index == row.size - 1
              # Don't output 2 trailing spaces when printing the last column
              "%#{maxima}s"
            else
              "%#{maxima}s  "
            end
          else
            formats[index]
          end
          sentence << f % column.to_s
        end

        sentence = truncate(sentence, options[:truncate]) if options[:truncate]
        stdout.puts sentence
      end
    end

print_wrapped(message, options = {}) click to toggle source

Prints a long string, word-wrapping the text to the current width of the terminal display. Ideal for printing heredocs.

#### Parameters¶ ↑

`String`

#### Options¶ ↑

indent<Integer>

  Indent each line of the printed paragraph by indent value.

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 227
    def print_wrapped(message, options = {})
      indent = options[:indent] || 0
      width = terminal_width - indent
      paras = message.split("\n\n")

      paras.map! do |unwrapped|
        counter = 0
        unwrapped.split(" ").inject do |memo, word|
          word = word.gsub(/\n\005/, "\n").gsub(/\005/, "\n")
          counter = 0 if word.include? "\n"
          if (counter + word.length + 1) < width
            memo = "#{memo} #{word}"
            counter += (word.length + 1)
          else
            memo = "#{memo}\n#{word}"
            counter = word.length
          end
          memo
        end
      end.compact!

      paras.each do |para|
        para.split("\n").each do |line|
          stdout.puts line.insert(0, " " * indent)
        end
        stdout.puts unless para == paras.last
      end
    end

say(message = "", color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/)) click to toggle source

Say (print) something to the user. If the sentence ends with a whitespace or tab character, a new line is not appended (print + flush). Otherwise are passed straight to puts (behavior got from Highline).

#### Example¶ ↑

say(“I know you knew that.”)

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 96
    def say(message = "", color = nil, force_new_line = (message.to_s !~ /( |\t)\Z/))
      buffer = prepare_message(message, *color)
      buffer << "\n" if force_new_line && !message.to_s.end_with?("\n")

      stdout.print(buffer)
      stdout.flush
    end

say_status(status, message, log_status = true) click to toggle source

Say a status with the given color and appends the message. Since this method is used frequently by actions, it allows nil or false to be given in log_status, avoiding the message from being shown. If a `Symbol` is given in log_status, it's used as the color.

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 109
    def say_status(status, message, log_status = true)
      return if quiet? || log_status == false
      spaces = "  " * (padding + 1)
      color  = log_status.is_a?(Symbol) ? log_status : :green

      status = status.to_s.rjust(12)
      status = set_color status, color, true if color

      buffer = "#{status}#{spaces}#{message}"
      buffer = "#{buffer}\n" unless buffer.end_with?("\n")

      stdout.print(buffer)
      stdout.flush
    end

terminal_width() click to toggle source

This code was copied from Rake, available under MIT-LICENSE Copyright © 2003, 2004 Jim Weirich

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 305
    def terminal_width
      result = if ENV["THOR_COLUMNS"]
        ENV["THOR_COLUMNS"].to_i
      else
        unix? ? dynamic_width : DEFAULT_TERMINAL_WIDTH
      end
      result < 10 ? DEFAULT_TERMINAL_WIDTH : result
    rescue
      DEFAULT_TERMINAL_WIDTH
    end

yes?(statement, color = nil) click to toggle source

Make a question the to user and returns true if the user replies “y” or “yes”.

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 127
    def yes?(statement, color = nil)
      !!(ask(statement, color, :add_to_history => false) =~ is?(:yes))
    end

### Protected Instance Methods

answer_match(possibilities, answer, case_insensitive) click to toggle source

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 465
    def answer_match(possibilities, answer, case_insensitive)
      if case_insensitive
        possibilities.detect{ |possibility| possibility.downcase == answer.downcase }
      else
        possibilities.detect{ |possibility| possibility == answer }
      end
    end

as_unicode() { || ... } click to toggle source

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 422
    def as_unicode
      yield
    end

ask_filtered(statement, color, options) click to toggle source

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 452
    def ask_filtered(statement, color, options)
      answer_set = options[:limited_to]
      case_insensitive = options.fetch(:case_insensitive, false)
      correct_answer = nil
      until correct_answer
        answers = answer_set.join(", ")
        answer = ask_simply("#{statement} [#{answers}]", color, options)
        correct_answer = answer_match(answer_set, answer, case_insensitive)
        say("Your response must be one of: [#{answers}]. Please try again.") unless correct_answer
      end
      correct_answer
    end

ask_simply(statement, color, options) click to toggle source

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 435
    def ask_simply(statement, color, options)
      default = options[:default]
      message = [statement, ("(#{default})" if default), nil].uniq.join(" ")
      message = prepare_message(message, *color)
      result = Bundler::Thor::LineEditor.readline(message, options)

      return unless result

      result = result.strip

      if default && result == ""
        default
      else
        result
      end
    end

can_display_colors?() click to toggle source

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 339
    def can_display_colors?
      false
    end

dynamic_width() click to toggle source

Calculate the dynamic width of the terminal

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 394
    def dynamic_width
      @dynamic_width ||= (dynamic_width_stty.nonzero? || dynamic_width_tput)
    end

dynamic_width_stty() click to toggle source

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 398
    def dynamic_width_stty
      `stty size 2>/dev/null`.split[1].to_i
    end

dynamic_width_tput() click to toggle source

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 402
    def dynamic_width_tput
      `tput cols 2>/dev/null`.to_i
    end

lookup_color(color) click to toggle source

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 343
    def lookup_color(color)
      return color unless color.is_a?(Symbol)
      self.class.const_get(color.to_s.upcase)
    end

prepare_message(message, *color) click to toggle source

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 334
    def prepare_message(message, *color)
      spaces = "  " * padding
      spaces + set_color(message.to_s, *color)
    end

stderr() click to toggle source

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 352
    def stderr
      $stderr
    end

stdout() click to toggle source

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 348
    def stdout
      $stdout
    end

truncate(string, width) click to toggle source

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 410
    def truncate(string, width)
      as_unicode do
        chars = string.chars.to_a
        if chars.length <= width
          chars.join
        else
          chars[0, width - 3].join + "..."
        end
      end
    end

unix?() click to toggle source

    # File lib/bundler/vendor/thor/lib/thor/shell/basic.rb, line 406
    def unix?
      RUBY_PLATFORM =~ /(aix|darwin|linux|(net|free|open)bsd|cygwin|solaris|irix|hpux)/i
    end