class Blufin::Terminal

Constants

ERR_OUTPUT
MSG_AUTOMATIC
MSG_CUSTOM
MSG_CUSTOM_AUTO_PAD
MSG_ERROR
MSG_GENERATED
MSG_INFO
MSG_PROCESSED
MSG_PROGRESS
MSG_TODO
MSG_WARNING

Public Class Methods

abort(title = nil, message = nil, exit_script = true, preceding_blank_line = false) click to toggle source

Displays error and exits script by default. @return void

# File lib/core/terminal.rb, line 168
def self.abort(title = nil, message = nil, exit_script = true, preceding_blank_line = false)
    title   = 'Abandon ship!' if title.nil?
    message = "You have chosen to \x1B[38;5;196mABORT\x1B[38;5;240m the script." if message.nil?
    Blufin::Terminal::error(title, message, exit_script, preceding_blank_line, 'ABORT')
end
any_key_to_continue(text = nil, preceding_blank_line = true) click to toggle source

Gives a prompt where ANY KEY will continue executing the script. @return void @deprecated

# File lib/core/terminal.rb, line 539
def self.any_key_to_continue(text = nil, preceding_blank_line = true)
    STDOUT.flush
    puts if preceding_blank_line
    text = 'Press any key to continue' if text.nil?
    print "     \x1B[38;5;240m#{text}\x1B[0m => "
    STDIN.gets
    puts
    nil
end
arg_instructions(arg_descriptions, preceding_blank_line = true) click to toggle source

Displays warning message. @return void

# File lib/core/terminal.rb, line 217
def self.arg_instructions(arg_descriptions, preceding_blank_line = true)
    puts if preceding_blank_line
    puts "  \x1B[38;5;231m\x1B[48;5;22m Instructions \x1B[0m \xe2\x86\x92 This command expects the following arguments:\n"
    arg_descriptions_converted = []
    arg_descriptions.each_with_index { |x, idx| arg_descriptions_converted << "#{idx + 1}) \x1B[38;5;208m#{x}\x1B[0m" }
    parse_messages(arg_descriptions_converted)
end
automatic(title = nil, message = nil, preceding_blank_line = true) click to toggle source

Displays automatic message. @return void

# File lib/core/terminal.rb, line 185
def self.automatic(title = nil, message = nil, preceding_blank_line = true)
    puts if preceding_blank_line
    puts "\x1B[38;5;231m\x1B[48;5;96m Automatic \x1B[0m #{title.nil? ? '' : "\xe2\x86\x92 "}#{title}\n"
    parse_messages(message)
end
code_highlight(string, type, indent = 5) click to toggle source

Outputs code to terminal that is syntax highlighted. @return void

# File lib/core/terminal.rb, line 612
def self.code_highlight(string, type, indent = 5)
    raise RuntimeError, "Expected String, instead got:#{string.class}" unless string.is_a?(String)
    type  = type.downcase
    types = {
        'yml'  => Rouge::Lexers::YAML.new,
        'json' => Rouge::Lexers::JSON.new,
        'js'   => Rouge::Lexers::Javascript.new,
        'java' => Rouge::Lexers::Javascript.new,
        'sass' => Rouge::Lexers::Sass.new
    }
    raise RuntimeError, "Lexer not defined for type: #{type}" unless types.has_key?(type)
    repeat    = ' ' * indent
    formatter = Rouge::Formatters::Terminal256.new
    formatter.format(types[type].lex(string)).split("\n").each do |line|
        puts "#{repeat}#{line}"
    end
end
code_highlight_file(path_and_file, type, indent = 5) click to toggle source

Outputs code to terminal that is syntax highlighted. @return void

# File lib/core/terminal.rb, line 605
def self.code_highlight_file(path_and_file, type, indent = 5)
    raise RuntimeError, "File does not exist: #{path_and_file}" unless Blufin::Files::file_exists(path_and_file)
    code_highlight(File.read(path_and_file), type, indent)
end
command(commands, location = nil, verbose = true, verbose_cd = true, capture_real_output = false, pbl: false, tbl: false) click to toggle source

Runs a series of commands in the terminal. @return void

