def conf(key, allow_missing = false, &handler)
      value = nil
      key.split(".").each do |part|
        if value
          value = value.fetch(part)
        else
          value = @@json.fetch(part)
        end
      end

      if handler
        handler.call(value)
      else
        value
      end
    rescue KeyError => e
      if allow_missing
        nil
      else
        puts "Your configuration file is missing $.#{key}."
        exit
      end
    end
def conf(key, allow_missing = false, &handler)
      value = nil
      key.split(".").each do |part|
        if value
          value = value.fetch(part)
        else
          value = @@json.fetch(part)
        end
      end

      if handler
        handler.call(value)
      else
        value
      end
    rescue KeyError => e
      if allow_missing
        nil
      else
        puts "Your configuration file is missing $.#{key}."
        exit
      end
    end
Internal: Handle any KeyErrors that occur while getting a configuration value
 by printing out a message describing the missing key and exiting.

 key     - the full key to get ex. `s3.buckets.directory`
 allow_missing - if true we will return nil for missing values instead of exiting
 handler - a block that will do additional processing on the key. If nil,
           the value is returned as is.

 Returns the configuration value if successful