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.
@@ -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
- LINE = /
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.each do |line|
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.read(@filename).split("\n")
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
@@ -0,0 +1,2 @@
1
+ require "dotenv"
2
+ Dotenv.load
@@ -0,0 +1,10 @@
1
+ module Dotenv
2
+ class Error < StandardError; end
3
+
4
+ class MissingKeys < Error # :nodoc:
5
+ def initialize(keys)
6
+ key_word = "key#{keys.size > 1 ? 's' : ''}"
7
+ super("Missing required configuration #{key_word}: #{keys.inspect}")
8
+ end
9
+ end
10
+ end
@@ -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
@@ -1,7 +1,7 @@
1
- desc 'Load environment settings from .env'
1
+ desc "Load environment settings from .env"
2
2
  task :dotenv do
3
- require 'dotenv'
3
+ require "dotenv"
4
4
  Dotenv.load
5
5
  end
6
6
 
7
- task :environment => :dotenv
7
+ task environment: :dotenv
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Dotenv
2
- VERSION = '0.9.0'
2
+ VERSION = "2.7.6".freeze
3
3
  end
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: 0.9.0
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: 2013-08-29 00:00:00.000000000 Z
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/capistrano.rb
69
- - lib/dotenv/capistrano/recipes.rb
67
+ - lib/dotenv/cli.rb
70
68
  - lib/dotenv/environment.rb
71
- - lib/dotenv/format_error.rb
72
- - lib/dotenv/railtie.rb
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
- rubyforge_project:
102
- rubygems_version: 1.8.23
96
+ rubygems_version: 3.0.3
103
97
  signing_key:
104
- specification_version: 3
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: []