# File lib/core/terminal.rb, line 29
def self.command(commands, location = nil, verbose = true, verbose_cd = true, capture_real_output = false, pbl: false, tbl: false)
    unless commands.is_a?(Array)
        commands = [commands]
    end
    unless location.nil?
        unless File.directory?(File.expand_path(location))
            error('Directory not found.', "Cannot find the following directory: \x1B[38;5;205m#{location}\x1B[0m", true)
        end
    end
    output = []
    if verbose_cd && verbose && commands.any? && !location.nil?
        puts "\x1B[38;5;231m\x1B[48;5;22m Executing \x1B[0m \x1B[0m\xe2\x86\x92\x1B[0m #{Blufin::Terminal::format_command("cd #{location}")}\n"
    end
    if commands.any?
        commands.each do |command|
            if verbose
                puts "\x1B[38;5;231m\x1B[48;5;22m Executing \x1B[0m \x1B[0m\xe2\x86\x92\x1B[0m #{Blufin::Terminal::format_command("#{command}")}\n"
                puts if pbl
            end

            if location.nil?
                if capture_real_output
                    output << `#{command}`
                else
                    output << system("#{command}")
                end
            else
                if capture_real_output
                    output << `cd #{location} && #{command}`
                else
                    output << system("cd #{location} && #{command}")
                end
            end
        end
    end
    if capture_real_output
        output.map! { |v| v.gsub('\n', "\n") }
    end
    puts if tbl
    output
end
command_capture(commands, location = nil, verbose = true, verbose_cd = true) click to toggle source

Runs a series of commands in the terminal (and captures the output). @return void

# File lib/core/terminal.rb, line 73
def self.command_capture(commands, location = nil, verbose = true, verbose_cd = true)
    command(commands, location, verbose, verbose_cd, true)
end
custom(keyword = 'N/A', color = 1, title = nil, message = nil, preceding_blank_line = true) click to toggle source

Displays custom message (ideally, keyword should be 7 characters long to match the rest of the output). @return void

# File lib/core/terminal.rb, line 227
def self.custom(keyword = 'N/A', color = 1, title = nil, message = nil, preceding_blank_line = true)
    color = 55 if color.nil?
    puts if preceding_blank_line
    puts "  \x1B[38;5;231m\x1B[48;5;#{color}m #{keyword} \x1B[0m #{title.nil? ? '' : "\xe2\x86\x92 "}#{title}\n"
    parse_messages(message)
end
custom_progress(keyword = 'N/A', color = 1, title = nil, message = nil, preceding_blank_line = true) click to toggle source

Displays custom message with a progress indicator. @return void Deprecated

# File lib/core/terminal.rb, line 237
def self.custom_progress(keyword = 'N/A', color = 1, title = nil, message = nil, preceding_blank_line = true)
    puts if preceding_blank_line
    puts "  \x1B[38;5;231m\x1B[48;5;#{color}m #{keyword} \x1B[0m #{title.nil? ? '' : "\xe2\x86\x92 "}#{title}\n"
    parse_messages(message)
end
error(title = nil, message = nil, exit_script = true, preceding_blank_line = true, error_text = 'Error') click to toggle source

Displays error and exits script by default. @return void

# File lib/core/terminal.rb, line 176
def self.error(title = nil, message = nil, exit_script = true, preceding_blank_line = true, error_text = 'Error')
    puts if preceding_blank_line
    puts "    \x1B[38;5;231m\x1B[48;5;124m #{error_text} \x1B[0m #{title.nil? ? '' : "\xe2\x86\x92 "}#{title}\n"
    parse_messages(message)
    exit 1 if exit_script
end
execute(command, path = nil, capture: false, verbose: true, text: nil, error_output: ERR_OUTPUT, display_error: true, ignore_error: false) click to toggle source

Executes a command and shows that something is happening (via a cli-spinner). If capture: is false, returns TRUE:FALSE whether command was successful or not. If capture: is true, returns raw output of command. See: github.com/piotrmurach/tty-spinner/blob/master/lib/tty/spinner/formats.rb (for spinner options). @return idx-1 => Command was successful (exit code 0) will output TRUE if capture: FALSE or otherwise STDOUT will be returned, IE: 'On branch master' @return idx-2 => STDERR (if any), IE: anything written to /tmp/execute-output

