class Dotenv::Parser
It allows for variable substitutions, command substitutions, and exporting of variables.
Parses the ‘.env` file format into key/value pairs.
def call(...)
def call(...) new(...).call end
def call
def call @string.scan(LINE) do match = $LAST_MATCH_INFO if existing?(match[:key]) # Use value from already defined variable @hash[match[:key]] = ENV[match[:key]] elsif match[:export] && !match[:value] # Check for exported variable with no value if !@hash.member?(match[:key]) raise FormatError, "Line #{match.to_s.inspect} has an unset variable" end else @hash[match[:key]] = parse_value(match[:value] || "") end end @hash end
def existing?(key)
def existing?(key) !@overwrite && key != "DOTENV_LINEBREAK_MODE" && ENV.key?(key) end
def expand_newlines(value)
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
def initialize(string, overwrite: false)
def initialize(string, overwrite: false) # Convert line breaks to same format @string = string.gsub(/\r\n?/, "\n") @hash = {} @overwrite = overwrite end
def parse_value(value)
def parse_value(value) # Remove surrounding quotes value = value.strip.sub(QUOTED_STRING, '\2') maybe_quote = Regexp.last_match(1) # Expand new lines in double quoted values value = expand_newlines(value) if maybe_quote == '"' # Unescape characters and performs substitutions unless value is single quoted if maybe_quote != "'" value = unescape_characters(value) self.class.substitutions.each { |proc| value = proc.call(value, @hash) } end value end
def unescape_characters(value)
def unescape_characters(value) value.gsub(/\\([^$])/, '\1') end