module Hocon::CLI

Constants

ConfigMissingError

Aliases

ConfigWrongTypeError
SUBCOMMANDS

List of valid subcommands

Public Class Methods

do_get(opts, hocon_text) click to toggle source

Entry point for the ‘get’ subcommand Returns a string representation of the the value at the path given on the command line

# File lib/hocon/cli.rb, line 133
def self.do_get(opts, hocon_text)
  config = Hocon::ConfigFactory.parse_string(hocon_text)
  unless config.has_path?(opts[:path])
    raise MissingPathError.new
  end

  value = config.get_any_ref(opts[:path])

  render_options = Hocon::ConfigRenderOptions.defaults
  # Otherwise weird comments show up in the output
  render_options.origin_comments = false
  # If json is false, the hocon format is used
  render_options.json = opts[:json]
  # Output colons between keys and values
  render_options.key_value_separator = :colon

  Hocon::ConfigValueFactory.from_any_ref(value).render(render_options)
end
do_set(opts, hocon_text) click to toggle source

Entry point for the ‘set’ subcommand Returns a string representation of the HOCON config after adding/replacing the value at the given path with the given value

# File lib/hocon/cli.rb, line 155
def self.do_set(opts, hocon_text)
  config_doc = Hocon::Parser::ConfigDocumentFactory.parse_string(hocon_text)
  modified_config_doc = config_doc.set_value(opts[:path], opts[:new_value])

  modified_config_doc.render
end
do_unset(opts, hocon_text) click to toggle source

Entry point for the ‘unset’ subcommand Returns a string representation of the HOCON config after removing the value at the given path

# File lib/hocon/cli.rb, line 165
def self.do_unset(opts, hocon_text)
  config_doc = Hocon::Parser::ConfigDocumentFactory.parse_string(hocon_text)
  unless config_doc.has_value?(opts[:path])
    raise MissingPathError.new
  end

  modified_config_doc = config_doc.remove_value(opts[:path])

  modified_config_doc.render
end
exit_with_error(message) click to toggle source

Print an error message and exit the program

# File lib/hocon/cli.rb, line 186
def self.exit_with_error(message)
  STDERR.puts "Error: #{message}"
  exit(1)
end
exit_with_usage_and_error(opt_parser, message) click to toggle source

Print an error message and usage, then exit the program

# File lib/hocon/cli.rb, line 192
def self.exit_with_usage_and_error(opt_parser, message)
  STDERR.puts opt_parser
  exit_with_error(message)
end
get_hocon_file(in_file) click to toggle source

If a file is provided, return it’s contents. Otherwise read from STDIN

# File lib/hocon/cli.rb, line 177
def self.get_hocon_file(in_file)
  if in_file
    File.read(in_file)
  else
    STDIN.read
  end
end
invalid_subcommand_error(subcommand, opt_parser) click to toggle source

Exits with an error for when a subcommand doesn’t exist. Prints the usage

# File lib/hocon/cli.rb, line 212
def self.invalid_subcommand_error(subcommand, opt_parser)
  error_message = "Invalid subcommand '#{subcommand}', must be one of [#{SUBCOMMANDS.join(', ')}]"
  exit_with_usage_and_error(opt_parser, error_message)
end
main(opts) click to toggle source

Main entry point into the script Calls the appropriate subcommand and handles errors raised from the subcommands

# File lib/hocon/cli.rb, line 110
def self.main(opts)
  hocon_text = get_hocon_file(opts[:in_file])

  begin
    case opts[:subcommand]
      when 'get'
        puts do_get(opts, hocon_text)
      when 'set'
        print_or_write(do_set(opts, hocon_text), opts[:out_file])
      when 'unset'
        print_or_write(do_unset(opts, hocon_text), opts[:out_file])
    end

  rescue MissingPathError
    exit_with_error("Can't find the given path: '#{opts[:path]}'")
  end

  exit
end
no_subcommand_error(opt_parser) click to toggle source