# File lib/core/terminal.rb, line 83
def self.execute(command, path = nil, capture: false, verbose: true, text: nil, error_output: ERR_OUTPUT, display_error: true, ignore_error: false)
    text    = text.is_a?(String) ? text : command
    t1      = Time.now
    spinner = TTY::Spinner.new("[:spinner] \x1B[38;5;208m#{text}#{!path.nil? ? " \x1B[38;5;246m\xe2\x86\x92 \x1B[38;5;240m#{path}" : nil}\x1B[0m", format: :dots) if verbose
    spinner.auto_spin if verbose
    path = File.expand_path('~/') if path.nil?
    path = File.expand_path(path) unless path.nil?
    `echo '' > #{ERR_OUTPUT}`
    if capture
        res = `cd #{path} && #{command} 2>#{error_output}`
    else
        res = system("cd #{path} && #{command} 1>/dev/null 2>#{error_output}")
    end
    t2    = Time.now
    delta = "#{'%.3f' % (t2 - t1).abs}s"
    error = `cat #{ERR_OUTPUT}`.to_s.strip
    if (res && error.length == 0) || ignore_error
        spinner.success("\x1B[38;5;246m\xe2\x86\x92 \x1B[38;5;46mComplete \x1B[38;5;240m(#{delta})\x1B[0m\x1B[0m") if verbose
        res = true unless capture
    else
        spinner.error("\x1B[38;5;246m\xe2\x86\x92 \x1B[38;5;196mFailed (#{delta})\x1B[0m") if verbose
        # If there is an error, output it (even if verbose == false).
        if error.length > 0 && display_error
            puts "\x1B[38;5;240m"
            system("cat #{ERR_OUTPUT}")
            puts "\x1B[0m"
        end
        res = false unless capture
    end
    error = nil if error.nil? || error.strip == ''
    return res, error
end
execute_proc(title, proc, verbose: true, hide_progress: false) click to toggle source

Same as above but with a proc/lambda instead of a terminal command. @return void

# File lib/core/terminal.rb, line 118
def self.execute_proc(title, proc, verbose: true, hide_progress: false)
    raise RuntimeError, "Expected String, instead got:#{title.class}" unless title.is_a?(String)
    raise RuntimeError, "Expected proc to be an instance of Proc, instead got: #{proc.class}" unless proc.is_a?(Proc)
    t1      = Time.now
    spinner = nil
    spinner = TTY::Spinner.new("[:spinner] \x1B[38;5;208m#{title}\x1B[0m", format: :dots) if verbose
    spinner.auto_spin if verbose && !hide_progress
    res   = proc.call
    t2    = Time.now
    delta = "#{'%.3f' % (t2 - t1).abs}s"
    spinner.success("\x1B[38;5;246m\xe2\x86\x92 \x1B[38;5;46mComplete \x1B[38;5;240m(#{delta})\x1B[0m\x1B[0m") if verbose && res
    spinner.error("\x1B[38;5;246m\xe2\x86\x92 \x1B[38;5;196mFailed (#{delta})\x1B[0m") if verbose && !res
    res
end
fill(length = 0, string = ' ') click to toggle source

Generates 'filler' string. @return String

# File lib/core/terminal.rb, line 325
def self.fill(length = 0, string = ' ')
    fill_string = ''
    (0..length - 1).each {
        fill_string = "#{fill_string}#{string}"
    }
    fill_string
end
format_action(action_text, capitalize = true) click to toggle source

Returns action message in consistent, uniform manner. @return String

# File lib/core/terminal.rb, line 245
def self.format_action(action_text, capitalize = true)
    action_text = action_text.nil? ? 'N/A' : action_text
    action_text = action_text.to_s.upcase if capitalize
    "\x1B[38;5;170m#{action_text}\x1B[0m"
end
format_branch(branch_name) click to toggle source

Returns branch name in consistent, uniform manner. @return String

# File lib/core/terminal.rb, line 253
def self.format_branch(branch_name)
    "\x1B[38;5;40m[#{branch_name}]\x1B[0m"
end
format_command(command_name) click to toggle source

Returns command name in consistent, uniform manner. @return String

# File lib/core/terminal.rb, line 259
def self.format_command(command_name)
    "\x1B[38;5;70m$ \x1B[38;5;240m#{command_name}\x1B[0m"
end
format_directory(directory_name, expand_path = true) click to toggle source

Returns directory name in consistent, uniform manner. @return String

# File lib/core/terminal.rb, line 265
def self.format_directory(directory_name, expand_path = true)
    return "\x1B[38;5;48m#{File.expand_path(directory_name)}\x1B[0m" if expand_path
    return "\x1B[38;5;48m#{directory_name}\x1B[0m" unless expand_path
end
format_flag(flag_letter, display_flag_text = true) click to toggle source

Returns flag name in consistent, uniform manner. @return String

# File lib/core/terminal.rb, line 272
def self.format_flag(flag_letter, display_flag_text = true)
    if flag_letter.is_a? String
        letter_array = [flag_letter]
    elsif flag_letter.is_a? Array
        letter_array = flag_letter
    else
        raise RuntimeError, 'Terminal::format_flag expects either String or Array.'
    end
    flag_txt = ''
    letter_array.each do |letter|
        flag_txt = "#{flag_txt}, -#{letter}"
    end
    xtra_txt = letter_array.length > 1 ? ' flags' : ' flag'
    flag_txt = flag_txt[2..-1]
    "\x1B[38;5;177m#{flag_txt}#{display_flag_text ? xtra_txt : ''}\x1B[0m"
end
format_highlight(highlighted_text, capitalize = false, target: nil) click to toggle source

Returns action message in consistent, uniform manner. @return String

# File lib/core/terminal.rb, line 291
def self.format_highlight(highlighted_text, capitalize = false, target: nil)
    case target
        when 'cf' # CloudFormation
            color     = 82
            color_end = "\x1B[38;5;246m"
        when 'cf-ctt' # CloudFormation (Creation Time Title)
            color     = 196
            color_end = "\x1B[38;5;246m"
        when 'cf-ct' # CloudFormation (Creation Time)
            color     = 82
            color_end = "\x1B[38;5;246m"
        else
            color     = 117
            color_end = "\x1B[0m"
    end
    if capitalize
        return "\x1B[38;5;#{color}m#{highlighted_text.upcase}#{color_end}"
    else
        return "\x1B[38;5;#{color}m#{highlighted_text}#{color_end}"
    end
end
format_invalid(invalid_string, capitalize = false) click to toggle source

Returns invalid data in consistent, uniform manner. @return String

# File lib/core/terminal.rb, line 315
def self.format_invalid(invalid_string, capitalize = false)
    if capitalize
        return "\x1B[38;5;196m#{invalid_string.upcase}\x1B[0m"
    else
        return "\x1B[38;5;196m#{invalid_string}\x1B[0m"
    end
end
get_terminal_height() click to toggle source

Gets the Terminal height @return Integer

# File lib/core/terminal.rb, line 558
def self.get_terminal_height
    terminal_size = HighLine::SystemExtensions.terminal_size
    terminal_size[1]
end
get_terminal_width() click to toggle source

Gets the Terminal width @return Integer

# File lib/core/terminal.rb, line 551
def self.get_terminal_width
    terminal_size = HighLine::SystemExtensions.terminal_size
    terminal_size[0]
end
info(title = nil, message = nil, preceding_blank_line = true) click to toggle source

Displays info message. @return void

# File lib/core/terminal.rb, line 193
def self.info(title = nil, message = nil, preceding_blank_line = true)
    puts if preceding_blank_line
    puts "  \x1B[38;5;231m\x1B[48;5;240m Message \x1B[0m #{title.nil? ? '' : "\xe2\x86\x92 "}#{title}\n"
    parse_messages(message)
end
output(message = 'No message', type = MSG_INFO, title = nil, bg_color = nil) click to toggle source

Outputs messages to the terminal. If CUSTOM, title must be 11 characters to match existing scheme. @return void

# File lib/core/terminal.rb, line 136
def self.output(message = 'No message', type = MSG_INFO, title = nil, bg_color = nil)
    raise RuntimeError, "'title' cannot be nil." if title.nil? && [MSG_CUSTOM, MSG_CUSTOM_AUTO_PAD].include?(type)
    raise RuntimeError, "'bg_color' cannot be nil." if bg_color.nil? && [MSG_CUSTOM, MSG_CUSTOM_AUTO_PAD].include?(type)
    raise RuntimeError, "'title' cannot be more that 9 characerts when MSG_CUSTOM_AUTO_PAD is the message type." if type == MSG_CUSTOM_AUTO_PAD && title.length > 9
    case type
        when MSG_INFO
            puts "\x1B[38;5;231m\x1B[48;5;22m Executing \x1B[0m \x1B[0m\xe2\x86\x92\x1B[0m \x1B[0m#{message}\x1B[0m\n"
        when MSG_WARNING
            puts "\x1B[38;5;231m\x1B[48;5;202m  Warning  \x1B[0m \x1B[0m\xe2\x86\x92\x1B[0m \x1B[0m#{message}\x1B[0m\n"
        when MSG_ERROR
            puts "\x1B[38;5;231m\x1B[48;5;196m   Error   \x1B[0m \x1B[0m\xe2\x86\x92\x1B[0m \x1B[0m#{message}\x1B[0m\n"
        when MSG_TODO
            puts "\x1B[38;5;231m\x1B[48;5;199m   @TODO   \x1B[0m \x1B[0m\xe2\x86\x92\x1B[0m \x1B[0m#{message}\x1B[0m\n"
        when MSG_AUTOMATIC
            puts "\x1B[38;5;231m\x1B[48;5;92m Automatic \x1B[0m \x1B[0m\xe2\x86\x92\x1B[0m \x1B[0m#{message}\x1B[0m\n"
        when MSG_GENERATED
            puts "\x1B[38;5;231m\x1B[48;5;89m Generated \x1B[0m \x1B[0m\xe2\x86\x92\x1B[0m \x1B[0m#{message}\x1B[0m\n"
        when MSG_PROCESSED
            puts "\x1B[38;5;231m\x1B[48;5;238m Processed \x1B[0m \x1B[0m\xe2\x86\x92\x1B[0m \x1B[0m#{message}\x1B[0m\n"
        when MSG_PROGRESS
            puts "    \x1B[38;5;240m#{message}\x1B[0m\n"
        when MSG_CUSTOM
            puts "\x1B[38;5;231m\x1B[48;5;#{bg_color}m#{title}\x1B[0m \x1B[0m\xe2\x86\x92\x1B[0m \x1B[0m#{message}\x1B[0m\n"
        when MSG_CUSTOM_AUTO_PAD
            puts "\x1B[38;5;231m#{''.rjust((9 - title.length), ' ')}\x1B[48;5;#{bg_color}m #{title} \x1B[0m \x1B[0m\xe2\x86\x92\x1B[0m \x1B[0m#{message}\x1B[0m\n"
        else
            raise RuntimeError, "Invalid Terminal::output type: #{type}"
    end
end
print_exception(e) click to toggle source

Outputs Exceptions in a pretty, standardized format. @return void

print_files_written(array_of_paths_or_files, message = nil, limit = 10, preceding_blank_line = true) click to toggle source

Outputs Array of files/directories in a pretty, standardized format. @return void

prompt_ask(question, default: nil, help: nil, validation_regex: nil) click to toggle source

See: github.com/piotrmurach/tty-prompt#1-usage See: www.rubydoc.info/gems/tty-prompt

> What is your name? (Albert Rannetsperger)

@return string

# File lib/core/terminal.rb, line 391
def self.prompt_ask(question, default: nil, help: nil, validation_regex: nil)
    puts display_prompt_help(help) unless help.nil?
    prompt = TTY::Prompt.new
    prompt.ask(display_prompt_text(question), default: default) do |q|
        q.modify :strip
        q.validate validation_regex unless validation_regex.nil?
    end
end
prompt_enum_select(question, options) click to toggle source

Select an editor?

1) emacs
2) nano
3) vim
Choose 1-3 [1]:

