dotenv but 3 lines of ruby
KW Stannard

KW Stannard @kwstannard

About: Developer. Design pattern enthusiast. Tilting at Agile practices.

Joined:
Sep 9, 2019

dotenv but 3 lines of ruby

Publish Date: Oct 17 '19
12 4

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

Comments 4 total

  • Ben Curtis
    Ben CurtisDec 5, 2019

    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.

    • KW Stannard
      KW StannardDec 5, 2019

      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.

    • KW Stannard
      KW StannardDec 5, 2019

      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)
      
  • Grachev Mikhail
    Grachev MikhailOct 28, 2020

    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.

Add comment