dotenv 2.7.1 → 2.8.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +34 -3
- data/lib/dotenv/cli.rb +27 -62
- data/lib/dotenv/missing_keys.rb +1 -1
- data/lib/dotenv/parser.rb +38 -27
- data/lib/dotenv/substitutions/command.rb +2 -2
- data/lib/dotenv/substitutions/variable.rb +3 -7
- data/lib/dotenv/template.rb +26 -0
- data/lib/dotenv/version.rb +1 -1
- metadata +12 -11
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 53a782f20ccb8d0ed6e70eb3f6e626313a96460297e75dfc02356da40bea9ef1
|
4
|
+
data.tar.gz: 7dee9ae1c761ad5f069883443f8ccb0c3e8540187e432fc184783c88f1844ac6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 0425caeb0f6321954bc8731438793f3d24306b72e0bf17c7de14e45c093bd2af892899d9b91780e0b688371e5db03a819eead8fe2475a7550fb1fc4762989e23
|
7
|
+
data.tar.gz: 52414dd28acab5d41879dc1740c08f8fe4265c66476dd04e1580291104701c0c5b5dcda87575d9aa4433f92587efcee87bf3aa7bb32eab35685b2fa2dd580855
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
# dotenv [![
|
1
|
+
# dotenv [![Gem Version](https://badge.fury.io/rb/dotenv.svg)](https://badge.fury.io/rb/dotenv) [![Join the chat at https://gitter.im/bkeepers/dotenv](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/bkeepers/dotenv?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
|
2
2
|
|
3
3
|
Shim to load environment variables from `.env` into `ENV` in *development*.
|
4
4
|
|
@@ -30,7 +30,10 @@ dotenv is initialized in your Rails app during the `before_configuration` callba
|
|
30
30
|
# config/application.rb
|
31
31
|
Bundler.require(*Rails.groups)
|
32
32
|
|
33
|
-
|
33
|
+
# Load dotenv only in development or test environment
|
34
|
+
if ['development', 'test'].include? ENV['RAILS_ENV']
|
35
|
+
Dotenv::Railtie.load
|
36
|
+
end
|
34
37
|
|
35
38
|
HOSTNAME = ENV['HOSTNAME']
|
36
39
|
```
|
@@ -62,7 +65,7 @@ Dotenv.load
|
|
62
65
|
|
63
66
|
By default, `load` will look for a file called `.env` in the current working directory. Pass in multiple files and they will be loaded in order. The first value set for a variable will win.
|
64
67
|
|
65
|
-
```
|
68
|
+
```ruby
|
66
69
|
require 'dotenv'
|
67
70
|
Dotenv.load('file1.env', 'file2.env')
|
68
71
|
```
|
@@ -218,12 +221,40 @@ If you use this gem to handle env vars for multiple Rails environments (developm
|
|
218
221
|
|
219
222
|
Credentials should only be accessible on the machines that need access to them. Never commit sensitive information to a repository that is not needed by every development machine and server.
|
220
223
|
|
224
|
+
|
225
|
+
You can use the `-t` or `--template` flag on the dotenv cli to create a template of your `.env` file.
|
226
|
+
```shell
|
227
|
+
$ dotenv -t .env
|
228
|
+
```
|
229
|
+
A template will be created in your working directory named `{FINAME}.template`. So in the above example, it would create a `.env.template` file.
|
230
|
+
|
231
|
+
The template will contain all the environment variables in your `.env` file but with their values set to the variable names.
|
232
|
+
|
233
|
+
```shell
|
234
|
+
# .env
|
235
|
+
S3_BUCKET=YOURS3BUCKET
|
236
|
+
SECRET_KEY=YOURSECRETKEYGOESHERE
|
237
|
+
```
|
238
|
+
|
239
|
+
Would become
|
240
|
+
|
241
|
+
```shell
|
242
|
+
# .env.template
|
243
|
+
S3_BUCKET=S3_BUCKET
|
244
|
+
SECRET_KEY=SECRET_KEY
|
245
|
+
```
|
246
|
+
|
221
247
|
Personally, I prefer to commit the `.env` file with development-only settings. This makes it easy for other developers to get started on the project without compromising credentials for other environments. If you follow this advice, make sure that all the credentials for your development environment are different from your other deployments and that the development credentials do not have access to any confidential data.
|
222
248
|
|
223
249
|
### Why is it not overriding existing `ENV` variables?
|
224
250
|
|
225
251
|
By default, it **won't** overwrite existing environment variables as dotenv assumes the deployment environment has more knowledge about configuration than the application does. To overwrite existing environment variables you can use `Dotenv.overload`.
|
226
252
|
|
253
|
+
You can also use the `-o` or `--overload` flag on the dotenv cli to override existing `ENV` variables.
|
254
|
+
```shell
|
255
|
+
$ dotenv -o -f ".env.local,.env"
|
256
|
+
```
|
257
|
+
|
227
258
|
## Contributing
|
228
259
|
|
229
260
|
If you want a better idea of how dotenv works, check out the [Ruby Rogues Code Reading of dotenv](https://www.youtube.com/watch?v=lKmY_0uY86s).
|
data/lib/dotenv/cli.rb
CHANGED
@@ -1,92 +1,57 @@
|
|
1
1
|
require "dotenv"
|
2
2
|
require "dotenv/version"
|
3
|
+
require "dotenv/template"
|
3
4
|
require "optparse"
|
4
5
|
|
5
6
|
module Dotenv
|
6
|
-
# The
|
7
|
-
|
8
|
-
|
9
|
-
attr_reader :argv, :exec_args, :parser_args, :filenames
|
7
|
+
# The command line interface
|
8
|
+
class CLI < OptionParser
|
9
|
+
attr_reader :argv, :filenames, :overload
|
10
10
|
|
11
11
|
def initialize(argv = [])
|
12
12
|
@argv = argv.dup
|
13
13
|
@filenames = []
|
14
|
-
@
|
15
|
-
end
|
14
|
+
@overload = false
|
16
15
|
|
17
|
-
|
18
|
-
|
16
|
+
super "Usage: dotenv [options]"
|
17
|
+
separator ""
|
19
18
|
|
20
|
-
|
21
|
-
|
22
|
-
rescue Errno::ENOENT => e
|
23
|
-
abort e.message
|
24
|
-
else
|
25
|
-
exec(*@exec_args) unless @exec_args.empty?
|
19
|
+
on("-f FILES", Array, "List of env files to parse") do |list|
|
20
|
+
@filenames = list
|
26
21
|
end
|
27
|
-
end
|
28
|
-
|
29
|
-
private
|
30
|
-
|
31
|
-
def parse_argv!(argv)
|
32
|
-
parser = create_option_parser
|
33
|
-
add_options(parser, @flag_matchers)
|
34
|
-
@parser_args, @exec_args = split_argv(argv.join(" "), @flag_matchers)
|
35
|
-
parser.parse! @parser_args
|
36
|
-
|
37
|
-
@filenames
|
38
|
-
end
|
39
22
|
|
40
|
-
|
41
|
-
|
42
|
-
add_help_option(parser, flag_matchers)
|
43
|
-
add_version_option(parser, flag_matchers)
|
44
|
-
end
|
45
|
-
|
46
|
-
def add_files_option(parser, flag_matchers)
|
47
|
-
flag_matchers.push("-f \\S+")
|
48
|
-
parser.on("-f FILES", Array, "List of env files to parse") do |list|
|
49
|
-
@filenames = list
|
23
|
+
on("-o", "--overload", "override existing ENV variables") do
|
24
|
+
@overload = true
|
50
25
|
end
|
51
|
-
end
|
52
26
|
|
53
|
-
|
54
|
-
|
55
|
-
parser.on("-h", "--help", "Display help") do
|
56
|
-
puts parser
|
27
|
+
on("-h", "--help", "Display help") do
|
28
|
+
puts self
|
57
29
|
exit
|
58
30
|
end
|
59
|
-
end
|
60
31
|
|
61
|
-
|
62
|
-
flag_matchers.push("-v", "--version")
|
63
|
-
parser.on("-v", "--version", "Show version") do
|
32
|
+
on("-v", "--version", "Show version") do
|
64
33
|
puts "dotenv #{Dotenv::VERSION}"
|
65
34
|
exit
|
66
35
|
end
|
67
|
-
end
|
68
|
-
|
69
|
-
# Detect dotenv flags vs executable args so we can parse properly and still
|
70
|
-
# take advantage of OptionParser for dotenv flags
|
71
|
-
def split_argv(arg_string, matchers)
|
72
|
-
matcher = /^((?:#{matchers.join("|")})\s?)?(.+)?$/
|
73
|
-
data = matcher.match(arg_string)
|
74
|
-
dotenv_args = []
|
75
|
-
exec_args = []
|
76
36
|
|
77
|
-
|
78
|
-
|
79
|
-
|
37
|
+
on("-t", "--template=FILE", "Create a template env file") do |file|
|
38
|
+
template = Dotenv::EnvTemplate.new(file)
|
39
|
+
template.create_template
|
80
40
|
end
|
81
41
|
|
82
|
-
|
42
|
+
order!(@argv)
|
83
43
|
end
|
84
44
|
|
85
|
-
def
|
86
|
-
|
87
|
-
|
88
|
-
|
45
|
+
def run
|
46
|
+
if @overload
|
47
|
+
Dotenv.overload!(*@filenames)
|
48
|
+
else
|
49
|
+
Dotenv.load!(*@filenames)
|
89
50
|
end
|
51
|
+
rescue Errno::ENOENT => e
|
52
|
+
abort e.message
|
53
|
+
else
|
54
|
+
exec(*@argv) unless @argv.empty?
|
90
55
|
end
|
91
56
|
end
|
92
57
|
end
|
data/lib/dotenv/missing_keys.rb
CHANGED
data/lib/dotenv/parser.rb
CHANGED
@@ -12,21 +12,21 @@ module Dotenv
|
|
12
12
|
[Dotenv::Substitutions::Variable, Dotenv::Substitutions::Command]
|
13
13
|
|
14
14
|
LINE = /
|
15
|
-
(?:^|\A)
|
16
|
-
\s*
|
17
|
-
(?:export\s+)?
|
18
|
-
([\w
|
19
|
-
(?:\s*=\s*?|:\s+?)
|
20
|
-
(
|
21
|
-
'(?:\\'|[^'])*' # single quoted value
|
22
|
-
|
|
23
|
-
"(?:\\"|[^"])*" # double quoted value
|
24
|
-
|
|
25
|
-
[^\#\r\n]+
|
26
|
-
)?
|
27
|
-
\s*
|
28
|
-
(?:\#.*)?
|
29
|
-
(?:$|\z)
|
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
30
|
/x
|
31
31
|
|
32
32
|
class << self
|
@@ -70,17 +70,9 @@ module Dotenv
|
|
70
70
|
def parse_value(value)
|
71
71
|
# Remove surrounding quotes
|
72
72
|
value = value.strip.sub(/\A(['"])(.*)\1\z/m, '\2')
|
73
|
-
|
74
|
-
|
75
|
-
|
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
|
73
|
+
maybe_quote = Regexp.last_match(1)
|
74
|
+
value = unescape_value(value, maybe_quote)
|
75
|
+
perform_substitutions(value, maybe_quote)
|
84
76
|
end
|
85
77
|
|
86
78
|
def unescape_characters(value)
|
@@ -92,7 +84,26 @@ module Dotenv
|
|
92
84
|
end
|
93
85
|
|
94
86
|
def variable_not_set?(line)
|
95
|
-
!line.split[1
|
87
|
+
!line.split[1..].all? { |var| @hash.member?(var) }
|
88
|
+
end
|
89
|
+
|
90
|
+
def unescape_value(value, maybe_quote)
|
91
|
+
if maybe_quote == '"'
|
92
|
+
unescape_characters(expand_newlines(value))
|
93
|
+
elsif maybe_quote.nil?
|
94
|
+
unescape_characters(value)
|
95
|
+
else
|
96
|
+
value
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
def perform_substitutions(value, maybe_quote)
|
101
|
+
if maybe_quote != "'"
|
102
|
+
self.class.substitutions.each do |proc|
|
103
|
+
value = proc.call(value, @hash, @is_load)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
value
|
96
107
|
end
|
97
108
|
end
|
98
109
|
end
|
@@ -13,7 +13,7 @@ module Dotenv
|
|
13
13
|
\$ # literal $
|
14
14
|
(?<cmd> # collect command content for eval
|
15
15
|
\( # require opening paren
|
16
|
-
([^()]|\g<cmd>)+ # allow any number of non-parens, or balanced
|
16
|
+
(?:[^()]|\g<cmd>)+ # allow any number of non-parens, or balanced
|
17
17
|
# parens (by nesting the <cmd> expression
|
18
18
|
# recursively)
|
19
19
|
\) # require closing paren
|
@@ -28,7 +28,7 @@ module Dotenv
|
|
28
28
|
|
29
29
|
if $LAST_MATCH_INFO[:backslash]
|
30
30
|
# Command is escaped, don't replace it.
|
31
|
-
$LAST_MATCH_INFO[0][1
|
31
|
+
$LAST_MATCH_INFO[0][1..]
|
32
32
|
else
|
33
33
|
# Execute the command and return the value
|
34
34
|
`#{command}`.chomp
|
@@ -19,11 +19,7 @@ module Dotenv
|
|
19
19
|
/xi
|
20
20
|
|
21
21
|
def call(value, env, is_load)
|
22
|
-
combined_env =
|
23
|
-
env.merge(ENV)
|
24
|
-
else
|
25
|
-
ENV.to_h.merge(env)
|
26
|
-
end
|
22
|
+
combined_env = is_load ? env.merge(ENV) : ENV.to_h.merge(env)
|
27
23
|
value.gsub(VARIABLE) do |variable|
|
28
24
|
match = $LAST_MATCH_INFO
|
29
25
|
substitute(match, variable, combined_env)
|
@@ -33,8 +29,8 @@ module Dotenv
|
|
33
29
|
private
|
34
30
|
|
35
31
|
def substitute(match, variable, env)
|
36
|
-
if match[1] ==
|
37
|
-
variable[1
|
32
|
+
if match[1] == "\\"
|
33
|
+
variable[1..]
|
38
34
|
elsif match[3]
|
39
35
|
env.fetch(match[3], "")
|
40
36
|
else
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Dotenv
|
2
|
+
EXPORT_COMMAND = "export ".freeze
|
3
|
+
# Class for creating a template from a env file
|
4
|
+
class EnvTemplate
|
5
|
+
def initialize(env_file)
|
6
|
+
@env_file = env_file
|
7
|
+
end
|
8
|
+
|
9
|
+
def create_template
|
10
|
+
File.open(@env_file, "r") do |env_file|
|
11
|
+
File.open("#{@env_file}.template", "w") do |env_template|
|
12
|
+
env_file.each do |line|
|
13
|
+
env_template.puts template_line(line)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def template_line(line)
|
20
|
+
var, value = line.split("=")
|
21
|
+
template = var.gsub(EXPORT_COMMAND, "")
|
22
|
+
is_a_comment = var.strip[0].eql?("#")
|
23
|
+
value.nil? || is_a_comment ? line : "#{var}=#{template}"
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/lib/dotenv/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dotenv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.
|
4
|
+
version: 2.8.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandon Keepers
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2022-07-26 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rake
|
@@ -39,19 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: '0'
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: standard
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
|
-
- - "
|
45
|
+
- - ">="
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: 0
|
47
|
+
version: '0'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
|
-
- - "
|
52
|
+
- - ">="
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: 0
|
54
|
+
version: '0'
|
55
55
|
description: Loads environment variables from `.env`.
|
56
56
|
email:
|
57
57
|
- brandon@opensoul.org
|
@@ -72,12 +72,13 @@ files:
|
|
72
72
|
- lib/dotenv/substitutions/command.rb
|
73
73
|
- lib/dotenv/substitutions/variable.rb
|
74
74
|
- lib/dotenv/tasks.rb
|
75
|
+
- lib/dotenv/template.rb
|
75
76
|
- lib/dotenv/version.rb
|
76
77
|
homepage: https://github.com/bkeepers/dotenv
|
77
78
|
licenses:
|
78
79
|
- MIT
|
79
80
|
metadata: {}
|
80
|
-
post_install_message:
|
81
|
+
post_install_message:
|
81
82
|
rdoc_options: []
|
82
83
|
require_paths:
|
83
84
|
- lib
|
@@ -92,8 +93,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
92
93
|
- !ruby/object:Gem::Version
|
93
94
|
version: '0'
|
94
95
|
requirements: []
|
95
|
-
rubygems_version: 3.
|
96
|
-
signing_key:
|
96
|
+
rubygems_version: 3.2.32
|
97
|
+
signing_key:
|
97
98
|
specification_version: 4
|
98
99
|
summary: Loads environment variables from `.env`.
|
99
100
|
test_files: []
|