123456789_123456789_123456789_123456789_123456789_

Class: ActiveSupport::DotEnvConfiguration

Relationships & Source Files
Super Chains via Extension / Inclusion / Inheritance
Class Chain:
Instance Chain:
Inherits: ActiveSupport::EnvConfiguration
Defined in: activesupport/lib/active_support/dot_env_configuration.rb

Overview

Provide an interface for accessing configuration options stored in a .env file. Keys are accepted as symbols and turned into upcased strings. Nesting is provided by double underscores.

This interface mirrors what is used for EnvConfiguration and EncryptedConfiguration and thus allows all three to serve as interchangeable backends for Rails.app.creds.

The .env file format supports:

  • Lines with KEY=value pairs
  • Comments starting with #
  • Empty lines (ignored)
  • Quoted values (single or double quotes)
  • Variable interpolation with $VAR syntax
  • Command execution with $(command) syntax

The command execution allows for easy integration with third-party credential providers, like 1password:

DB_HOST=$(op read op://Vault/item/value --=MyAccount)

When used inside Rails, the default path for the .env file will be Rails.root.join(".env"). Otherwise it must be passed in as path.

Examples:

require(:db_host)                                   # => value of DB_HOST from {.env}
require(:database, :host)                           # => value of DATABASE__HOST from {.env}
option(:debug)                                      # => value of DEBUG from {.env} or nil if missing
option(:debug, default: "true")                     # => value of DEBUG from {.env} or "true" if not found
option(:database, :host, default: -> { "missing" }) # => value of DATABASE__HOST from {.env} or "missing" if not found

Class Method Summary

Instance Method Summary

EnvConfiguration - Inherited

#keys

Returns an array of symbolized keys from the environment variables.

#option

Find an upcased and double-underscored-joined string-version of the key in ENV.

#reload

Reload the cached ENV values in case any of them changed or new ones were added during runtime.

#require

Find an upcased and double-underscored-joined string-version of the key in ENV.

#envify, #inspect

Constructor Details

.new(path) ⇒ DotEnvConfiguration

[ GitHub ]

  
# File 'activesupport/lib/active_support/dot_env_configuration.rb', line 40

def initialize(path)
  @path = path
  reload
end

Instance Method Details

#execute_commands(value) (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/dot_env_configuration.rb', line 93

def execute_commands(value)
  value.gsub(/\$\((.+?)\)/) { `#{$1}`.chomp }
end

#interpolate(value, envs) (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/dot_env_configuration.rb', line 97

def interpolate(value, envs)
  value.gsub(/\$\{([A-Za-z_][A-Za-z0-9_]*)\}/) { envs[$1] || "" }
end

#parse_env_file (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/dot_env_configuration.rb', line 51

def parse_env_file
  if File.exist?(@path.to_s)
    envs = {}

    File.foreach(@path) do |line|
      line = line.strip

      next if line.empty? || line.start_with?("#")

      # Match KEY=value pattern
      if line =~ /\A([A-Za-z_][A-Za-z0-9_]*)\s*=\s*(.*)\z/
        key, value = $1, $2
        envs[key] = interpolate(execute_commands(unquote(strip_inline_comment(value))), envs)
      end
    end

    envs
  else
    {}
  end
end

#reload

Reload the cached .env values in case the file changed during runtime.

[ GitHub ]

  
# File 'activesupport/lib/active_support/dot_env_configuration.rb', line 46

def reload
  @envs = parse_env_file
end

#strip_inline_comment(value) (private)

Strip a trailing " # comment" from an unquoted value, matching the common .env convention. Quoted values are left untouched so that a "#" inside quotes (e.g. PASS="a # b") is preserved, and a "#" that is not preceded by whitespace (e.g. URL=http://host#frag) stays part of the value.

[ GitHub ]

  
# File 'activesupport/lib/active_support/dot_env_configuration.rb', line 78

def strip_inline_comment(value)
  return value if value.start_with?('"', "'")
  value.sub(/\s+#.*\z/, "")
end

#unquote(value) (private)

[ GitHub ]

  
# File 'activesupport/lib/active_support/dot_env_configuration.rb', line 83

def unquote(value)
  if value.start_with?('"') && value.end_with?('"')
    value[1..-2].gsub('\n', "\n").gsub('\"', '"')
  elsif value.start_with?("'") && value.end_with?("'")
    value[1..-2]
  else
    value
  end
end