Find environment variables in Ruby projects
Every time i deal with a new (legacy/third-party) Ruby/Rails application i want to
try to deploy it somewhere real quick to test things out before i dig into the code.
In most cases the application is Heroku-friendly, i.e has a Procfile
or readme
instructions on how to start all necessary processes.
When it comes to deployment, often it takes a few failed attempts until you get things
right. Majority of those failures are usually related to missing environment variables
or other configuration settings. In development we mostly rely on having an .env
file wilh all the vars set for local work, but that file is never checked into
the repo, so in other words - you have to scan your whole application to find out
which environment variables need to be set before you can run the damn thing.
Let's automate this. In ruby code many components fetch variables from the ENV
object: ENV["MY_VAR"]
or ENV.fetch("MY_VAR")
. Later is better since it'll error
out when variable is not present. Next, to find out which files have any mention
of ENV
we can use grep
. As an example, i run the following command against
Gitlab's master branch:
grep -rnw . -e "ENV"
We'll see files where ENV is used (shortened):
./app/views/layouts/_search.html.haml:46: = button_tag 'Go' if ENV['RAILS_ENV'] == 'test'
./app/views/projects/merge_requests/_show.html.haml:50: .merge-request-tabs-holder{ class: ("js-tabs-affix" unless ENV['RAILS_ENV'] == 'test') }
./app/workers/post_receive.rb:15: Sidekiq.logger.info "changes: #{changes.inspect}" if ENV['SIDEKIQ_LOG_ARGUMENTS']
./bin/bundle:2:ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
./bin/pkgr_before_precompile.sh:10:config=$(echo '<% gitlab_url = URI(ENV["GITLAB_URL"] || "http://localhost:80") %>' | cat - config/gitlab.yml)
./bin/spring:6:unless (defined?(Spring) || ENV['ENABLE_SPRING'] != '1') && File.basename($0) != 'spring'
./config/application.rb:148: ENV['GITLAB_PATH_OUTSIDE_HOOK'] = ENV['PATH']
./config/boot.rb:6:require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
./config/database.yml.env:6: adapter: <%= ENV['GITLAB_DATABASE_ADAPTER'] || 'postgresql' %>
./config/database.yml.env:11: port: <%= ENV['GITLAB_DATABASE_PORT'] || '5432' %>
./config/database.yml.env:16: encoding: <%= ENV['GITLAB_DATABASE_ENCODING'] || 'unicode' %>
./config/database.yml.env:17: pool: <%= ENV['GITLAB_DATABASE_POOL'] || '10' %>
./config/environments/development.rb:41: config.action_mailer.perform_deliveries = (ENV['BOOTSTRAP'] != '1')
./config/initializers/0_post_deployment_migrations.rb:4:unless ENV['SKIP_POST_DEPLOYMENT_MIGRATIONS']
./config/initializers/1_settings.rb:4: source ENV.fetch('GITLAB_CONFIG') { "#{Rails.root}/config/gitlab.yml" }
Finally, if you really need a list of all vars, i wrote a small ruby script that does just that:
#!/usr/bin/env ruby
items = []
`grep -rnw . -e "ENV"`.split("\n").each do |line|
if line =~ /ENV.fetch\(['"](\w+)['"]\)/ || line =~ /ENV\[['"](\w+)['"]\]/
items << $1
end
end
if items.size > 0
puts "Found these environment variables:"
puts items.uniq.sort
else
puts "No mention of environment variables found"
end
In the output you'll see a list of all variables (shortened):
GITLAB_DATABASE_POOL
GITLAB_DATABASE_PORT
GITLAB_DATABASE_USERNAME
GITLAB_EMAIL_DISPLAY_NAME
GITLAB_EMAIL_FROM
GITLAB_EMAIL_REPLY_TO
GITLAB_EMAIL_SUBJECT_SUFFIX
GITLAB_HOST
GITLAB_PATH_OUTSIDE_HOOK
GITLAB_ROOT_EMAIL
GITLAB_ROOT_PASSWORD
GITLAB_UNICORN_MEMORY_MAX
GITLAB_UNICORN_MEMORY_MIN
GITLAB_URL
MAIL_ROOM_GITLAB_CONFIG_FILE
MYSQL_PWD
NAMESPACE
NO_KNAPSACK
Save the script somewhere in your system (maybe as /usr/local/bin/showenv
). Next time
you're in the project's root, just run it:
$ showenv
Bam. Easy Peasy.