Exits with an error for when no subcommand is supplied on the command line. Prints the usage

# File lib/hocon/cli.rb, line 206
def self.no_subcommand_error(opt_parser)
  error_message = "Must specify subcommand from [#{SUBCOMMANDS.join(', ')}]"
  exit_with_usage_and_error(opt_parser, error_message)
end
parse_args(args) click to toggle source

Parses the command line flags and argument Returns a options hash with values for each option and argument

# File lib/hocon/cli.rb, line 24
def self.parse_args(args)
  options = {}
  opt_parser = OptionParser.new do |opts|
    subcommands = SUBCOMMANDS.join(',')
    opts.banner = "Usage: hocon [options] {#{subcommands}} PATH [VALUE]\n\n" +
        "Example usages:\n" +
        "  hocon -i settings.conf -o new_settings.conf set some.nested.value 42\n" +
        "  hocon -f settings.conf set some.nested.value 42\n" +
        "  cat settings.conf | hocon get some.nested.value\n\n" +
        "Subcommands:\n" +
        "  get PATH - Returns the value at the given path\n" +
        "  set PATH VALUE - Sets or adds the given value at the given path\n" +
        "  unset PATH - Removes the value at the given path"

    opts.separator('')
    opts.separator('Options:')

    in_file_description = 'HOCON file to read/modify. If omitted, STDIN assumed'
    opts.on('-i', '--in-file HOCON_FILE', in_file_description) do |in_file|
      options[:in_file] = in_file
    end

    out_file_description = 'File to be written to. If omitted, STDOUT assumed'
    opts.on('-o', '--out-file HOCON_FILE', out_file_description) do |out_file|
      options[:out_file] = out_file
    end

    file_description = 'File to read/write to. Equivalent to setting -i/-o to the same file'
    opts.on('-f', '--file HOCON_FILE', file_description) do |file|
      options[:file] = file
    end

    json_description = "Output values from the 'get' subcommand in json format"
    opts.on('-j', '--json', json_description) do |json|
      options[:json] = json
    end

    opts.on_tail('-h', '--help', 'Show this message') do
      puts opts
      exit
    end

    opts.on_tail('-v', '--version', 'Show version') do
      puts Hocon::Version::STRING
      exit
    end
  end
  # parse! returns the argument list minus all the flags it found
  remaining_args = opt_parser.parse!(args)

  # Ensure -i and -o aren't used at the same time as -f
  if (options[:in_file] || options[:out_file]) && options[:file]
    exit_with_usage_and_error(opt_parser, "--file can't be used with --in-file or --out-file")
  end

  # If --file is used, set --in/out-file to the same file
  if options[:file]
    options[:in_file] = options[:file]
    options[:out_file] = options[:file]
  end

  no_subcommand_error(opt_parser) unless remaining_args.size > 0

  # Assume the first arg is the subcommand
  subcommand = remaining_args.shift
  options[:subcommand] = subcommand

  case subcommand
    when 'set'
      subcommand_arguments_error(subcommand, opt_parser) unless remaining_args.size >= 2
      options[:path] = remaining_args.shift
      options[:new_value] = remaining_args.shift

    when 'get', 'unset'
      subcommand_arguments_error(subcommand, opt_parser) unless remaining_args.size >= 1
      options[:path] = remaining_args.shift

    else
      invalid_subcommand_error(subcommand, opt_parser)
  end

  options
end
print_or_write(string, out_file) click to toggle source

If out_file is not nil, write to that file. Otherwise print to STDOUT

subcommand_arguments_error(subcommand, opt_parser) click to toggle source

Exits with an error saying there aren’t enough arguments found for a given subcommand. Prints the usage

# File lib/hocon/cli.rb, line 199
def self.subcommand_arguments_error(subcommand, opt_parser)
  error_message = "Too few arguments for '#{subcommand}' subcommand"
  exit_with_usage_and_error(opt_parser, error_message)
end