Class: Dotenv::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/dotenv/parser.rb

Constant Summary collapse

LINE =
/
  \A
  (?:export\s+)?    # optional export
  ([\w\.]+)         # key
  (?:\s*=\s*|:\s+?) # separator
  (                 # optional value begin
    '(?:\'|[^'])*'  #   single quoted value
    |               #   or
    "(?:\"|[^"])*"  #   double quoted value
    |               #   or
    [^#\n]+         #   unquoted value
  )?                # value end
  (?:\s*\#.*)?      # optional comment
  \z
/x
@@substitutions =
Substitutions.constants.map { |const| Substitutions.const_get(const) }

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(string) ⇒ Parser



32
33
34
# File 'lib/dotenv/parser.rb', line 32

def initialize(string)
  @string = string
end

Class Method Details

.call(string) ⇒ Object



28
29
30
# File 'lib/dotenv/parser.rb', line 28

def self.call(string)
  new(string).call
end

Instance Method Details

#callObject



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/dotenv/parser.rb', line 36

def call
  @string.split("\n").inject({}) do |hash, line|
    if match = line.match(LINE)
      key, value = match.captures

      value ||= ''
      # Remove surrounding quotes
      value = value.strip.sub(/\A(['"])(.*)\1\z/, '\2')

      if $1 == '"'
        value = value.gsub('\n', "\n")
        # Unescape all characters except $ so variables can be escaped properly
        value = value.gsub(/\\([^$])/, '\1')
      end

      if $1 != "'"
        @@substitutions.each do |proc|
          value = proc.call(value, hash)
        end
      end

      hash[key] = value
    elsif line !~ /\A\s*(?:#.*)?\z/ # not comment or blank line
      raise FormatError, "Line #{line.inspect} doesn't match format"
    end
    hash
  end
end