module CliHelper

Constants

DEFAULTS

Public Instance Methods

abort_if_errors() click to toggle source

Display global warnings and errors arrays and exit if necessary

# File lib/cli_helper.rb, line 369
def abort_if_errors
  unless configatron.warnings.empty?
    STDERR.puts
    STDERR.puts "The following warnings were generated:"
    STDERR.puts
    configatron.warnings.each do |w|
      STDERR.puts "\tWarning: #{w}"
    end
    STDERR.print "\nAbort program? (y/N) "
    answer = (STDIN.gets).chomp.strip.downcase
    configatron.errors << "Aborted by user" if answer.size>0 && 'y' == answer[0]
    configatron.warnings = []
  end
  unless configatron.errors.empty?
    STDERR.puts
    STDERR.puts "Correct the following errors and try again:"
    STDERR.puts
    configatron.errors.each do |e|
      STDERR.puts "\t#{e}"
    end
    STDERR.puts
    exit(-1)
  end
end
cli_helper( my_banner='', slop_options_config={} ) { |param| ... } click to toggle source

Invoke Slop with common CLI parameters and custom parameters provided via a block. Create '?' for all boolean parameters that have a '–name' flag form. Returns a Slop::Options object

# File lib/cli_helper.rb, line 198
def cli_helper( my_banner='',
                slop_options_config={}
              )
  default_config  = { suppress_errors: configatron.suppress_errors }
  options_hash    = default_config.merge(slop_options_config)

  param = Slop::Options.new( **options_hash )

  if my_banner.empty?
    param.banner = "Usage: #{my_name} [options] ..."
  else
    param.banner = my_banner
    param.separator "\nUsage: #{my_name} [options] ..."
  end

  param.separator "\nWhere:"

  if  configatron.disable_help      &&
      configatron.disable_verbose   &&
      configatron.disable_debug     &&
      configatron.disable_version
    # NOOP
  else
    param.separator "\n  Common Options Are:"
  end

  unless configatron.disable_help
    param.bool '-h', '--help',    'show this message'
  end

  unless configatron.disable_verbose
    param.bool '-v', '--verbose', 'enable verbose mode'
  end

  unless configatron.disable_debug
    param.bool '-d', '--debug',   'enable debug mode'
  end

  unless configatron.disable_version
    param.on '--version', "print the version: #{configatron.version}" do
      puts configatron.version
      exit
    end
  end

  param.separator "\n  Program Options Are:"

  yield(param) if block_given?

  if configatron.enable_config_files
    param.paths '--config',    'read config file(s) [*.rb, *.yml, *.ini, *.erb]'
  end

  parser = Slop::Parser.new(param, suppress_errors: configatron.suppress_errors)

  configatron.cli = parser.parse(ARGV)

  # Lets do some error checking ...
  configatron.cli.options.options.each do |opt|
    if opt.count > 1
      warning "#{opt.desc} #{opt.flags.inspect} entered more than once; only last value is used"
    end
    if opt.value.nil?
      if opt.config.default.nil?
        # NOTE: why is this a warning and not an error?
        #       while it may be required, it might be set in a config file
        #       so we let the user decide to continue or abort.
        # SMELL: see below, past the loading of the config file values.
        warning "Required parameter is missing: #{opt.desc} #{opt.flags.inspect}"
      end
    end
  end

  unless configatron.cli.arguments.empty?
    bad_options = configatron.cli.arguments.select {|o| o.start_with?('-')}
    unless bad_options.empty?
      error "Invalid parameters: #{bad_options.inspect}"
      bad_options.each do |o|
        x = configatron.cli.arguments.index(o)
        configatron.cli.arguments[x] = nil
      end
      configatron.cli.arguments.compact!
    end
  end


  # NOTE: The config files are being process before the
  #       command line options in order for the command
  #       line options to over-write the values from the
  #       config files.
  if configatron.enable_config_files
    configatron.cli[:config].each do |cf|
      cli_helper_process_config_file(cf)
    end # configatron.cli.config.each do |cf|
  end # if configatron.enable_config_files

  # SMELL: a required parameter that is not entered on the command line
  #        will have a value of nil.  IF THAT parameter had been
  #        set in a config file, this will overlay the valid value
  #        with an invalid nil.
  configatron.configure_from_hash(configatron.cli.to_hash)
  configatron.arguments = configatron.cli.arguments

  bools = param.options.select do |o|
    o.is_a? Slop::BoolOption
  end.select{|o| o.flags.select{|f|f.start_with?('--')}}.
      map{|o| o.flags.last.gsub('--','')} # SMELL: depends on convention

  bools.each do |m|
    s = m.to_sym
    define_method(m+'?') do
      configatron[s]
    end unless self.respond_to?(m+'?')
    define_method((m+'!').to_sym) do
      configatron[s] = true
    end unless self.respond_to?(m+'!')
  end


  if self.respond_to?(:help?) && help?
    show_usage
    exit
  end

  return param
end
cli_helper_process_config_file(a_cf) click to toggle source

Obtain options and values from a config file

