dotenv 0.10.0 → 0.11.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Changelog.md +4 -0
- data/Gemfile +3 -1
- data/Guardfile +1 -1
- data/README.md +5 -32
- data/dotenv.gemspec +2 -0
- data/lib/dotenv-rails.rb +10 -0
- data/lib/dotenv.rb +16 -20
- data/lib/dotenv/capistrano.rb +5 -10
- data/lib/dotenv/environment.rb +2 -47
- data/lib/dotenv/parser.rb +63 -0
- data/lib/dotenv/railtie.rb +2 -4
- data/lib/dotenv/version.rb +1 -1
- data/spec/dotenv/environment_spec.rb +0 -121
- data/spec/dotenv/parser_spec.rb +129 -0
- data/spec/dotenv_spec.rb +9 -10
- metadata +20 -4
- data/lib/dotenv/capistrano/recipes.rb +0 -12
- data/lib/dotenv/format_error.rb +0 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 085d6d9b5a7558d0579157fa916768f6155185da
|
4
|
+
data.tar.gz: 6c7dcb253bdb822bb487bfd2fc549dbc1c0f1eb2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1b32c2962340f412985bd1eb0641b32bbd587e701439a767957c7c004583e744c2120a7fb222e1b432093b19b91348543ad8a93a52b8ee954f98576272b1d7d5
|
7
|
+
data.tar.gz: 376591ef2ad8da7dd026aa57df5f257c831d3e737431ff1ed280429f12f96eb96045ea30bafed20d24104e279fd2fc0785995c88712171f276a6da5a35d1e970
|
data/Changelog.md
CHANGED
data/Gemfile
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
gemspec :name => 'dotenv'
|
3
3
|
|
4
|
+
gem 'dotenv-deployment', :github => 'bkeepers/dotenv-deployment'
|
5
|
+
|
4
6
|
group :guard do
|
5
7
|
gem 'guard-rspec'
|
6
8
|
gem 'guard-bundler'
|
@@ -9,4 +11,4 @@ end
|
|
9
11
|
|
10
12
|
platforms :rbx do
|
11
13
|
gem 'rubysl', '~> 2.0' # if using anything in the ruby standard library
|
12
|
-
end
|
14
|
+
end
|
data/Guardfile
CHANGED
data/README.md
CHANGED
@@ -1,10 +1,13 @@
|
|
1
1
|
# dotenv [![Build Status](https://secure.travis-ci.org/bkeepers/dotenv.png?branch=master)](https://travis-ci.org/bkeepers/dotenv)
|
2
2
|
|
3
|
-
|
3
|
+
Shim to load environment variables from `.env` into `ENV` in *development*.
|
4
4
|
|
5
5
|
Storing [configuration in the environment](http://www.12factor.net/config) is one of the tenets of a [twelve-factor app](http://www.12factor.net/). Anything that is likely to change between deployment environments–such as resource handles for databases or credentials for external services–should be extracted from the code into environment variables.
|
6
6
|
|
7
|
-
But it is not always practical to set environment variables on development machines or continuous integration servers where multiple projects are run.
|
7
|
+
But it is not always practical to set environment variables on development machines or continuous integration servers where multiple projects are run. dotenv loads variables from a `.env` file into `ENV` when the environment is bootstrapped.
|
8
|
+
|
9
|
+
dotenv is intended to be used in development. If you would like to use it in production or other environments, see [dotenv-deployment](https://github.com/bkeepers/dotenv-deployment)
|
10
|
+
|
8
11
|
|
9
12
|
## Installation
|
10
13
|
|
@@ -64,13 +67,6 @@ S3_BUCKET=YOURS3BUCKET
|
|
64
67
|
SECRET_KEY=YOURSECRETKEYGOESHERE
|
65
68
|
```
|
66
69
|
|
67
|
-
You can also create files per environment, such as `.env.test`.
|
68
|
-
|
69
|
-
```shell
|
70
|
-
S3_BUCKET=tests3bucket
|
71
|
-
SECRET_KEY=testsecretkey
|
72
|
-
```
|
73
|
-
|
74
70
|
An alternate yaml-like syntax is supported:
|
75
71
|
|
76
72
|
```yaml
|
@@ -84,29 +80,6 @@ Whenever your application loads, these variables will be available in `ENV`:
|
|
84
80
|
config.fog_directory = ENV['S3_BUCKET']
|
85
81
|
```
|
86
82
|
|
87
|
-
## Capistrano integration
|
88
|
-
|
89
|
-
If you want to use Dotenv with Capistrano in your production environment, make sure the dotenv gem is included in your Gemfile `:production` group.
|
90
|
-
|
91
|
-
### Capistrano version 2.x.x
|
92
|
-
|
93
|
-
Add the gem to your `config/deploy.rb` file:
|
94
|
-
|
95
|
-
```ruby
|
96
|
-
require "dotenv/capistrano"
|
97
|
-
```
|
98
|
-
|
99
|
-
It will symlink the `.env` located in `/path/to/shared` in the new release.
|
100
|
-
|
101
|
-
|
102
|
-
### Capistrano version 3.x.x
|
103
|
-
|
104
|
-
Just add `.env` to the list of linked files, for example:
|
105
|
-
|
106
|
-
```ruby
|
107
|
-
set :linked_files, %w{config/database.yml .env}
|
108
|
-
```
|
109
|
-
|
110
83
|
## Should I commit my .env file?
|
111
84
|
|
112
85
|
It is recommended that you store development-only settings in your `.env` file, and commit it to your repository. Make sure that all your credentials for your development environment are different from your other deployments. This makes it easy for other developers to get started on your project, without compromising your credentials for other environments.
|
data/dotenv.gemspec
CHANGED
data/lib/dotenv-rails.rb
CHANGED
@@ -1 +1,11 @@
|
|
1
1
|
require 'dotenv/railtie'
|
2
|
+
|
3
|
+
env_file = ".env.#{Rails.env}"
|
4
|
+
if File.exists?(env_file) && !defined?(Dotenv::Deployment)
|
5
|
+
warn "Auto-loading of `#{env_file}` will be removed in 1.0. See " +
|
6
|
+
"https://github.com/bkeepers/dotenv-deployment if you would like to " +
|
7
|
+
"continue using this feature."
|
8
|
+
Dotenv.load ".env.#{Rails.env}"
|
9
|
+
end
|
10
|
+
|
11
|
+
Dotenv.load '.env'
|
data/lib/dotenv.rb
CHANGED
@@ -1,33 +1,29 @@
|
|
1
|
+
require 'dotenv/parser'
|
1
2
|
require 'dotenv/environment'
|
2
3
|
|
3
4
|
module Dotenv
|
4
5
|
def self.load(*filenames)
|
5
|
-
|
6
|
-
filename = File.expand_path filename
|
7
|
-
hash.merge(File.exists?(filename) ? Environment.new(filename).apply : {})
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
# same as `load`, but will override existing values in `ENV`
|
12
|
-
def self.overload(*filenames)
|
13
|
-
default_if_empty(filenames).inject({}) do |hash, filename|
|
14
|
-
filename = File.expand_path filename
|
15
|
-
hash.merge(File.exists?(filename) ? Environment.new(filename).apply! : {})
|
16
|
-
end
|
6
|
+
with(*filenames) { |f| Environment.new(f).apply if File.exists?(f) }
|
17
7
|
end
|
18
8
|
|
19
9
|
# same as `load`, but raises Errno::ENOENT if any files don't exist
|
20
10
|
def self.load!(*filenames)
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
)
|
11
|
+
with(*filenames) { |f| Environment.new(f).apply }
|
12
|
+
end
|
13
|
+
|
14
|
+
# same as `load`, but will override existing values in `ENV`
|
15
|
+
def self.overload(*filenames)
|
16
|
+
with(*filenames) { |f| Environment.new(f).apply! if File.exists?(f) }
|
27
17
|
end
|
28
18
|
|
29
19
|
protected
|
30
|
-
|
31
|
-
|
20
|
+
|
21
|
+
def self.with(*filenames, &block)
|
22
|
+
filenames << '.env' if filenames.empty?
|
23
|
+
|
24
|
+
filenames.inject({}) do |hash, filename|
|
25
|
+
filename = File.expand_path filename
|
26
|
+
hash.merge(block.call(filename) || {})
|
27
|
+
end
|
32
28
|
end
|
33
29
|
end
|
data/lib/dotenv/capistrano.rb
CHANGED
@@ -1,11 +1,6 @@
|
|
1
|
-
|
1
|
+
warn "Capistrano support has been moved to the dotenv-deployment gem. Add it " +
|
2
|
+
"to your Gemfile and change the require to 'dotenv/deployment/capistrano'. " +
|
3
|
+
"See https://github.com/bkeepers/dotenv-deployment#capistrano."
|
2
4
|
|
3
|
-
|
4
|
-
|
5
|
-
else
|
6
|
-
require 'dotenv/capistrano/recipes'
|
7
|
-
|
8
|
-
Capistrano::Configuration.instance(:must_exist).load do
|
9
|
-
before "deploy:finalize_update", "dotenv:symlink"
|
10
|
-
end
|
11
|
-
end
|
5
|
+
# This will be removed in 1.0
|
6
|
+
require 'dotenv/deployment/capistrano'
|
data/lib/dotenv/environment.rb
CHANGED
@@ -1,28 +1,5 @@
|
|
1
|
-
require 'dotenv/format_error'
|
2
|
-
require 'dotenv/substitutions/variable'
|
3
|
-
if RUBY_VERSION > '1.8.7'
|
4
|
-
require 'dotenv/substitutions/command'
|
5
|
-
end
|
6
|
-
|
7
1
|
module Dotenv
|
8
2
|
class Environment < Hash
|
9
|
-
@@substitutions = Substitutions.constants.map { |const| Substitutions.const_get(const) }
|
10
|
-
|
11
|
-
LINE = /
|
12
|
-
\A
|
13
|
-
(?:export\s+)? # optional export
|
14
|
-
([\w\.]+) # key
|
15
|
-
(?:\s*=\s*|:\s+?) # separator
|
16
|
-
( # optional value begin
|
17
|
-
'(?:\'|[^'])*' # single quoted value
|
18
|
-
| # or
|
19
|
-
"(?:\"|[^"])*" # double quoted value
|
20
|
-
| # or
|
21
|
-
[^#\n]+ # unquoted value
|
22
|
-
)? # value end
|
23
|
-
(?:\s*\#.*)? # optional comment
|
24
|
-
\z
|
25
|
-
/x
|
26
3
|
|
27
4
|
def initialize(filename)
|
28
5
|
@filename = filename
|
@@ -30,33 +7,11 @@ module Dotenv
|
|
30
7
|
end
|
31
8
|
|
32
9
|
def load
|
33
|
-
read
|
34
|
-
if match = line.match(LINE)
|
35
|
-
key, value = match.captures
|
36
|
-
|
37
|
-
value ||= ''
|
38
|
-
# Remove surrounding quotes
|
39
|
-
value = value.strip.sub(/\A(['"])(.*)\1\z/, '\2')
|
40
|
-
|
41
|
-
if $1 == '"'
|
42
|
-
value = value.gsub('\n', "\n")
|
43
|
-
# Unescape all characters except $ so variables can be escaped properly
|
44
|
-
value = value.gsub(/\\([^$])/, '\1')
|
45
|
-
end
|
46
|
-
|
47
|
-
@@substitutions.each do |proc|
|
48
|
-
value = proc.call(value, self)
|
49
|
-
end
|
50
|
-
|
51
|
-
self[key] = value
|
52
|
-
elsif line !~ /\A\s*(?:#.*)?\z/ # not comment or blank line
|
53
|
-
raise FormatError, "Line #{line.inspect} doesn't match format"
|
54
|
-
end
|
55
|
-
end
|
10
|
+
update Parser.call(read)
|
56
11
|
end
|
57
12
|
|
58
13
|
def read
|
59
|
-
File.read(@filename)
|
14
|
+
File.read(@filename)
|
60
15
|
end
|
61
16
|
|
62
17
|
def apply
|
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'dotenv/substitutions/variable'
|
2
|
+
if RUBY_VERSION > '1.8.7'
|
3
|
+
require 'dotenv/substitutions/command'
|
4
|
+
end
|
5
|
+
|
6
|
+
module Dotenv
|
7
|
+
class FormatError < SyntaxError; end
|
8
|
+
|
9
|
+
class Parser
|
10
|
+
@@substitutions = Substitutions.constants.map { |const| Substitutions.const_get(const) }
|
11
|
+
|
12
|
+
LINE = /
|
13
|
+
\A
|
14
|
+
(?:export\s+)? # optional export
|
15
|
+
([\w\.]+) # key
|
16
|
+
(?:\s*=\s*|:\s+?) # separator
|
17
|
+
( # optional value begin
|
18
|
+
'(?:\'|[^'])*' # single quoted value
|
19
|
+
| # or
|
20
|
+
"(?:\"|[^"])*" # double quoted value
|
21
|
+
| # or
|
22
|
+
[^#\n]+ # unquoted value
|
23
|
+
)? # value end
|
24
|
+
(?:\s*\#.*)? # optional comment
|
25
|
+
\z
|
26
|
+
/x
|
27
|
+
|
28
|
+
def self.call(string)
|
29
|
+
new(string).call
|
30
|
+
end
|
31
|
+
|
32
|
+
def initialize(string)
|
33
|
+
@string = string
|
34
|
+
end
|
35
|
+
|
36
|
+
def call
|
37
|
+
@string.split("\n").inject({}) do |hash, line|
|
38
|
+
if match = line.match(LINE)
|
39
|
+
key, value = match.captures
|
40
|
+
|
41
|
+
value ||= ''
|
42
|
+
# Remove surrounding quotes
|
43
|
+
value = value.strip.sub(/\A(['"])(.*)\1\z/, '\2')
|
44
|
+
|
45
|
+
if $1 == '"'
|
46
|
+
value = value.gsub('\n', "\n")
|
47
|
+
# Unescape all characters except $ so variables can be escaped properly
|
48
|
+
value = value.gsub(/\\([^$])/, '\1')
|
49
|
+
end
|
50
|
+
|
51
|
+
@@substitutions.each do |proc|
|
52
|
+
value = proc.call(value, hash)
|
53
|
+
end
|
54
|
+
|
55
|
+
hash[key] = value
|
56
|
+
elsif line !~ /\A\s*(?:#.*)?\z/ # not comment or blank line
|
57
|
+
raise FormatError, "Line #{line.inspect} doesn't match format"
|
58
|
+
end
|
59
|
+
hash
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
end
|
data/lib/dotenv/railtie.rb
CHANGED
@@ -3,12 +3,10 @@ require 'dotenv'
|
|
3
3
|
module Dotenv
|
4
4
|
class Railtie < Rails::Railtie
|
5
5
|
rake_tasks do
|
6
|
-
desc 'Load environment settings from .env'
|
7
6
|
task :dotenv do
|
8
|
-
|
7
|
+
# If the dotenv task is defined, then dotenv has already been loaded.
|
8
|
+
warn "The `dotenv` task is no longer needed and will be removed in 1.0."
|
9
9
|
end
|
10
10
|
end
|
11
11
|
end
|
12
12
|
end
|
13
|
-
|
14
|
-
Dotenv.load ".env.#{Rails.env}", '.env'
|
data/lib/dotenv/version.rb
CHANGED
@@ -42,127 +42,6 @@ describe Dotenv::Environment do
|
|
42
42
|
end
|
43
43
|
end
|
44
44
|
|
45
|
-
it 'parses unquoted values' do
|
46
|
-
expect(env('FOO=bar')).to eql('FOO' => 'bar')
|
47
|
-
end
|
48
|
-
|
49
|
-
it 'parses values with spaces around equal sign' do
|
50
|
-
expect(env("FOO =bar")).to eql('FOO' => 'bar')
|
51
|
-
expect(env("FOO= bar")).to eql('FOO' => 'bar')
|
52
|
-
end
|
53
|
-
|
54
|
-
it 'parses double quoted values' do
|
55
|
-
expect(env('FOO="bar"')).to eql('FOO' => 'bar')
|
56
|
-
end
|
57
|
-
|
58
|
-
it 'parses single quoted values' do
|
59
|
-
expect(env("FOO='bar'")).to eql('FOO' => 'bar')
|
60
|
-
end
|
61
|
-
|
62
|
-
it 'parses escaped double quotes' do
|
63
|
-
expect(env('FOO="escaped\"bar"')).to eql('FOO' => 'escaped"bar')
|
64
|
-
end
|
65
|
-
|
66
|
-
it 'parses empty values' do
|
67
|
-
expect(env('FOO=')).to eql('FOO' => '')
|
68
|
-
end
|
69
|
-
|
70
|
-
it 'expands variables found in values' do
|
71
|
-
expect(env("FOO=test\nBAR=$FOO")).to eql('FOO' => 'test', 'BAR' => 'test')
|
72
|
-
end
|
73
|
-
|
74
|
-
it 'parses variables wrapped in brackets' do
|
75
|
-
expect(env("FOO=test\nBAR=${FOO}bar")).to eql('FOO' => 'test', 'BAR' => 'testbar')
|
76
|
-
end
|
77
|
-
|
78
|
-
it 'reads variables from ENV when expanding if not found in local env' do
|
79
|
-
ENV['FOO'] = 'test'
|
80
|
-
expect(env('BAR=$FOO')).to eql('BAR' => 'test')
|
81
|
-
end
|
82
|
-
|
83
|
-
it 'expands undefined variables to an empty string' do
|
84
|
-
expect(env('BAR=$FOO')).to eql('BAR' => '')
|
85
|
-
end
|
86
|
-
|
87
|
-
it 'expands variables in quoted strings' do
|
88
|
-
expect(env("FOO=test\nBAR='quote $FOO'")).to eql('FOO' => 'test', 'BAR' => 'quote test')
|
89
|
-
end
|
90
|
-
|
91
|
-
it 'does not expand escaped variables' do
|
92
|
-
expect(env('FOO="foo\$BAR"')).to eql('FOO' => 'foo$BAR')
|
93
|
-
expect(env('FOO="foo\${BAR}"')).to eql('FOO' => 'foo${BAR}')
|
94
|
-
end
|
95
|
-
|
96
|
-
it 'parses yaml style options' do
|
97
|
-
expect(env('OPTION_A: 1')).to eql('OPTION_A' => '1')
|
98
|
-
end
|
99
|
-
|
100
|
-
it 'parses export keyword' do
|
101
|
-
expect(env('export OPTION_A=2')).to eql('OPTION_A' => '2')
|
102
|
-
end
|
103
|
-
|
104
|
-
it 'expands newlines in quoted strings' do
|
105
|
-
expect(env('FOO="bar\nbaz"')).to eql('FOO' => "bar\nbaz")
|
106
|
-
end
|
107
|
-
|
108
|
-
it 'parses variables with "." in the name' do
|
109
|
-
expect(env('FOO.BAR=foobar')).to eql('FOO.BAR' => 'foobar')
|
110
|
-
end
|
111
|
-
|
112
|
-
it 'strips unquoted values' do
|
113
|
-
expect(env('foo=bar ')).to eql('foo' => 'bar') # not 'bar '
|
114
|
-
end
|
115
|
-
|
116
|
-
it 'throws an error if line format is incorrect' do
|
117
|
-
expect{env('lol$wut')}.to raise_error(Dotenv::FormatError)
|
118
|
-
end
|
119
|
-
|
120
|
-
it 'ignores empty lines' do
|
121
|
-
expect(env("\n \t \nfoo=bar\n \nfizz=buzz")).to eql('foo' => 'bar', 'fizz' => 'buzz')
|
122
|
-
end
|
123
|
-
|
124
|
-
it 'ignores inline comments' do
|
125
|
-
expect(env("foo=bar # this is foo")).to eql('foo' => 'bar')
|
126
|
-
end
|
127
|
-
|
128
|
-
it 'allows # in quoted value' do
|
129
|
-
expect(env('foo="bar#baz" # comment')).to eql('foo' => 'bar#baz')
|
130
|
-
end
|
131
|
-
|
132
|
-
it 'ignores comment lines' do
|
133
|
-
expect(env("\n\n\n # HERE GOES FOO \nfoo=bar")).to eql('foo' => 'bar')
|
134
|
-
end
|
135
|
-
|
136
|
-
it 'parses # in quoted values' do
|
137
|
-
expect(env('foo="ba#r"')).to eql('foo' => 'ba#r')
|
138
|
-
expect(env("foo='ba#r'")).to eql('foo' => 'ba#r')
|
139
|
-
end
|
140
|
-
|
141
|
-
if RUBY_VERSION > '1.8.7'
|
142
|
-
it 'parses shell commands interpolated in $()' do
|
143
|
-
expect(env('ruby_v=$(ruby -v)')).to eql('ruby_v' => RUBY_DESCRIPTION)
|
144
|
-
end
|
145
|
-
|
146
|
-
it 'allows balanced parentheses within interpolated shell commands' do
|
147
|
-
expect(env('ruby_v=$(echo "$(echo "$(echo "$(ruby -v)")")")')).to eql('ruby_v' => RUBY_DESCRIPTION)
|
148
|
-
end
|
149
|
-
|
150
|
-
it "doesn't interpolate shell commands when escape says not to" do
|
151
|
-
expect(env('ruby_v=escaped-\$(ruby -v)')).to eql('ruby_v' => 'escaped-$(ruby -v)')
|
152
|
-
end
|
153
|
-
|
154
|
-
it 'is not thrown off by quotes in interpolated shell commands' do
|
155
|
-
expect(env('interp=$(echo "Quotes won\'t be a problem")')['interp']).to eql("Quotes won't be a problem")
|
156
|
-
end
|
157
|
-
|
158
|
-
# This functionality is not supported on JRuby or Rubinius
|
159
|
-
if (!defined?(RUBY_ENGINE) || RUBY_ENGINE != 'jruby') && !defined?(Rubinius)
|
160
|
-
it 'substitutes shell variables within interpolated shell commands' do
|
161
|
-
expect(env(%(VAR1=var1\ninterp=$(echo "VAR1 is $VAR1")))['interp']).to eql("VAR1 is var1")
|
162
|
-
end
|
163
|
-
end
|
164
|
-
end
|
165
|
-
|
166
45
|
require 'tempfile'
|
167
46
|
def env(text)
|
168
47
|
file = Tempfile.new('dotenv')
|
@@ -0,0 +1,129 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Dotenv::Parser do
|
4
|
+
def env(string)
|
5
|
+
Dotenv::Parser.call(string)
|
6
|
+
end
|
7
|
+
|
8
|
+
it 'parses unquoted values' do
|
9
|
+
expect(env('FOO=bar')).to eql('FOO' => 'bar')
|
10
|
+
end
|
11
|
+
|
12
|
+
it 'parses values with spaces around equal sign' do
|
13
|
+
expect(env("FOO =bar")).to eql('FOO' => 'bar')
|
14
|
+
expect(env("FOO= bar")).to eql('FOO' => 'bar')
|
15
|
+
end
|
16
|
+
|
17
|
+
it 'parses double quoted values' do
|
18
|
+
expect(env('FOO="bar"')).to eql('FOO' => 'bar')
|
19
|
+
end
|
20
|
+
|
21
|
+
it 'parses single quoted values' do
|
22
|
+
expect(env("FOO='bar'")).to eql('FOO' => 'bar')
|
23
|
+
end
|
24
|
+
|
25
|
+
it 'parses escaped double quotes' do
|
26
|
+
expect(env('FOO="escaped\"bar"')).to eql('FOO' => 'escaped"bar')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'parses empty values' do
|
30
|
+
expect(env('FOO=')).to eql('FOO' => '')
|
31
|
+
end
|
32
|
+
|
33
|
+
it 'expands variables found in values' do
|
34
|
+
expect(env("FOO=test\nBAR=$FOO")).to eql('FOO' => 'test', 'BAR' => 'test')
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'parses variables wrapped in brackets' do
|
38
|
+
expect(env("FOO=test\nBAR=${FOO}bar")).to eql('FOO' => 'test', 'BAR' => 'testbar')
|
39
|
+
end
|
40
|
+
|
41
|
+
it 'reads variables from ENV when expanding if not found in local env' do
|
42
|
+
ENV['FOO'] = 'test'
|
43
|
+
expect(env('BAR=$FOO')).to eql('BAR' => 'test')
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'expands undefined variables to an empty string' do
|
47
|
+
expect(env('BAR=$FOO')).to eql('BAR' => '')
|
48
|
+
end
|
49
|
+
|
50
|
+
it 'expands variables in quoted strings' do
|
51
|
+
expect(env("FOO=test\nBAR='quote $FOO'")).to eql('FOO' => 'test', 'BAR' => 'quote test')
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'does not expand escaped variables' do
|
55
|
+
expect(env('FOO="foo\$BAR"')).to eql('FOO' => 'foo$BAR')
|
56
|
+
expect(env('FOO="foo\${BAR}"')).to eql('FOO' => 'foo${BAR}')
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'parses yaml style options' do
|
60
|
+
expect(env('OPTION_A: 1')).to eql('OPTION_A' => '1')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'parses export keyword' do
|
64
|
+
expect(env('export OPTION_A=2')).to eql('OPTION_A' => '2')
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'expands newlines in quoted strings' do
|
68
|
+
expect(env('FOO="bar\nbaz"')).to eql('FOO' => "bar\nbaz")
|
69
|
+
end
|
70
|
+
|
71
|
+
it 'parses variables with "." in the name' do
|
72
|
+
expect(env('FOO.BAR=foobar')).to eql('FOO.BAR' => 'foobar')
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'strips unquoted values' do
|
76
|
+
expect(env('foo=bar ')).to eql('foo' => 'bar') # not 'bar '
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'throws an error if line format is incorrect' do
|
80
|
+
expect{env('lol$wut')}.to raise_error(Dotenv::FormatError)
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'ignores empty lines' do
|
84
|
+
expect(env("\n \t \nfoo=bar\n \nfizz=buzz")).to eql('foo' => 'bar', 'fizz' => 'buzz')
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'ignores inline comments' do
|
88
|
+
expect(env("foo=bar # this is foo")).to eql('foo' => 'bar')
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'allows # in quoted value' do
|
92
|
+
expect(env('foo="bar#baz" # comment')).to eql('foo' => 'bar#baz')
|
93
|
+
end
|
94
|
+
|
95
|
+
it 'ignores comment lines' do
|
96
|
+
expect(env("\n\n\n # HERE GOES FOO \nfoo=bar")).to eql('foo' => 'bar')
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'parses # in quoted values' do
|
100
|
+
expect(env('foo="ba#r"')).to eql('foo' => 'ba#r')
|
101
|
+
expect(env("foo='ba#r'")).to eql('foo' => 'ba#r')
|
102
|
+
end
|
103
|
+
|
104
|
+
if RUBY_VERSION > '1.8.7'
|
105
|
+
it 'parses shell commands interpolated in $()' do
|
106
|
+
expect(env('ruby_v=$(ruby -v)')).to eql('ruby_v' => RUBY_DESCRIPTION)
|
107
|
+
end
|
108
|
+
|
109
|
+
it 'allows balanced parentheses within interpolated shell commands' do
|
110
|
+
expect(env('ruby_v=$(echo "$(echo "$(echo "$(ruby -v)")")")')).to eql('ruby_v' => RUBY_DESCRIPTION)
|
111
|
+
end
|
112
|
+
|
113
|
+
it "doesn't interpolate shell commands when escape says not to" do
|
114
|
+
expect(env('ruby_v=escaped-\$(ruby -v)')).to eql('ruby_v' => 'escaped-$(ruby -v)')
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'is not thrown off by quotes in interpolated shell commands' do
|
118
|
+
expect(env('interp=$(echo "Quotes won\'t be a problem")')['interp']).to eql("Quotes won't be a problem")
|
119
|
+
end
|
120
|
+
|
121
|
+
# This functionality is not supported on JRuby or Rubinius
|
122
|
+
if (!defined?(RUBY_ENGINE) || RUBY_ENGINE != 'jruby') && !defined?(Rubinius)
|
123
|
+
it 'substitutes shell variables within interpolated shell commands' do
|
124
|
+
expect(env(%(VAR1=var1\ninterp=$(echo "VAR1 is $VAR1")))['interp']).to eql("VAR1 is var1")
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
end
|
data/spec/dotenv_spec.rb
CHANGED
@@ -7,7 +7,7 @@ describe Dotenv do
|
|
7
7
|
|
8
8
|
it 'defaults to .env' do
|
9
9
|
expect(Dotenv::Environment).to receive(:new).with(expand('.env')).
|
10
|
-
and_return(double(:apply => {}))
|
10
|
+
and_return(double(:apply => {}, :apply! => {}))
|
11
11
|
subject
|
12
12
|
end
|
13
13
|
end
|
@@ -19,7 +19,7 @@ describe Dotenv do
|
|
19
19
|
expected = expand("~/.env")
|
20
20
|
allow(File).to receive(:exists?){ |arg| arg == expected }
|
21
21
|
expect(Dotenv::Environment).to receive(:new).with(expected).
|
22
|
-
and_return(double(:apply => {}))
|
22
|
+
and_return(double(:apply => {}, :apply! => {}))
|
23
23
|
subject
|
24
24
|
end
|
25
25
|
end
|
@@ -72,22 +72,21 @@ describe Dotenv do
|
|
72
72
|
context 'when one file exists and one does not' do
|
73
73
|
let(:env_files) { ['.env', '.env_does_not_exist'] }
|
74
74
|
|
75
|
-
it 'raises an Errno::ENOENT error
|
76
|
-
expect
|
77
|
-
expect do
|
78
|
-
subject
|
79
|
-
end.to raise_error(Errno::ENOENT)
|
80
|
-
end.to_not change { ENV.keys }
|
75
|
+
it 'raises an Errno::ENOENT error' do
|
76
|
+
expect { subject }.to raise_error(Errno::ENOENT)
|
81
77
|
end
|
82
78
|
end
|
83
79
|
end
|
84
80
|
|
85
81
|
describe 'overload' do
|
82
|
+
let(:env_files) { [fixture_path('plain.env')] }
|
83
|
+
subject { Dotenv.overload(*env_files) }
|
84
|
+
it_behaves_like 'load'
|
85
|
+
|
86
86
|
it 'overrides any existing ENV variables' do
|
87
87
|
ENV['OPTION_A'] = 'predefined'
|
88
|
-
path = fixture_path 'plain.env'
|
89
88
|
|
90
|
-
|
89
|
+
subject
|
91
90
|
|
92
91
|
expect(ENV['OPTION_A']).to eq('1')
|
93
92
|
end
|
metadata
CHANGED
@@ -1,15 +1,29 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: dotenv
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.11.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Brandon Keepers
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2014-
|
11
|
+
date: 2014-04-22 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: dotenv-deployment
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - '='
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: 0.0.1
|
20
|
+
type: :runtime
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - '='
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: 0.0.1
|
13
27
|
- !ruby/object:Gem::Dependency
|
14
28
|
name: rake
|
15
29
|
requirement: !ruby/object:Gem::Requirement
|
@@ -61,15 +75,15 @@ files:
|
|
61
75
|
- lib/dotenv-rails.rb
|
62
76
|
- lib/dotenv.rb
|
63
77
|
- lib/dotenv/capistrano.rb
|
64
|
-
- lib/dotenv/capistrano/recipes.rb
|
65
78
|
- lib/dotenv/environment.rb
|
66
|
-
- lib/dotenv/
|
79
|
+
- lib/dotenv/parser.rb
|
67
80
|
- lib/dotenv/railtie.rb
|
68
81
|
- lib/dotenv/substitutions/command.rb
|
69
82
|
- lib/dotenv/substitutions/variable.rb
|
70
83
|
- lib/dotenv/tasks.rb
|
71
84
|
- lib/dotenv/version.rb
|
72
85
|
- spec/dotenv/environment_spec.rb
|
86
|
+
- spec/dotenv/parser_spec.rb
|
73
87
|
- spec/dotenv_spec.rb
|
74
88
|
- spec/fixtures/exported.env
|
75
89
|
- spec/fixtures/plain.env
|
@@ -102,9 +116,11 @@ specification_version: 4
|
|
102
116
|
summary: Loads environment variables from `.env`.
|
103
117
|
test_files:
|
104
118
|
- spec/dotenv/environment_spec.rb
|
119
|
+
- spec/dotenv/parser_spec.rb
|
105
120
|
- spec/dotenv_spec.rb
|
106
121
|
- spec/fixtures/exported.env
|
107
122
|
- spec/fixtures/plain.env
|
108
123
|
- spec/fixtures/quoted.env
|
109
124
|
- spec/fixtures/yaml.env
|
110
125
|
- spec/spec_helper.rb
|
126
|
+
has_rdoc:
|
@@ -1,12 +0,0 @@
|
|
1
|
-
Capistrano::Configuration.instance(:must_exist).load do
|
2
|
-
_cset(:dotenv_path){ "#{shared_path}/.env" }
|
3
|
-
|
4
|
-
symlink_args = (role = fetch(:dotenv_role, nil) ? {:roles => role} : {})
|
5
|
-
|
6
|
-
namespace :dotenv do
|
7
|
-
desc "Symlink shared .env to current release"
|
8
|
-
task :symlink, symlink_args do
|
9
|
-
run "ln -nfs #{dotenv_path} #{release_path}/.env"
|
10
|
-
end
|
11
|
-
end
|
12
|
-
end
|
data/lib/dotenv/format_error.rb
DELETED