Module: Envi

Defined in:
lib/envi.rb

Overview

Envi is a simple module to define environment variable requirements, and to load those environment variables into Ruby constants. This is ideal for managing configuration settings using environment variables, as one would on Heroku.

Setup

The envars.yml file

First, define your requirements in a YAML file. By default, Envi will look for ./config/envars.yml. For example:

---
&defaults:
  - name: AWS_ACCESS_KEY
    message: Please provide your Amazon AWS credentials as environment variables.
  - name: AWS_ACCESS_SECRET
    message: Please provide your Amazon AWS credentials as environment variables.
  - name: HASHING_SALT
production:
  <<: *defaults
development:
  <<: *defaults

{: lang="yaml" }

You can define your required environment variables by name, and also provide an optional custom exception message to be used when that variable is not set.

Initializing Envi

To read the requirements and inspect the current environment variables, simply call Envi.init. This will raise an exception if requirements are not met. When working with Rails apps, you might want to use this is an initializer.

Providing environment variables in a file

A common pattern is to define custom environment variables in a .env file in your application's root directory. Other gems, such as [Foreman][] will use such a file to augment the environment before running processes. When in development mode, Envi can also do this for you. Simply tell it which file to use:

Envi.init parse: '.env'

{: lang="ruby" }

It is a good idea to not include such a file (which commonly contains application secrets) in source control.

Extending your Rails application configuration

Envi will expose all the loaded environment variables as constants in the Envi module, so you can access them as Envi::MY_VARIABLE. You could also opt to extend your Rails configuration object:

Envi.init use: MyApp::Application.config
MyApp::Application.config.my_variable # => ...

Author:

Constant Summary collapse

FileNotFound =

Special exception raised when required files could not be found. This is a library-specific wrapper around Errno::ENOENT.

Class.new(StandardError)
UnknownEnvironment =

Special exception raised when the currently configured environment name is not present in the configuration file.

Class.new(StandardError)
ENVI_DEFAULT_CONFIG_FILE =

Returns standard location to look for a configuration YAML file.

Returns:

  • (String)

    standard location to look for a configuration YAML file

'config/envars.yml'.freeze
ENVI_DEFAULT_ENVIRONMENT =

Returns the default environment to load from the configuration file.

Returns:

  • (String)

    the default environment to load from the configuration file

'production'.freeze
VERSION =

Returns Envi gem version in format major.minor.patch.

Returns:

  • (String)

    Envi gem version in format major.minor.patch

'0.0.1'.freeze

Class Method Summary collapse

Class Method Details

.config(options) ⇒ Object

Loads the YAML configuration file and returns the keys under the environment.

Parameters:

  • options (Hash)

Options Hash (options):

  • :config (String)

    path to the configuration file. Defaults to value of ENVI_DEFAULT_CONFIG_FILE

  • :enviroment (String)

    name of the application environment. Defaults to environment.

Raises:

  • (UnknownEnvironment)

    when the current environment is not defined in the configuration file.

See Also:



158
159
160
161
162
163
164
165
166
# File 'lib/envi.rb', line 158

def config(options)
  location = options.fetch(:config, ENVI_DEFAULT_CONFIG_FILE)
  env      = options.fetch(:environment, environment)
  YAML.load_file(location).fetch(env) do
    raise UnknownEnvironment, 'No configuration found for environment ' + environment
  end
rescue Errno::ENOENT => e
  raise FileNotFound, e
end

.environmentString

Returns the value of RACK_ENV, RAILS_ENV or ENVI_DEFAULT_ENVIRONMENT.

Returns:



169
170
171
# File 'lib/envi.rb', line 169

def environment
  ENV['RACK_ENV'] || ENV['RAILS_ENV'] || ENVI_DEFAULT_ENVIRONMENT
end

.init(options = {}) ⇒ Hash

Define the required environment variables defined in the configuration YAML file (or the :config option) as constants on the Envi module. Any previously defined constants will be removed.

Parameters:

  • options (Hash) (defaults to: {})

Options Hash (options):

  • :parse (String)

    path to a file to read extra environment variables from.

  • :use (Object)

    an object to set downcased properties on

  • :config (String)

    path to the configuration file. Defaults to value of ENVI_DEFAULT_CONFIG_FILE

  • :enviroment (String)

    name of the application environment. Defaults to environment.

Returns:

  • (Hash)

    the parsed YAML configuration file

Raises:

  • (NameError)

    when a required environment variable is not set.

  • (FileNotFound)

    when files in the :config or :parse options could not be found.

  • (UnknownEnvironment)

    when the current environment is not defined in the configuration file.



102
103
104
105
106
107
108
109
110
111
112
# File 'lib/envi.rb', line 102

def init(options = {})
  reset_consts
  parse_envars_from(options[:parse]) if options[:parse]
  config(options).each do |envar|
    name = envar.fetch('name')
    value = ENV.fetch(name) do
      raise NameError, envar.fetch('message', "Required environment variable #{name} is undefined")
    end
    set name, value, options
  end
end

.parse_envars_from(filename) ⇒ Object

Read and parse a given filename and extract environment variables from it.

Examples:

# in .env
FOO=bar

parse_envars_from('.env')
ENV['FOO'] # => 'bar'

Raises:



123
124
125
126
127
128
129
130
# File 'lib/envi.rb', line 123

def parse_envars_from(filename)
  contents = File.readlines(filename).each do |line|
    name, value = line.chomp.split('=', 2)
    ENV[name] = value
  end
rescue Errno::ENOENT => e
  raise FileNotFound, e
end

.reset_constsObject

Remove any constants previously defined with set.



174
175
176
177
178
# File 'lib/envi.rb', line 174

def reset_consts
  (@_envi_constants || []).each do |name|
    remove_const name if const_defined? name
  end
end

.set(name, value, options) ⇒ Object

Store a constant by its name and value by defining it as a constant in the Envi module. Optionally, this will call a setter method on the object in options[:use].

Parameters:

  • name (String)

    of the constant to define

  • value (String)

    of the constant to define

  • options (Hash)

Options Hash (options):

  • :use (Object)

    an object to set downcased properties on



140
141
142
143
144
145
146
# File 'lib/envi.rb', line 140

def set(name, value, options)
  if object = options[:use]
    object.send("#{name.downcase}=", value)
  end
  const_set name, value
  (@_envi_constants ||= []) << name
end