module Dotenv
Shim to load environment variables from ‘.env files into `ENV`.
Constants
- EXPORT_COMMAND
- Railtie
- SEMAPHORE
-
An internal monitor to synchronize access to ENV in multi-threaded environments.
- VERSION
Attributes
Public Instance Methods
Source
# File lib/dotenv.rb, line 18 def load(*filenames, overwrite: false, ignore: true) parse(*filenames, overwrite: overwrite, ignore: ignore) do |env| instrument(:load, env: env) do |payload| update(env, overwrite: overwrite) end end end
Loads environment variables from one or more ‘.env` files. See `#parse` for more details.
Source
# File lib/dotenv.rb, line 27 def load!(*filenames) load(*filenames, ignore: false) end
Same as ‘#load`, but raises Errno::ENOENT if any files don’t exist
Source
# File lib/dotenv.rb, line 116 def modify(env = {}, &block) SEMAPHORE.synchronize do diff = Dotenv::Diff.new update(env, overwrite: true) block.call ensure restore(diff.a, safe: true) end end
Modify ‘ENV` for the block and restore it to its previous state afterwards.
Note that the block is synchronized to prevent concurrent modifications to ‘ENV`, so multiple threads will be executed serially.
@param env [Hash] Hash of keys and values to set in ‘ENV`
Source
# File lib/dotenv.rb, line 32 def overwrite(*filenames) load(*filenames, overwrite: true) end
same as ‘#load`, but will overwrite existing values in `ENV`
Source
# File lib/dotenv.rb, line 38 def overwrite!(*filenames) load(*filenames, overwrite: true, ignore: false) end
same as ‘#overwrite`, but raises Errno::ENOENT if any files don’t exist
Source
# File lib/dotenv.rb, line 50 def parse(*filenames, overwrite: false, ignore: true, &block) filenames << ".env" if filenames.empty? filenames = filenames.reverse if overwrite filenames.reduce({}) do |hash, filename| begin env = Environment.new(File.expand_path(filename), overwrite: overwrite) env = block.call(env) if block rescue Errno::ENOENT, Errno::EISDIR raise unless ignore end hash.merge! env || {} end end
Parses the given files, yielding for each file if a block is given.
@param filenames [String, Array<String>] Files to parse @param overwrite [Boolean] Overwrite existing ‘ENV` values @param ignore [Boolean] Ignore non-existent files @param block [Proc] Block to yield for each parsed `Dotenv::Environment` @return [Hash] parsed key/value pairs
Source
# File lib/dotenv.rb, line 126 def require_keys(*keys) missing_keys = keys.flatten - ::ENV.keys return if missing_keys.empty? raise MissingKeys, missing_keys end
Source
# File lib/dotenv.rb, line 77 def restore(env = @diff&.a, safe: Thread.current == Thread.main) # No previously saved or provided state to restore return unless env diff = Dotenv::Diff.new(b: env) return unless diff.any? unless safe raise ThreadError, <<~EOE.tr("\n", " ") Dotenv.restore is not thread safe. Use `Dotenv.modify { }` to update ENV for the duration of the block in a thread safe manner, or call `Dotenv.restore(safe: true)` to ignore this error. EOE end instrument(:restore, diff: diff) { ENV.replace(env) } end
Restore ‘ENV` to a given state
@param env [Hash] Hash of keys and values to restore, defaults to the last saved state @param safe [Boolean] Is it safe to modify ‘ENV`? Defaults to `true` in the main thread, otherwise raises an error.
Source
# File lib/dotenv.rb, line 67 def save instrument(:save) do |payload| @diff = payload[:diff] = Dotenv::Diff.new end end
Save the current ‘ENV` to be restored later
Source
# File lib/dotenv.rb, line 98 def update(env = {}, overwrite: false) instrument(:update) do |payload| diff = payload[:diff] = Dotenv::Diff.new do ENV.update(env.transform_keys(&:to_s)) do |key, old_value, new_value| # This block is called when a key exists. Return the new value if overwrite is true. overwrite ? new_value : old_value end end diff.env end end
Update ‘ENV` with the given hash of keys and values
@param env [Hash] Hash of keys and values to set in ‘ENV` @param overwrite [Boolean] Overwrite existing `ENV` values
Private Instance Methods
Source
# File lib/dotenv.rb, line 134 def instrument(name, payload = {}, &block) if instrumenter instrumenter.instrument("#{name}.dotenv", payload, &block) else block&.call payload end end