class DTK::Client::Shell::InteractiveWizard

Constants

INVALID_INPUT
PP_LINE
PP_LINE_HEAD
PromptResponse

response_type can be

:value_provided
:skipped

Public Class Methods

interactive_user_input(wizard_dsl, recursion_call = false) click to toggle source

InteractiveWizard.interactive_user_input is generic wizard which will return hash map based on metadata input

Example of form of param 'wizard_params'

wizard_params = [

{:target_name     => {}},
{:description     => {:optional => true }}
{:iaas_type       => { :type => :selection, :options => [:ec2] }},
{:aws_install    => { :type => :question,
                      :question => "Do we have your permission to add necessery 'key-pair' and 'security-group' to your EC2 account?",
                      :options => ["yes","no"],
                      :required_options => ["yes"],
                      :explanation => "This permission is necessary for creation of a custom target."
                    }}

]

# File lib/shell/interactive_wizard.rb, line 49
def self.interactive_user_input(wizard_dsl, recursion_call = false)
  results = {}
  wizard_dsl = [wizard_dsl].flatten
  begin
    wizard_dsl.each do |meta_input|
      input_name = meta_input.keys.first
      display_name = input_name.to_s.gsub(/_/,' ').capitalize
      metadata = meta_input.values.first

      # default values
      output = display_name
      validation = metadata[:validation]
      is_password = false
      is_required = metadata[:requried]

      case metadata[:type]
        when nil
        when :email
          validation = /\A([^@\s]+)@((?:[-a-z0-9]+\.)+[a-z]{2,})\z/i
        when :question
          output = "#{metadata[:question]}"
          validation = metadata[:validation]
        when :password
          is_password = true
          is_required = true
        when :repeat_password
          is_password = true
          is_required = true
          validation  = /^#{results[:password]}$/
        when :selection
          options = ""
          display_field = metadata[:display_field]
          metadata[:options].each_with_index do |o,i|
            if display_field
              options += "\t#{i+1}. #{o[display_field]}\n"
            else
              options += "\t#{i+1}. #{o}\n"
            end
          end
          options += OsUtil.colorize("\t0. Skip\n", :yellow) if metadata[:skip_option]
          output = "Select '#{display_name}': \n\n #{options} \n "
          validation_range_start = metadata[:skip_option] ? 0 : 1
          validation = (validation_range_start..metadata[:options].size).to_a
        when :group
          # recursion call to populate second level of hash params
          puts " Enter '#{display_name}': "
          results[input_name] = self.interactive_user_input(metadata[:options], true)
          next
      end

      input = text_input(output, is_required, validation, is_password)

      if metadata[:required_options] && !metadata[:required_options].include?(input)
        # case where we have to give explicit permission, if answer is not affirmative
        # we terminate rest of the wizard
        OsUtil.print(" #{metadata[:explanation]}", :red)
        return nil
      end

      # post processing
      if metadata[:type] == :selection
        input = input.to_i == 0 ? nil : metadata[:options][input.to_i - 1]
      end

      results[input_name] = input
    end

    return results
  rescue Interrupt => e
    puts
    raise DtkValidationError, "Exiting the wizard ..."
  end
end
new() click to toggle source
# File lib/shell/interactive_wizard.rb, line 30
def initialize
end
prompt_user_for_value(prompt_msg) click to toggle source
# File lib/shell/interactive_wizard.rb, line 143
def self.prompt_user_for_value(prompt_msg)
  value = nil
  puts "#{prompt_msg}:"
  begin 
    value = Readline.readline(": ", true)
    response_type = :value_provided
   rescue Interrupt 
    response_type = :skipped
  end
  PromptResponse.new(response_type, value)
end
resolve_missing_params(param_list, additional_message = nil) click to toggle source

takes hash maps with description of missing params and returns array of hash map with key, value for each missed param

# File lib/shell/interactive_wizard.rb, line 157
def self.resolve_missing_params(param_list, additional_message = nil)
  begin
    user_provided_params, checkup_hash = [], {}

    puts "\nPlease fill in missing data.\n"
    param_list.each do |param_info|
      description =
        if param_info['display_name'] =~ Regexp.new(param_info['description'])
          param_info['display_name']
        else
          "#{param_info['display_name']} (#{param_info['description']})"
        end
      datatype_info = (param_info['datatype'] ? OsUtil.colorize(" [#{param_info['datatype'].upcase}]", :yellow) : '')
      string_identifier = OsUtil.colorize(description, :green) + datatype_info

      puts "Please enter #{string_identifier}:"
      while line = Readline.readline(": ", true)
        id = param_info['id']
        user_provided_params << {:id => id, :value => line, :display_name => param_info['display_name']}
        checkup_hash[id] = {:value => line, :description => description}
        break
      end

    end

    # pp print for provided parameters
    pretty_print_provided_user_info(checkup_hash)

    # make sure this is satisfactory
    while line = Readline.readline("Is provided information ok? (yes|no) ", true)
      # start all over again
      return resolve_missing_params(param_list) if 'no'.eql? line
      # continue with the code
      break if 'yes'.eql? line
    end

   rescue Interrupt => e
    raise DtkError::InteractiveWizardError, "You have decided to skip correction wizard.#{additional_message}"
  end

  return user_provided_params
end
text_input(output, is_required = false, validation_regex = nil, is_password = false) click to toggle source
# File lib/shell/interactive_wizard.rb, line 123
def self.text_input(output, is_required = false, validation_regex = nil, is_password = false)
  while line = ask("#{output}: ") { |q| q.echo = !is_password }
    if is_required && line.strip.empty?
      puts OsUtil.colorize("Field '#{output}' is required field. ", :red)
      next
    end

    if validation_regex && !validation_regex.match(line)
      puts OsUtil.colorize("Input is not valid, please enter it again. ", :red)
      next
    end

    return line
  end
end

Private Class Methods

pretty_print_provided_user_info(user_information) click to toggle source
# File lib/shell/interactive_wizard.rb, line 202
def self.pretty_print_provided_user_info(user_information)
  puts PP_LINE_HEAD
  user_information.each do |key,info|
    description = info[:description]
    value = info[:value]
    printf "%48s : %s\n", OsUtil.colorize(description, :green), OsUtil.colorize(value, :yellow)
  end
  puts PP_LINE
  puts
end