@@ -14,21 +14,23 @@ class Parser
1414 ]
1515
1616 LINE = /
17- (?:^|\A ) # beginning of line
18- \s * # leading whitespace
19- (?:export\s +)? # optional export
20- ([\w .]+) # key
21- (?:\s *=\s *?|:\s +?) # separator
22- ( # optional value begin
23- \s *'(?:\\ '|[^'])*' # single quoted value
24- | # or
25- \s *"(?:\\ "|[^"])*" # double quoted value
26- | # or
27- [^\# \r \n ]+ # unquoted value
28- )? # value end
29- \s * # trailing whitespace
30- (?:\# .*)? # optional comment
31- (?:$|\z ) # end of line
17+ (?:^|\A ) # beginning of line
18+ \s * # leading whitespace
19+ (?<export>export\s +)? # optional export
20+ (?<key>[\w .]+) # key
21+ (?: # optional separator and value
22+ (?:\s *=\s *?|:\s +?) # separator
23+ (?<value> # optional value begin
24+ \s *'(?:\\ '|[^'])*' # single quoted value
25+ | # or
26+ \s *"(?:\\ "|[^"])*" # double quoted value
27+ | # or
28+ [^\# \n ]+ # unquoted value
29+ )? # value end
30+ )? # separator and value end
31+ \s * # trailing whitespace
32+ (?:\# .*)? # optional comment
33+ (?:$|\z ) # end of line
3234 /x
3335
3436 class << self
@@ -40,25 +42,29 @@ def call(...)
4042 end
4143
4244 def initialize ( string , overwrite : false )
43- @string = string
45+ # Convert line breaks to same format
46+ @string = string . gsub ( /[\n \r ]+/ , "\n " )
4447 @hash = { }
4548 @overwrite = overwrite
4649 end
4750
4851 def call
49- # Convert line breaks to same format
50- lines = @string . gsub ( /\r \n ?/ , "\n " )
51- # Process matches
52- lines . scan ( LINE ) . each do |key , value |
53- # Skip parsing values that will be ignored
54- next if ignore? ( key )
52+ @string . scan ( LINE ) do
53+ match = $LAST_MATCH_INFO
5554
56- @hash [ key ] = parse_value ( value || "" )
57- end
58- # Process non-matches
59- lines . gsub ( LINE , "" ) . split ( /[\n \r ]+/ ) . each do |line |
60- parse_line ( line )
55+ # Skip parsing values that will be ignored
56+ next if ignore? ( match [ :key ] )
57+
58+ # Check for exported variable with no value
59+ if match [ :export ] && !match [ :value ]
60+ if !@hash . member? ( match [ :key ] )
61+ raise FormatError , "Line #{ match . to_s . inspect } has an unset variable"
62+ end
63+ else
64+ @hash [ match [ :key ] ] = parse_value ( match [ :value ] || "" )
65+ end
6166 end
67+
6268 @hash
6369 end
6470
@@ -69,14 +75,6 @@ def ignore?(key)
6975 !@overwrite && key != "DOTENV_LINEBREAK_MODE" && ENV . key? ( key )
7076 end
7177
72- def parse_line ( line )
73- if line . split . first == "export"
74- if variable_not_set? ( line )
75- raise FormatError , "Line #{ line . inspect } has an unset variable"
76- end
77- end
78- end
79-
8078 QUOTED_STRING = /\A (['"])(.*)\1 \z /m
8179 def parse_value ( value )
8280 # Remove surrounding quotes
@@ -106,9 +104,5 @@ def expand_newlines(value)
106104 value . gsub ( '\n' , "\\ \\ \\ n" ) . gsub ( '\r' , "\\ \\ \\ r" )
107105 end
108106 end
109-
110- def variable_not_set? ( line )
111- !line . split [ 1 ..] . all? { |var | @hash . member? ( var ) }
112- end
113107 end
114108end
0 commit comments