dotenv 0.9.0 → 2.7.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/README.md +187 -24
- data/bin/dotenv +2 -10
- data/lib/dotenv.rb +75 -14
- data/lib/dotenv/cli.rb +80 -0
- data/lib/dotenv/environment.rb +13 -61
- data/lib/dotenv/load.rb +2 -0
- data/lib/dotenv/missing_keys.rb +10 -0
- data/lib/dotenv/parser.rb +98 -0
- data/lib/dotenv/substitutions/command.rb +41 -0
- data/lib/dotenv/substitutions/variable.rb +47 -0
- data/lib/dotenv/tasks.rb +3 -3
- data/lib/dotenv/template.rb +21 -0
- data/lib/dotenv/version.rb +1 -1
- metadata +35 -48
- data/.env +0 -1
- data/.gitignore +0 -8
- data/.travis.yml +0 -6
- data/Changelog.md +0 -83
- data/Gemfile +0 -6
- data/Guardfile +0 -9
- data/Rakefile +0 -30
- data/dotenv-rails.gemspec +0 -17
- data/dotenv.gemspec +0 -20
- data/lib/dotenv-rails.rb +0 -1
- data/lib/dotenv/capistrano.rb +0 -5
- data/lib/dotenv/capistrano/recipes.rb +0 -10
- data/lib/dotenv/format_error.rb +0 -4
- data/lib/dotenv/railtie.rb +0 -14
- data/spec/dotenv/environment_spec.rb +0 -137
- data/spec/dotenv_spec.rb +0 -92
- data/spec/fixtures/exported.env +0 -2
- data/spec/fixtures/plain.env +0 -5
- data/spec/fixtures/quoted.env +0 -8
- data/spec/fixtures/yaml.env +0 -4
- data/spec/spec_helper.rb +0 -7
data/lib/dotenv/environment.rb
CHANGED
@@ -1,76 +1,28 @@
|
|
1
|
-
require 'dotenv/format_error'
|
2
|
-
|
3
1
|
module Dotenv
|
2
|
+
# This class inherits from Hash and represents the environment into which
|
3
|
+
# Dotenv will load key value pairs from a file.
|
4
4
|
class Environment < Hash
|
5
|
-
|
6
|
-
\A
|
7
|
-
(?:export\s+)? # optional export
|
8
|
-
([\w\.]+) # key
|
9
|
-
(?:\s*=\s*|:\s+?) # separator
|
10
|
-
( # optional value begin
|
11
|
-
'(?:\'|[^'])*' # single quoted value
|
12
|
-
| # or
|
13
|
-
"(?:\"|[^"])*" # double quoted value
|
14
|
-
| # or
|
15
|
-
[^#\n]+ # unquoted value
|
16
|
-
)? # value end
|
17
|
-
(?:\s*\#.*)? # optional comment
|
18
|
-
\z
|
19
|
-
/x
|
20
|
-
VARIABLE = /
|
21
|
-
(\\)?
|
22
|
-
(\$)
|
23
|
-
( # collect braces with var for sub
|
24
|
-
\{? # allow brace wrapping
|
25
|
-
([A-Z0-9_]+) # match the variable
|
26
|
-
\}? # closing brace
|
27
|
-
)
|
28
|
-
/xi
|
5
|
+
attr_reader :filename
|
29
6
|
|
30
|
-
def initialize(filename)
|
7
|
+
def initialize(filename, is_load = false)
|
31
8
|
@filename = filename
|
32
|
-
load
|
9
|
+
load(is_load)
|
33
10
|
end
|
34
11
|
|
35
|
-
def load
|
36
|
-
read
|
37
|
-
if match = line.match(LINE)
|
38
|
-
key, value = match.captures
|
39
|
-
|
40
|
-
value ||= ''
|
41
|
-
# Remove surrounding quotes
|
42
|
-
value = value.strip.sub(/\A(['"])(.*)\1\z/, '\2')
|
43
|
-
|
44
|
-
if $1 == '"'
|
45
|
-
value = value.gsub('\n', "\n")
|
46
|
-
# Unescape all characters except $ so variables can be escaped properly
|
47
|
-
value = value.gsub(/\\([^$])/, '\1')
|
48
|
-
end
|
49
|
-
|
50
|
-
# Process embedded variables
|
51
|
-
value.scan(VARIABLE).each do |parts|
|
52
|
-
if parts.first == '\\'
|
53
|
-
replace = parts[1...-1].join('')
|
54
|
-
else
|
55
|
-
replace = self.fetch(parts.last) { ENV[parts.last] }
|
56
|
-
end
|
57
|
-
|
58
|
-
value = value.sub(parts[0...-1].join(''), replace || '')
|
59
|
-
end
|
60
|
-
|
61
|
-
self[key] = value
|
62
|
-
elsif line !~ /\A\s*(?:#.*)?\z/ # not comment or blank line
|
63
|
-
raise FormatError, "Line #{line.inspect} doesn't match format"
|
64
|
-
end
|
65
|
-
end
|
12
|
+
def load(is_load = false)
|
13
|
+
update Parser.call(read, is_load)
|
66
14
|
end
|
67
15
|
|
68
16
|
def read
|
69
|
-
File.
|
17
|
+
File.open(@filename, "rb:bom|utf-8", &:read)
|
70
18
|
end
|
71
19
|
|
72
20
|
def apply
|
73
|
-
each { |k,v| ENV[k] ||= v }
|
21
|
+
each { |k, v| ENV[k] ||= v }
|
22
|
+
end
|
23
|
+
|
24
|
+
def apply!
|
25
|
+
each { |k, v| ENV[k] = v }
|
74
26
|
end
|
75
27
|
end
|
76
28
|
end
|
data/lib/dotenv/load.rb
ADDED
@@ -0,0 +1,98 @@
|
|
1
|
+
require "dotenv/substitutions/variable"
|
2
|
+
require "dotenv/substitutions/command" if RUBY_VERSION > "1.8.7"
|
3
|
+
|
4
|
+
module Dotenv
|
5
|
+
class FormatError < SyntaxError; end
|
6
|
+
|
7
|
+
# This class enables parsing of a string for key value pairs to be returned
|
8
|
+
# and stored in the Environment. It allows for variable substitutions and
|
9
|
+
# exporting of variables.
|
10
|
+
class Parser
|
11
|
+
@substitutions =
|
12
|
+
[Dotenv::Substitutions::Variable, Dotenv::Substitutions::Command]
|
13
|
+
|
14
|
+
LINE = /
|
15
|
+
(?:^|\A) # beginning of line
|
16
|
+
\s* # leading whitespace
|
17
|
+
(?:export\s+)? # optional export
|
18
|
+
([\w\.]+) # key
|
19
|
+
(?:\s*=\s*?|:\s+?) # separator
|
20
|
+
( # optional value begin
|
21
|
+
\s*'(?:\\'|[^'])*' # single quoted value
|
22
|
+
| # or
|
23
|
+
\s*"(?:\\"|[^"])*" # double quoted value
|
24
|
+
| # or
|
25
|
+
[^\#\r\n]+ # unquoted value
|
26
|
+
)? # value end
|
27
|
+
\s* # trailing whitespace
|
28
|
+
(?:\#.*)? # optional comment
|
29
|
+
(?:$|\z) # end of line
|
30
|
+
/x
|
31
|
+
|
32
|
+
class << self
|
33
|
+
attr_reader :substitutions
|
34
|
+
|
35
|
+
def call(string, is_load = false)
|
36
|
+
new(string, is_load).call
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
def initialize(string, is_load = false)
|
41
|
+
@string = string
|
42
|
+
@hash = {}
|
43
|
+
@is_load = is_load
|
44
|
+
end
|
45
|
+
|
46
|
+
def call
|
47
|
+
# Convert line breaks to same format
|
48
|
+
lines = @string.gsub(/\r\n?/, "\n")
|
49
|
+
# Process matches
|
50
|
+
lines.scan(LINE).each do |key, value|
|
51
|
+
@hash[key] = parse_value(value || "")
|
52
|
+
end
|
53
|
+
# Process non-matches
|
54
|
+
lines.gsub(LINE, "").split(/[\n\r]+/).each do |line|
|
55
|
+
parse_line(line)
|
56
|
+
end
|
57
|
+
@hash
|
58
|
+
end
|
59
|
+
|
60
|
+
private
|
61
|
+
|
62
|
+
def parse_line(line)
|
63
|
+
if line.split.first == "export"
|
64
|
+
if variable_not_set?(line)
|
65
|
+
raise FormatError, "Line #{line.inspect} has an unset variable"
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def parse_value(value)
|
71
|
+
# Remove surrounding quotes
|
72
|
+
value = value.strip.sub(/\A(['"])(.*)\1\z/m, '\2')
|
73
|
+
|
74
|
+
if Regexp.last_match(1) == '"'
|
75
|
+
value = unescape_characters(expand_newlines(value))
|
76
|
+
end
|
77
|
+
|
78
|
+
if Regexp.last_match(1) != "'"
|
79
|
+
self.class.substitutions.each do |proc|
|
80
|
+
value = proc.call(value, @hash, @is_load)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
value
|
84
|
+
end
|
85
|
+
|
86
|
+
def unescape_characters(value)
|
87
|
+
value.gsub(/\\([^$])/, '\1')
|
88
|
+
end
|
89
|
+
|
90
|
+
def expand_newlines(value)
|
91
|
+
value.gsub('\n', "\n").gsub('\r', "\r")
|
92
|
+
end
|
93
|
+
|
94
|
+
def variable_not_set?(line)
|
95
|
+
!line.split[1..-1].all? { |var| @hash.member?(var) }
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require "English"
|
2
|
+
|
3
|
+
module Dotenv
|
4
|
+
module Substitutions
|
5
|
+
# Substitute shell commands in a value.
|
6
|
+
#
|
7
|
+
# SHA=$(git rev-parse HEAD)
|
8
|
+
#
|
9
|
+
module Command
|
10
|
+
class << self
|
11
|
+
INTERPOLATED_SHELL_COMMAND = /
|
12
|
+
(?<backslash>\\)? # is it escaped with a backslash?
|
13
|
+
\$ # literal $
|
14
|
+
(?<cmd> # collect command content for eval
|
15
|
+
\( # require opening paren
|
16
|
+
([^()]|\g<cmd>)+ # allow any number of non-parens, or balanced
|
17
|
+
# parens (by nesting the <cmd> expression
|
18
|
+
# recursively)
|
19
|
+
\) # require closing paren
|
20
|
+
)
|
21
|
+
/x
|
22
|
+
|
23
|
+
def call(value, _env, _is_load)
|
24
|
+
# Process interpolated shell commands
|
25
|
+
value.gsub(INTERPOLATED_SHELL_COMMAND) do |*|
|
26
|
+
# Eliminate opening and closing parentheses
|
27
|
+
command = $LAST_MATCH_INFO[:cmd][1..-2]
|
28
|
+
|
29
|
+
if $LAST_MATCH_INFO[:backslash]
|
30
|
+
# Command is escaped, don't replace it.
|
31
|
+
$LAST_MATCH_INFO[0][1..-1]
|
32
|
+
else
|
33
|
+
# Execute the command and return the value
|
34
|
+
`#{command}`.chomp
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
require "English"
|
2
|
+
|
3
|
+
module Dotenv
|
4
|
+
module Substitutions
|
5
|
+
# Substitute variables in a value.
|
6
|
+
#
|
7
|
+
# HOST=example.com
|
8
|
+
# URL="https://$HOST"
|
9
|
+
#
|
10
|
+
module Variable
|
11
|
+
class << self
|
12
|
+
VARIABLE = /
|
13
|
+
(\\)? # is it escaped with a backslash?
|
14
|
+
(\$) # literal $
|
15
|
+
(?!\() # shouldnt be followed by paranthesis
|
16
|
+
\{? # allow brace wrapping
|
17
|
+
([A-Z0-9_]+)? # optional alpha nums
|
18
|
+
\}? # closing brace
|
19
|
+
/xi
|
20
|
+
|
21
|
+
def call(value, env, is_load)
|
22
|
+
combined_env = if is_load
|
23
|
+
env.merge(ENV)
|
24
|
+
else
|
25
|
+
ENV.to_h.merge(env)
|
26
|
+
end
|
27
|
+
value.gsub(VARIABLE) do |variable|
|
28
|
+
match = $LAST_MATCH_INFO
|
29
|
+
substitute(match, variable, combined_env)
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
private
|
34
|
+
|
35
|
+
def substitute(match, variable, env)
|
36
|
+
if match[1] == '\\'
|
37
|
+
variable[1..-1]
|
38
|
+
elsif match[3]
|
39
|
+
env.fetch(match[3], "")
|
40
|
+
else
|
41
|
+
variable
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
data/lib/dotenv/tasks.rb
CHANGED
@@ -0,0 +1,21 @@
|
|
1
|
+
module Dotenv
|
2
|
+
# Class for creating a template from a env file
|
3
|
+
class EnvTemplate
|
4
|
+
def initialize(env_file)
|
5
|
+
@env_file = env_file
|
6
|
+
end
|
7
|
+
|
8
|
+
def create_template
|
9
|
+
File.open(@env_file, "r") do |env_file|
|
10
|
+
File.open("#{@env_file}.template", "w") do |env_template|
|
11
|
+
env_file.each do |line|
|
12
|
+
var, value = line.split("=")
|
13
|
+
is_a_comment = var.strip[0].eql?("#")
|
14
|
+
line_transform = value.nil? || is_a_comment ? line : "#{var}=#{var}"
|
15
|
+
env_template.puts line_transform
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
data/lib/dotenv/version.rb
CHANGED
metadata
CHANGED
@@ -1,48 +1,57 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dotenv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
5
|
-
prerelease:
|
4
|
+
version: 2.7.6
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- Brandon Keepers
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2020-07-11 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rake
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
|
-
- -
|
17
|
+
- - ">="
|
20
18
|
- !ruby/object:Gem::Version
|
21
19
|
version: '0'
|
22
20
|
type: :development
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
|
-
- -
|
24
|
+
- - ">="
|
28
25
|
- !ruby/object:Gem::Version
|
29
26
|
version: '0'
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: rspec
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
|
-
- -
|
31
|
+
- - ">="
|
36
32
|
- !ruby/object:Gem::Version
|
37
33
|
version: '0'
|
38
34
|
type: :development
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
|
-
- -
|
38
|
+
- - ">="
|
44
39
|
- !ruby/object:Gem::Version
|
45
40
|
version: '0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rubocop
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: 0.40.0
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: 0.40.0
|
46
55
|
description: Loads environment variables from `.env`.
|
47
56
|
email:
|
48
57
|
- brandon@opensoul.org
|
@@ -51,63 +60,41 @@ executables:
|
|
51
60
|
extensions: []
|
52
61
|
extra_rdoc_files: []
|
53
62
|
files:
|
54
|
-
- .env
|
55
|
-
- .gitignore
|
56
|
-
- .travis.yml
|
57
|
-
- Changelog.md
|
58
|
-
- Gemfile
|
59
|
-
- Guardfile
|
60
63
|
- LICENSE
|
61
64
|
- README.md
|
62
|
-
- Rakefile
|
63
65
|
- bin/dotenv
|
64
|
-
- dotenv-rails.gemspec
|
65
|
-
- dotenv.gemspec
|
66
|
-
- lib/dotenv-rails.rb
|
67
66
|
- lib/dotenv.rb
|
68
|
-
- lib/dotenv/
|
69
|
-
- lib/dotenv/capistrano/recipes.rb
|
67
|
+
- lib/dotenv/cli.rb
|
70
68
|
- lib/dotenv/environment.rb
|
71
|
-
- lib/dotenv/
|
72
|
-
- lib/dotenv/
|
69
|
+
- lib/dotenv/load.rb
|
70
|
+
- lib/dotenv/missing_keys.rb
|
71
|
+
- lib/dotenv/parser.rb
|
72
|
+
- lib/dotenv/substitutions/command.rb
|
73
|
+
- lib/dotenv/substitutions/variable.rb
|
73
74
|
- lib/dotenv/tasks.rb
|
75
|
+
- lib/dotenv/template.rb
|
74
76
|
- lib/dotenv/version.rb
|
75
|
-
- spec/dotenv/environment_spec.rb
|
76
|
-
- spec/dotenv_spec.rb
|
77
|
-
- spec/fixtures/exported.env
|
78
|
-
- spec/fixtures/plain.env
|
79
|
-
- spec/fixtures/quoted.env
|
80
|
-
- spec/fixtures/yaml.env
|
81
|
-
- spec/spec_helper.rb
|
82
77
|
homepage: https://github.com/bkeepers/dotenv
|
83
|
-
licenses:
|
78
|
+
licenses:
|
79
|
+
- MIT
|
80
|
+
metadata: {}
|
84
81
|
post_install_message:
|
85
82
|
rdoc_options: []
|
86
83
|
require_paths:
|
87
84
|
- lib
|
88
85
|
required_ruby_version: !ruby/object:Gem::Requirement
|
89
|
-
none: false
|
90
86
|
requirements:
|
91
|
-
- -
|
87
|
+
- - ">="
|
92
88
|
- !ruby/object:Gem::Version
|
93
89
|
version: '0'
|
94
90
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
95
|
-
none: false
|
96
91
|
requirements:
|
97
|
-
- -
|
92
|
+
- - ">="
|
98
93
|
- !ruby/object:Gem::Version
|
99
94
|
version: '0'
|
100
95
|
requirements: []
|
101
|
-
|
102
|
-
rubygems_version: 1.8.23
|
96
|
+
rubygems_version: 3.0.3
|
103
97
|
signing_key:
|
104
|
-
specification_version:
|
98
|
+
specification_version: 4
|
105
99
|
summary: Loads environment variables from `.env`.
|
106
|
-
test_files:
|
107
|
-
- spec/dotenv/environment_spec.rb
|
108
|
-
- spec/dotenv_spec.rb
|
109
|
-
- spec/fixtures/exported.env
|
110
|
-
- spec/fixtures/plain.env
|
111
|
-
- spec/fixtures/quoted.env
|
112
|
-
- spec/fixtures/yaml.env
|
113
|
-
- spec/spec_helper.rb
|
100
|
+
test_files: []
|