@options = %w(emacs nano vim) @return Array

# File lib/core/terminal.rb, line 495
def self.prompt_enum_select(question, options)
    raise RuntimeError, "Expected Array, instead got #{options.class}" unless options.is_a?(Array)
    prompt = TTY::Prompt.new
    prompt.enum_select(display_prompt_text(question), options)
end
prompt_expand(question, options) click to toggle source

Overwrite Gemfile? (enter “h” for help) [y,n,a,d,q,h] @options = [

{ key: 'y', name: 'overwrite this file', value: :yes },
{ key: 'n', name: 'do not overwrite this file', value: :no },
{ key: 'a', name: 'overwrite this file and all later files', value: :all },
{ key: 'd', name: 'show diff', value: :diff },
{ key: 'q', name: 'quit; do not overwrite this file ', value: :quit }

] @return multiple

# File lib/core/terminal.rb, line 510
def self.prompt_expand(question, options)
    raise RuntimeError, "Expected Array, instead got #{options.class}" unless options.is_a?(Array)
    options.each do |option|
        found_key   = false
        found_name  = false
        found_value = false
        option.each do |k, v|
            case k
                when :key
                    found_key = true
                when :name
                    found_name = true
                when :value
                    found_value = true
                else
                    raise RuntimeError, "Unrecognized Key: #{k}"
            end
        end
        raise RuntimeError, "Option is missing #{Blufin::Terminal::format_highlight('key')}: #{option.inspect}" unless found_key
        raise RuntimeError, "Option is missing #{Blufin::Terminal::format_highlight('name')}: #{option.inspect}" unless found_name
        raise RuntimeError, "Option is missing #{Blufin::Terminal::format_highlight('value')}: #{option.inspect}" unless found_value
    end
    prompt = TTY::Prompt.new
    prompt.expand(display_prompt_text(question), options)
