class Dotenv::Parser

Parses the ‘.env` file format into key/value pairs. It allows for variable substitutions, command substitutions, and exporting of variables.

Constants

LINE

Attributes

substitutions[R]

Public Class Methods

call(...) click to toggle source
# File lib/dotenv/parser.rb, line 35
def call(...)
  new(...).call
end
new(string, overwrite: false) click to toggle source
# File lib/dotenv/parser.rb, line 40
def initialize(string, overwrite: false)
  @string = string
  @hash = {}
  @overwrite = overwrite
end

Public Instance Methods

call() click to toggle source
# File lib/dotenv/parser.rb, line 46
def call
  # Convert line breaks to same format
  lines = @string.gsub(/\r\n?/, "\n")
  # Process matches
  lines.scan(LINE).each do |key, value|
    @hash[key] = parse_value(value || "")
  end
  # Process non-matches
  lines.gsub(LINE, "").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 82
def expand_newlines(value)
  if (@hash["DOTENV_LINEBREAK_MODE"] || ENV["DOTENV_LINEBREAK_MODE"]) == "legacy"
    value.gsub('\n', "\n").gsub('\r', "\r")
  else
    value.gsub('\n', "\\\\\\n").gsub('\r', "\\\\\\r")
  end
end
parse_line(line) click to toggle source
# File lib/dotenv/parser.rb, line 62
def parse_line(line)
  if line.split.first == "export"
    if variable_not_set?(line)
      raise FormatError, "Line #{line.inspect} has an unset variable"
    end
  end
end
parse_value(value) click to toggle source
# File lib/dotenv/parser.rb, line 70
def parse_value(value)
  # Remove surrounding quotes
  value = value.strip.sub(/\A(['"])(.*)\1\z/m, '\2')
  maybe_quote = Regexp.last_match(1)
  value = unescape_value(value, maybe_quote)
  perform_substitutions(value, maybe_quote)
end
perform_substitutions(value, maybe_quote) click to toggle source
# File lib/dotenv/parser.rb, line 104
def perform_substitutions(value, maybe_quote)
  if maybe_quote != "'"
    self.class.substitutions.each do |proc|
      value = proc.call(value, @hash, overwrite: @overwrite)
    end
  end
  value
end
unescape_characters(value) click to toggle source
# File lib/dotenv/parser.rb, line 78
def unescape_characters(value)
  value.gsub(/\\([^$])/, '\1')
end
unescape_value(value, maybe_quote) click to toggle source
# File lib/dotenv/parser.rb, line 94
def unescape_value(value, maybe_quote)
  if maybe_quote == '"'
    unescape_characters(expand_newlines(value))
  elsif maybe_quote.nil?
    unescape_characters(value)
  else
    value
  end
end
variable_not_set?(line) click to toggle source
# File lib/dotenv/parser.rb, line 90
def variable_not_set?(line)
  !line.split[1..].all? { |var| @hash.member?(var) }
end