Mario Gil
Mario Gil

Reputation: 563

Does "vanilla" Ruby dotenv pick up any file other than .env?

I want to use environment-specific variables in my non-Rails Ruby application.

I tried different file names like .env.test.local, .env.local, .env.test

I tried using the Dotenv.load and require 'dotenv/load' approaches

This is how I wrap the task

require 'rspec'
require 'rack/test'
require 'rspec/core/rake_task'
require 'dotenv/tasks'

task test: :dotenv do
  RSpec::Core::RakeTask.new(:spec).run_task(verbose: true)
end

This is my server

require 'dotenv/load'
require 'sinatra'
require 'sinatra/reloader' if development?

set :bind, '0.0.0.0'

get ENV['API_URL'] do
  'Hello World!'
end

My .env.test file

API_URL=/api/v1

Expected behavior

The API_URL variable should be available to the code run by the :test task (using bundle exec rake test).

Observed behavior

An error caused because ENV['API_URL'] is null.

/Users/mariogil/.rvm/rubies/ruby-2.6.3/bin/ruby -I/Users/mariogil/.rvm/gems/ruby-2.6.3/gems/rspec-core-3.8.0/lib:/Users/mariogil/.rvm/gems/ruby-2.6.3/gems/rspec-support-3.8.0/lib /Users/mariogil/.rvm/gems/ruby-2.6.3/gems/rspec-core-3.8.0/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb

An error occurred while loading ./spec/server_spec.rb.
Failure/Error:
  get ENV['API_URL'] do
    'Hello World!'
  end

TypeError:
  NilClass can't be coerced into Mustermann::Pattern
# /Users/mariogil/.rvm/gems/ruby-2.6.3/gems/mustermann-1.0.3/lib/mustermann.rb:73:in `new'
# /Users/mariogil/.rvm/gems/ruby-2.6.3/gems/sinatra-2.0.5/lib/sinatra/base.rb:1641:in `compile'
# /Users/mariogil/.rvm/gems/ruby-2.6.3/gems/sinatra-2.0.5/lib/sinatra/base.rb:1629:in `compile!'
# /Users/mariogil/.rvm/gems/ruby-2.6.3/gems/sinatra-2.0.5/lib/sinatra/base.rb:1604:in `route'
# /Users/mariogil/.rvm/gems/ruby-2.6.3/gems/sinatra-2.0.5/lib/sinatra/base.rb:1386:in `get'
# /Users/mariogil/.rvm/gems/ruby-2.6.3/gems/sinatra-2.0.5/lib/sinatra/base.rb:1925:in `block (2 levels) in delegate'
# ./lib/server.rb:9:in `<top (required)>'
# ./spec/server_spec.rb:6:in `require'
# ./spec/server_spec.rb:6:in `<top (required)>'
No examples found.


Finished in 0.00026 seconds (files took 0.18951 seconds to load)
0 examples, 0 failures, 1 error occurred outside of examples

/Users/mariogil/.rvm/rubies/ruby-2.6.3/bin/ruby -I/Users/mariogil/.rvm/gems/ruby-2.6.3/gems/rspec-core-3.8.0/lib:/Users/mariogil/.rvm/gems/ruby-2.6.3/gems/rspec-support-3.8.0/lib /Users/mariogil/.rvm/gems/ruby-2.6.3/gems/rspec-core-3.8.0/exe/rspec --pattern spec/\*\*\{,/\*/\*\*\}/\*_spec.rb failed

See the repo

Upvotes: 1

Views: 980

Answers (1)

Mario Gil
Mario Gil

Reputation: 563

I came up with this workaround

require 'dotenv'
require 'sinatra'
require 'sinatra/reloader' if development?
Dotenv.load(".env.#{ENV['APP_ENV']}") # Remember to set your app environment

set :bind, '0.0.0.0'

get ENV['API_URL'] do
  'Hello World!'
end

It only works for .env.<ENVIROMENT> files. Maybe this could be wrapped in a function but I definitely would like this to be handled by the gem as in Rails applications, it makes more sense to me.

Upvotes: 2

Related Questions