end
prompt_for_input(title = 'Input Required', message = nil, subtitle_array = nil, validation_proc = nil, validation_message = 'Invalid value', clear_screen = true, preceding_blank_line = true) click to toggle source

Shows a prompt waiting for user input. If validation_proc is passed, the Proc must return TRUE in order for validation to pass. @return string @deprecated

# File lib/core/terminal.rb, line 365
def self.prompt_for_input(title = 'Input Required', message = nil, subtitle_array = nil, validation_proc = nil, validation_message = 'Invalid value', clear_screen = true, preceding_blank_line = true)
    system('clear') if clear_screen
    puts if preceding_blank_line
    puts "  \x1B[38;5;231m\x1B[48;5;125m #{title.upcase} \x1B[0m \xe2\x86\x92 #{message} \x1B[38;5;240m\xe2\x80\x94 \x1B[38;5;160m(or 'X' to cancel)\x1B[0m\n"
    parse_messages(subtitle_array) unless subtitle_array.nil?
    puts if subtitle_array.nil?
    response = nil
    while response.nil?
        response = Readline::readline("     \x1B[38;5;245m=>\x1B[0m ", true)
        unless validation_proc.nil?
            raise RuntimeError, "Expected validation_proc to be an instance of Proc, instead got: #{validation_proc.class}" unless validation_proc.is_a?(Proc)
            unless response.upcase == 'X' || validation_proc.call(response)
                puts "     \x1B[38;5;245m=>\x1B[0m \x1B[38;5;196mERROR\x1B[0m \xe2\x80\x94 #{validation_message}\n"
                response = nil
            end
        end
    end
    abort if response.upcase == 'X'
    puts
    response
