class KBSecret::CLI

An encapsulation of useful methods for kbsecret's CLI. Most methods in this class assume that they are being called from the context of a command-line utility.

Constants

RED
TYPE_ALIASES

Abbreviations for record types (e.g., `env` for `environment`).

Attributes

args[R]

@return [Dreck::Result, nil] the result of trailing argument parsing, if

requested via {#dreck}
opts[R]

@return [Slop::Result, nil] the result of option parsing, if requested

via {#slop}
session[R]

@return [Session, nil] the session associated with the command, if requested

via {#ensure_session!}

Public Class Methods

create(argv = ARGV, &block) click to toggle source

Encapsulate both the options and trailing arguments passed to a `kbsecret` command. @yield [CLI] the {CLI} instance to specify @return [CLI] the command's initial state @example

cmd = KBSecret::CLI.create do |c|
  c.slop do |o|
    o.string "-s", "--session", "session label"
    o.bool "-f", "--foo", "whatever"
  end

  c.dreck do
    string :name
  end

  c.ensure_session!
end

cmd.opts # => Slop::Result
cmd.args # => Dreck::Result
# File lib/kbsecret/cli.rb, line 104
def self.create(argv = ARGV, &block)
  CLI.new(argv, &block)
end
die(msg) click to toggle source

Print an error message and terminate. @param msg [String] the message to print @return [void] @note This method does not return!

# File lib/kbsecret/cli.rb, line 42
def die(msg)
  fatal = ENV["NO_COLOR"] ? "Fatal" : RED["Fatal"]
  abort "#{fatal}: #{msg}"
end
ifs() click to toggle source

Finds a reasonable default field separator by checking the environment first

and then falling back to ":".

@return [String] the field separator

# File lib/kbsecret/cli.rb, line 50
def ifs
  ENV["IFS"] || ":"
end
installed?(util) click to toggle source

Searches for an executable on the user's `$PATH`. @param util [String] the name of the executable to search for. @return [Boolean] whether or not `util` is available on the `$PATH`. @example

CLI.installed? "foo" # => false
CLI.installed? "gcc" # => true
# File lib/kbsecret/cli.rb, line 78
def installed?(util)
  ENV["PATH"].split(File::PATH_SEPARATOR).any? do |path|
    File.executable?(File.join(path, util))
  end
end
new(argv = ARGV) { |self| ... } click to toggle source

@api private @deprecated see {create}

# File lib/kbsecret/cli.rb, line 110
def initialize(argv = ARGV)
  @argv = argv.dup
  guard { yield self }
end
stderr() click to toggle source

@return [IO] the IO object corresponding to the current standard error @note Internal `kbsecret` commands should use this, and not `STDERR`.

# File lib/kbsecret/cli.rb, line 68
def stderr
  $stderr
end
stdin() click to toggle source

@return [IO] the IO object corresponding to the current standard input @note Internal `kbsecret` commands should use this, and not `STDIN`.

# File lib/kbsecret/cli.rb, line 56
def stdin
  $stdin
end
stdout() click to toggle source

@return [IO] the IO object corresponding to the current standard output @note Internal `kbsecret` commands should use this, and not `STDOUT`.

# File lib/kbsecret/cli.rb, line 62
def stdout
  $stdout
end

Public Instance Methods

bye(msg) click to toggle source

Print an informational message via {#info} and exit successfully. @param msg [String] the message to print @return [void] @note This method does not return!

# File lib/kbsecret/cli.rb, line 245
def bye(msg)
  info msg
  exit
end
dreck(errors: true, &block) click to toggle source

Parse trailing arguments for a `kbsecret` command, using the elements remaining

after options have been removed and interpreted via {#slop}.

@param errors [Boolean] whether or not to produce (strict) Dreck errors @note If {#slop} is called, it must be called before this.

# File lib/kbsecret/cli.rb, line 152
def dreck(errors: true, &block)
  @args = Dreck.parse @argv, strict: errors do
    instance_eval(&block)
  end
end
ensure_generator!(where = :option) click to toggle source

Ensure that a generator profile passed in as an option or argument already

exists (i.e., is already configured).

@param where [Symbol] Where to look for the session label to test.

If `:option` is passed, then the generator is expected to be the value of
the `--generator` option. If `:argument` is passed, then the type is expected
to be in the argument list labeled as `:generator` by Dreck.

@return [void] @note {#slop} and {#dreck} should be called before this, depending on whether

options or arguments are being tested for a valid session.
# File lib/kbsecret/cli.rb, line 195
def ensure_generator!(where = :option)
  gen = where == :option ? @opts[:generator] : @args[:generator]
  Config.generator gen
end
ensure_session!(where = :option) click to toggle source

Ensure that a session passed in as an option or argument already exists

(i.e., is already configured).

@param where [Symbol] Where to look for the session label to test.

If `:option` is passed, then the session is expected to be the value of
the `--session` option. If `:argument` is passed, then the session is expected
to be in the argument list labeled as `:argument` by Dreck.

@return [void] @note {#slop} and {#dreck} should be called before this, depending on whether

options or arguments are being tested for a valid session.
# File lib/kbsecret/cli.rb, line 167
def ensure_session!(where = :option)
  label = where == :option ? @opts[:session] : @args[:session]
  @session = Session[label]
end
ensure_type!(where = :option) click to toggle source

Ensure that a record type passed in as an option or argument is resolvable

to a record class.

@param where [Symbol] Where to look for the record type to test.

If `:option` is passed, then the type is expected to be the value of the
`--type` option. If `:argument` is passed, then the type is expected to
be in the argument list labeled as `:type` by Dreck.

@return [void] @note {#slop} and {#dreck} should be called before this, depending on whether

options or arguments are being tested for a valid session.
# File lib/kbsecret/cli.rb, line 181
def ensure_type!(where = :option)
  type = TYPE_ALIASES[where == :option ? @opts[:type] : @args[:type]]
  Record.class_for type
end
guard() { || ... } click to toggle source

“Guard” a block by propagating any exceptions as fatal (unrecoverable)

errors.

@return [Object] the result of the block @note This should be used to guard chunks of code that are likely to

raise exceptions. The amount of code guarded should be minimized.
# File lib/kbsecret/cli.rb, line 205
def guard
  yield
rescue => e
  stderr.puts e.backtrace if @opts&.debug?
  die "#{e.to_s.capitalize}."
end
info(msg) click to toggle source

Print an informational message. @param msg [String] the message to print @return [void]

# File lib/kbsecret/cli.rb, line 228
def info(msg)
  info = ENV["NO_COLOR"] ? "Info" : GREEN["Info"]
  stderr.puts "#{info}: #{msg}"
end
prompt(question, echo: true) click to toggle source

Prompt the user for some input. @param question [String] the question to ask the user @param echo [Boolean] whether or not to echo the user's input @return [String] the user's response, with trailing newline removed

# File lib/kbsecret/cli.rb, line 216
def prompt(question, echo: true)
  if !echo && stdin.tty?
    stdin.getpass("#{question} ")
  else
    stdout.print "#{question} "
    stdin.gets.chomp
  end
end
slop(cmds: [], errors: true) { |o| ... } click to toggle source

Parse options for a `kbsecret` command, adding some default options for

introspection, verbosity, and help output.

@param cmds [Array<String>] additional commands to print in `–introspect-flags` @param errors [Boolean] whether or not to produce Slop errors @return [Slop::Result] the result of argument parsing @note This should be called within the block passed to {#initialize}.

# File lib/kbsecret/cli.rb, line 123
def slop(cmds: [], errors: true)
  @opts = Slop.parse @argv, suppress_errors: !errors do |o|
    o.separator "Options:"

    yield o

    o.bool "-V", "--verbose", "produce more verbose output"
    o.bool "-w", "--no-warn", "suppress warning messages"
    o.bool "--debug", "produce full backtraces on errors"

    o.on "-h", "--help", "show this help message" do
      puts o.to_s prefix: "  "
      exit
    end

    o.on "--introspect-flags", "dump recognized flags and subcommands" do
      comp = o.options.flat_map(&:flags) + cmds
      puts comp.join "\n"
      exit
    end
  end

  @argv = @opts.args
end
verbose(msg) click to toggle source

Print an information message, but only if verbose output has been enabled. @param msg [String] the message to print @return [void]

# File lib/kbsecret/cli.rb, line 236
def verbose(msg)
  return unless @opts.verbose?
  info msg
end
warn(msg) click to toggle source

Print a warning message unless warnings have been suppressed. @param msg [String] the message to print @return [void]

# File lib/kbsecret/cli.rb, line 253
def warn(msg)
  return if @opts.no_warn?
  warning = ENV["NO_COLOR"] ? "Warning" : YELLOW["Warning"]
  stderr.puts "#{warning}: #{msg}"
end