3 ms·
At Shopify, we do a similar thing using a tool we wrote called Shadowenv[1], which evaluates little programs to manipulate the environment on directory entry/ex
by burke 5y ago
At Shopify, we do a similar thing using a tool we wrote called Shadowenv[1], which evaluates little programs to manipulate the environment on directory entry/exit. It's a lot like direnv, but it can't do anything that makes it slow, and is guaranteed to run in at most 100ms (though it typically only takes a few)
When I set `ruby: 2.6.8` in my `dev.yml` file, for example, I get this Shadowenv program written out to `.shadowenv.d/550_dev_ruby.lisp`:
(provide "ruby" "2.6.8")
(when-let ((ruby-root (env/get "RUBY_ROOT")))
(env/remove-from-pathlist "PATH" (path-concat ruby-root "bin"))
(when-let ((gem-root (env/get "GEM_ROOT")))
(env/remove-from-pathlist "PATH" (path-concat gem-root "bin")))
(when-let ((gem-home (env/get "GEM_HOME")))
(env/remove-from-pathlist "PATH" (path-concat gem-home "bin"))))
(env/set "BUNDLE_PATH" ())
(env/set "GEM_PATH" ())
(env/set "GEM_HOME" ())
(env/set "RUBYOPT" ())
(env/set "RUBYLIB" ())
(env/set "RUBY_ROOT" "/opt/rubies/2.6.8")
(env/prepend-to-pathlist "PATH" "/opt/rubies/2.6.8/bin")
(env/set "RUBY_ENGINE" "ruby")
(env/set "RUBY_VERSION" "2.6.8")
(env/set "GEM_ROOT" "/opt/rubies/2.6.8/lib/ruby/gems/2.6.0")
(when-let ((gem-root (env/get "GEM_ROOT")))
(env/prepend-to-pathlist "GEM_PATH" gem-root)
(env/prepend-to-pathlist "PATH" (path-concat gem-root "bin")))
(let ((gem-home
(path-concat (env/get "HOME") ".gem" (env/get "RUBY_ENGINE") (env/get "RUBY_VERSION"))))
(do
(env/set "GEM_HOME" gem-home)
(env/prepend-to-pathlist "GEM_PATH" gem-home)
(env/prepend-to-pathlist "PATH" (path-concat gem-home "bin"))))
I really like this strategy. It's really nicely generalizable to any of these language runtimes that need to change on a per-project basis.
[1]: https://shopify.github.io/shadowenv/ https://shopify.github.io/shadowenv/
- ravi-delia 5y agoOh I like the look of this. Can't wait to try it out