end
prompt_mask(question) click to toggle source

> What is your secret? ••••

@return string

# File lib/core/terminal.rb, line 413
def self.prompt_mask(question)
    prompt = TTY::Prompt.new
    prompt.mask(display_prompt_text(question))
end
prompt_multi_select(question, options, help: nil, per_page: 20, cycle: true) click to toggle source

Select drinks? (Use ↑/↓ arrow keys, press Space to select and Enter to finish)“ ‣ ⬡ vodka

 beer
 wine
 whisky
 bourbon

@options = %w(vodka beer wine whisky bourbon) @return Array

# File lib/core/terminal.rb, line 466
def self.prompt_multi_select(question, options, help: nil, per_page: 20, cycle: true)
    raise RuntimeError, "Expected Array, instead got #{options.class}" unless options.is_a?(Array)
    puts display_prompt_help(help) unless help.nil?
    prompt = TTY::Prompt.new
    if options[0].is_a?(String)
        prompt.multi_select(display_prompt_text(question), options, per_page: per_page, cycle: cycle)
    elsif options[0].is_a?(Hash)
        prompt.multi_select(display_prompt_text(question), options, per_page: per_page, cycle: cycle) do |menu|
            options.each do |option|
                raise RuntimeError, "Expected option to be Hash, instead got: (#{option.class}) #{option.inspect}" unless option.is_a?(Hash)
                raise RuntimeError, 'Option is missing key => :text' unless option.has_key?(:text)
                raise RuntimeError, 'Option is missing key => :value' unless option.has_key?(:value)
                raise RuntimeError, "Expected :disabled option to be String, instead got: #{option[:disabled].class}" if option.has_key?(:disabled) && !option[:disabled].is_a?(String) && !option[:disabled].nil?
                menu.choice option[:text], option[:value] unless option.has_key?(:disabled)
                menu.choice option[:text], option[:value], disabled: "\x1B[38;5;196m#{option[:disabled]}\x1B[0m" if option.has_key?(:disabled)
            end
        end
    else
        raise RuntimeError, "Expected options Array to consist of either Strings or Hashes, instead got: #{options.inspect}"
    end
