Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .tool-versions
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
erlang 23.1.1
elixir 1.11.1-otp-23
erlang 28.0.1
elixir 1.18.3-otp-27
77 changes: 40 additions & 37 deletions lib/dotenv.ex
Original file line number Diff line number Diff line change
Expand Up @@ -24,37 +24,43 @@ defmodule Dotenv do
Dotenv.Supervisor.start_link(env_path)
end

@quotes_pattern ~r/^(['"])(.*)\1$/
@pattern ~r/
\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

# https://regex101.com/r/XrvCwE/1
@env_expand_pattern ~r/
(?:^|[^\\]) # prevent to expand \\$
( # get variable key pattern
\$ #
(?: #
([A-Z0-9_]*[A-Z_]+[A-Z0-9_]*) # get variable key
| #
(?: #
{([A-Z0-9_]*[A-Z_]+[A-Z0-9_]*)} # get variable key between {}
) #
) #
) #
/x
defp quotes_pattern do
~r/^(['"])(.*)\1$/
end

defp pattern do
~r/
\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
end

defp env_expand_pattern do
~r/
(?:^|[^\\]) # prevent to expand \\$
( # get variable key pattern
\$ #
(?: #
([A-Z0-9_]*[A-Z_]+[A-Z0-9_]*) # get variable key
| #
(?: #
{([A-Z0-9_]*[A-Z_]+[A-Z0-9_]*)} # get variable key between {}
) #
) #
) #
/x
end

##############################################################################
# Server API
Expand Down Expand Up @@ -141,7 +147,7 @@ defmodule Dotenv do
values = String.split(contents, "\n")

values
|> Enum.flat_map(&Regex.scan(@pattern, &1))
|> Enum.flat_map(&Regex.scan(pattern(), &1))
|> trim_quotes_from_values
|> Enum.reduce([], &expand_env/2)
|> Enum.reduce(Map.new(), &collect_into_map/2)
Expand All @@ -158,14 +164,11 @@ defmodule Dotenv do
end

defp trim_quotes(value) do
String.replace(value, @quotes_pattern, "\\2")
String.replace(value, quotes_pattern(), "\\2")
end

# without value
defp expand_env([_whole, _k], acc), do: acc

defp expand_env([whole, k, v], acc) do
matchs = Regex.scan(@env_expand_pattern, v)
matchs = Regex.scan(env_expand_pattern(), v)

new_value =
case Enum.empty?(matchs) do
Expand Down