DEV Community

loading...

dotenv but 3 lines of ruby

Kelly Stannard
Developer. Design pattern enthusiast. Tilting at Agile practices.
Updated on ・1 min read

edit: Thanks to Ben Curtis for inspiring me to cut this from 7 lines to 3.
edit2: More complex regexp to handle multiline vars.

Make an executable file with the following contents:

#!/usr/bin/env ruby

regexp = /^(?<a>\w+)=(?:'(?<b>.+?)'|"\g<b>"|\g<b>)$/m

ENV.update File.read(".env").scan(regexp).to_h if File.exist?(".env")
exec(ENV, *ARGV)
Enter fullscreen mode Exit fullscreen mode

Make an alias. Here is one with bundle exec also included.

alias be="/path/to/executable bundle exec"

Make an .env file.

echo HELLO=WORLD > .env

Run be bash -c 'echo $HELLO'

edit3: this has an added benefit of being language independent over the regular ruby dotenv as this is a shell program and ruby dotenv runs inside your ruby program.

edit4: do the following to have a .gitconfig like transversal up the parent directories.

#!/usr/bin/env ruby

require 'pathname'
env = Pathname.pwd.ascend.map{|x| x.join(".env")}.select(&:exist?).map(&:read).reverse.join

regexp = /^(?<a>\w+)=(?:'(?<b>.+?)'|"\g<b>"|\g<b>)$/m
ENV.update env.scan(regexp).to_h
exec(ENV, *ARGV)

Enter fullscreen mode Exit fullscreen mode

Discussion (4)

Collapse
stympy profile image
Ben Curtis

This is great! Here's an alternative to the 2 lines of code in the loop:

    ENV.update l.chomp.scan(/^(?:export )?(\w+)\s*=\s*(?:['"])?([^'"]+)/i).to_h

This change also handles .env files that have lines in the format of export FOO=bar.

Collapse
kwstannard profile image
Kelly Stannard Author

How about 3 lines or fairly readable ruby?

#!/usr/bin/env ruby

regexp = /^(\w+)=['"]?(.+?)['"]?$/

ENV.update File.read(".env").scan(regexp).to_h if File.exist?(".env")
exec(ENV, *ARGV)
Collapse
kwstannard profile image
Kelly Stannard Author

Nice!

I will personally leave out the export stuff because I don't actually need to be compatible with dotenv, but it would be nice for people who do.

Collapse
mgrachev profile image
Grachev Mikhail

In addition to using environment variables I can recommend the tool github.com/dotenv-linter/dotenv-li... - it’s a lightning-fast linter for .env files. Written in Rust.
Maybe it would be useful for you.