end
prompt_select(question, options, help: nil, per_page: 20) click to toggle source

Choose your destiny? (Use ↑/↓ arrow keys, press Enter to select) ‣ Scorpion

Kano
Jax

@options = %w(Scorpion Kano Jax) @options = [{ :text => 'Description', :value => '1', :disabled => nil/'Reason' }] @return string

# File lib/core/terminal.rb, line 425
def self.prompt_select(question, options, help: nil, per_page: 20)
    raise RuntimeError, "Expected Array, instead got #{options.class}" unless options.is_a?(Array)
    raise RuntimeError, 'Array cannot be empty.' unless options.any?
    puts display_prompt_help(help) unless help.nil?
    prompt = TTY::Prompt.new
    if options[0].is_a?(String)
        prompt.select(display_prompt_text(question), options, per_page: per_page)
    elsif options[0].is_a?(Hash)
        options_fixed = []
        options.each do |option|
            raise RuntimeError, "Expected option to be Hash, instead got: (#{option.class}) #{option.inspect}" unless option.is_a?(Hash)
            raise RuntimeError, 'Option is missing key => :text' unless option.has_key?(:text)
            raise RuntimeError, 'Option is missing key => :value' unless option.has_key?(:value)
            raise RuntimeError, "Expected :disabled option to be String, instead got: #{option[:disabled].class}" if option.has_key?(:disabled) && !option[:disabled].is_a?(String) && !option[:disabled].nil?
            v = option[:value]
            v = 'true' if option[:value].is_a?(TrueClass)
            v = 'false' if option[:value].is_a?(FalseClass)
            options_fixed << {:text => option[:text], :value => v}
        end
        result = prompt.select(display_prompt_text(question), per_page: per_page) do |menu|
            options_fixed.each do |option|
                menu.choice option[:text], option[:value] unless option.has_key?(:disabled)
                menu.choice option[:text], option[:value], disabled: "\x1B[38;5;196m#{option[:disabled]}\x1B[0m" if option.has_key?(:disabled)
            end
        end
        return true if result == 'true'
        return false if result == 'false'
        return result
    else
        raise RuntimeError, "Expected options Array to consist of either Strings or Hashes, instead got: #{options.inspect}"
    end
end
prompt_yes?(question) click to toggle source

> Do you like Ruby? (Y/n)

@return boolean

# File lib/core/terminal.rb, line 402
def self.prompt_yes?(question)
    begin
        prompt = TTY::Prompt.new
        return prompt.yes?(display_prompt_text(question))
    rescue
        prompt_yes?(question)
    end
