class Dotenv::Parser

This class enables parsing of a string for key value pairs to be returned and stored in the Environment. It allows for variable substitutions and exporting of variables.

Constants

LINE

Attributes

substitutions[R]

Public Class Methods

call(string) click to toggle source
# File lib/dotenv/parser.rb, line 33
def call(string)
  new(string).call
end
new(string) click to toggle source
# File lib/dotenv/parser.rb, line 38
def initialize(string)
  @string = string
  @hash = {}
end

Public Instance Methods

call() click to toggle source
# File lib/dotenv/parser.rb, line 43
def call
  @string.split(/[\n\r]+/).each do |line|
    parse_line(line)
  end
  @hash
end

Private Instance Methods

expand_newlines(value) click to toggle source
# File lib/dotenv/parser.rb, line 85
def expand_newlines(value)
  value.gsub('\n', "\n").gsub('\r', "\r")
end
parse_line(line) click to toggle source
# File lib/dotenv/parser.rb, line 52
def parse_line(line)
  if (match = line.match(LINE))
    key, value = match.captures
    @hash[key] = parse_value(value || "")
  elsif line.split.first == "export"
    if variable_not_set?(line)
      raise FormatError, "Line #{line.inspect} has an unset variable"
    end
  elsif line !~ /\A\s*(?:#.*)?\z/ # not comment or blank line
    raise FormatError, "Line #{line.inspect} doesn't match format"
  end
end
parse_value(value) click to toggle source
# File lib/dotenv/parser.rb, line 65
def parse_value(value)
  # Remove surrounding quotes
  value = value.strip.sub(/\A(['"])(.*)\1\z/, '\2')

  if Regexp.last_match(1) == '"'
    value = unescape_characters(expand_newlines(value))
  end

  if Regexp.last_match(1) != "'"
    self.class.substitutions.each do |proc|
      value = proc.call(value, @hash)
    end
  end
  value
end
unescape_characters(value) click to toggle source
# File lib/dotenv/parser.rb, line 81
def unescape_characters(value)
  value.gsub(/\([^$])/, '\1')
end
variable_not_set?(line) click to toggle source
# File lib/dotenv/parser.rb, line 89
def variable_not_set?(line)
  !line.split[1..-1].all? { |var| @hash.member?(var) }
end