# File lib/cli_helper.rb, line 134
def cli_helper_process_config_file(a_cf)
  cf = String == a_cf.class ? Pathname.new(a_cf) : a_cf
  if cf.directory?
    cf.children.each do |ccf|
      cli_helper_process_config_file(ccf)
    end
    return
  end
  unless cf.exist?
    error "Config file is missing: #{cf}"
  else
    file_type = case cf.extname.downcase
      when '.rb'
        :ruby
      when '.yml', '.yaml'
        :yaml
      when '.ini', '.txt'
        :ini
      when '.erb'
        extname = cf.basename.to_s.downcase.gsub('.erb','').split('.').last
        if %w[ yml yaml].include? extname
          :yaml
        elsif %w[ ini txt ].include? extname
          :ini
        elsif 'rb' == extname
          warning 'MakesNoSenseToMe: *.rb.erb is not supported'
          :unknown
        else
          :unknown
        end
    else
      :unknown
    end

    case file_type
      when :ruby
        load cf
      when :yaml
        configatron.configure_from_hash(
          config_file_hash = configatron.configure_from_hash(
            cli_helper_process_yaml(
              cli_helper_process_erb(cf.read)
            )
          )
        )
      when :ini
        configatron.configure_from_hash(
          configatron.configure_from_hash(
            cli_helper_process_ini(
              cli_helper_process_erb(cf.read)
            )
          )
        )
      else
        error "Do not know how to parse this file: #{cf}"
    end # case type_type
  end # unless cf.exist? || cf.directory?
end
cli_helper_process_erb(file_contents) click to toggle source

Extract options and values from an ERB formatted config file

# File lib/cli_helper.rb, line 108
def cli_helper_process_erb(file_contents)
  erb_contents = ERB.new(file_contents).result
  return erb_contents
end
cli_helper_process_ini(file_contents='') click to toggle source

Extract options and values from an INI formated config file

# File lib/cli_helper.rb, line 122
def cli_helper_process_ini(file_contents='')
  an_ini_object = IniFile.new(
                    content: file_contents,
                    comment: configatron.ini_comment,
                    parameter: configatron.ini_seperator,
                    encoding: configatron.ini_encoding
                  )
  return an_ini_object.to_h
end
cli_helper_process_yaml(file_contents='') click to toggle source

Extract options and values from a YAML formatted config file

# File lib/cli_helper.rb, line 115
def cli_helper_process_yaml(file_contents='')
  a_hash = YAML.load file_contents
  return a_hash
end
error(a_string) click to toggle source

Adds a string to the global $errors array

# File lib/cli_helper.rb, line 396
def error(a_string)
  configatron.errors << a_string
end
errors() click to toggle source

Returns an Array of errors

# File lib/cli_helper.rb, line 402
def errors
  configatron.errors
end
get_pathnames_from(an_array, extnames=['.json', '.txt', '.docx']) click to toggle source

Returns an array of valid files of valid type(s) Creates warnings for files not matching the valid extensions. Generates errors fpr files that do not exist

# File lib/cli_helper.rb, line 343
def get_pathnames_from(an_array, extnames=['.json', '.txt', '.docx'])
  an_array = [an_array] unless an_array.is_a? Array
  extnames = [extnames] unless extnames.is_a? Array
  extnames = extnames.map{|e| e.downcase}
  file_array = []
  an_array.each do |a|
    pfn = Pathname.new(a)
    if pfn.directory?
      file_array << get_pathnames_from(pfn.children, extnames)
    else
      if pfn.exist?
        if extnames.include?(pfn.extname.downcase)
          file_array << pfn
        else
          warning "File ignored because extension is not #{extnames.join(' or ')} file: #{pfn}"
        end
      else
        error "File does not exist: #{pfn}"
      end
    end
  end
  return file_array.flatten
end
me() click to toggle source

Return full pathname of program

# File lib/cli_helper.rb, line 83
def me
  configatron.me
end
my_dir() click to toggle source

Return full pathname of program

# File lib/cli_helper.rb, line 89
def my_dir
  configatron.my_dir
end
Also aliased as: root
my_name() click to toggle source

Returns the basename of the program as a string

# File lib/cli_helper.rb, line 96
def my_name
  configatron.my_name
end
root()
Alias for: my_dir
show_usage() click to toggle source

Prints to STDOUT the usage/help string

# File lib/cli_helper.rb, line 335
def show_usage
  puts usage()
end
usage() click to toggle source

Returns the usage/help information as a string

# File lib/cli_helper.rb, line 327
def usage
  a_string = configatron.cli.to_s + "\n"
  a_string += HELP + "\n" if defined?(HELP)
  return a_string
end
version() click to toggle source

Returns the version of the program as a string

# File lib/cli_helper.rb, line 102
def version
  configatron.version
end
warning(a_string) click to toggle source

Adds a string to the global $warnings array

# File lib/cli_helper.rb, line 408
def warning(a_string)
  configatron.warnings << a_string
end
warnings() click to toggle source

Returns an Array of warnings

# File lib/cli_helper.rb, line 414
def warnings
  configatron.warnings
end