end
prompt_yes_no(title = nil, message = nil, confirmation_message = nil, preceding_blank_line = true) click to toggle source

Gives a prompt where 'y/Y' will return TRUE, 'n/N' will return false, and ANY other key will do nothing. @return void

# File lib/core/terminal.rb, line 335
def self.prompt_yes_no(title = nil, message = nil, confirmation_message = nil, preceding_blank_line = true)
    title                = 'Please confirm YES or NO.' if title.nil?
    confirmation_message = 'Would you like to continue?' if confirmation_message.nil?
    puts if preceding_blank_line
    puts "  \x1B[38;5;231m\x1B[48;5;55m Confirm \x1B[0m #{title.nil? ? '' : "\xe2\x86\x92 "}#{title}\n"
    parse_messages(message)
    response = ''
    until %w[y Y n N x X a A].include? response
        response = Readline::readline("     \x1B[38;5;161m#{confirmation_message} \x1B[0m[y/n]\x1B[90m => \x1B[0m", true)
    end
    case response.downcase
        when 'y'
            puts "\n"
            return true
        when 'n'
            puts "\n"
            return false
        when 'a'
            Blufin::Terminal::error('Abandon ship!', ["You have chosen to \x1B[38;5;196mABORT\x1B[38;5;240m the script.", nil, 'Please note that whenever you do this, any scripted tasks which were running', 'will have been interrupted mid-script. This may (or may not) cause problems.'], true)
        when 'x'
            Blufin::Terminal::error('Abandon ship!', ["You have chosen to \x1B[38;5;196mABORT\x1B[38;5;240m the script.", nil, 'Please note that whenever you do this, any scripted tasks which were running', 'will have been interrupted mid-script. This may (or may not) cause problems.'], true)
        else
            raise RuntimeError, "Un-handled response: #{response.downcase}"
    end
end
success(title = nil, message = nil, preceding_blank_line = true) click to toggle source

Displays success message. @return void

# File lib/core/terminal.rb, line 201
def self.success(title = nil, message = nil, preceding_blank_line = true)
    puts if preceding_blank_line
    puts "  \x1B[38;5;231m\x1B[48;5;22m Success \x1B[0m #{title.nil? ? '' : "\xe2\x86\x92 "}#{title}\n"
    parse_messages(message)
end
warning(title = nil, message = nil, preceding_blank_line = true) click to toggle source

Displays warning message. @return void

# File lib/core/terminal.rb, line 209
def self.warning(title = nil, message = nil, preceding_blank_line = true)
    puts if preceding_blank_line
    puts "  \x1B[38;5;231m\x1B[48;5;130m Warning \x1B[0m #{title.nil? ? '' : "\xe2\x86\x92 "}#{title}\n"
    parse_messages(message)
end

Private Class Methods

display_prompt_help(help) click to toggle source

Standardized way of displaying prompts help. @return string

# File lib/core/terminal.rb, line 652
def self.display_prompt_help(help)
    "\x1B[38;5;240m#{help}\x1B[0m"
end
display_prompt_text(question, answer = nil) click to toggle source

Standardized way of displaying prompts text. @return string

# File lib/core/terminal.rb, line 658
def self.display_prompt_text(question, answer = nil)
    return "\x1B[38;5;208m#{question}\x1B[38;5;240m =>\x1B[0m" if answer.nil?
    return "\x1B[38;5;208m#{question}\x1B[38;5;240m => \x1B[38;5;46m#{answer}\x1B[0m" unless answer.nil?
end
parse_messages(message) click to toggle source

Parses messages for various output functions. @return void

# File lib/core/terminal.rb, line 634
def self.parse_messages(message)
    puts
    unless message.nil?
        if message.is_a?(Array)
            messages = message
        else
            messages = message.split("\n")
        end
        messages.each do |line|
            new_line = line.nil? ? '' : line.to_s.gsub("\x1B[0m", "\x1B[38;5;240m")
            puts "     \x1B[38;5;240m#{new_line}\x1B[0m"
        end
        puts
    end
end