Reputation: 13527
I have a clojure project using leiningen. I want to load environment variables from a file on nrepl start. I only want this to run on repl start because these environment variables are configured for local development.
The reason I don't want to use default params in edn config is that the environment variables can contain some sensitive info (even for local development) like API TOKENS which will differ for every developer. I do not want this to be commited. There will be a file "repl_env" which will contain all the development evn variables. This file will be added to .gitignore thus making sure that these are never commited.
I see there is :init
under :repl-options
but I am not sure how I can leverage it to load environment variables. Any suggestions?
Upvotes: 0
Views: 279
Reputation: 112
The repl will load the environment variables from the current shell session, what you need to do is to load all those environment variables when the user starts a new session, I'm assuming you are using a *nix
based OS, you can achieve this by exporting the variables inside the *rc
file.
At this point you have at least two flavors: bash
or zsh
, for both you use the same syntax but in different files, for zsh
you can add your variables into $HOME/.zshrc
:
# my awesome zshrc file
export MY_SUPER_SECRET_KEY=THISISASECRETKEY
export MY_SUPER_SECRET_VALUE=THISISASECRETVALUE
Now, every time the user starts a shell session, those values will be available for repl, of course each developer should add those values on theirs own file.
I'm using environ library, loading the library into the repl and asking to resolve those variables I got:
I guess you should have similar results using #env
from aero
.
Upvotes: 0
Reputation: 4901
Can you use System properties instead of environment variables? If so, here is how you can do it. System properties can be set using command line arguments to the JVM, so it is possible to do it using Leiningen.
Here is how I did it. I created a new project lein new syspropdemo
och edited the following files:
Added the line :profiles {:repl {:jvm-opts ["@sysprops.txt"]}}
to project.clj
and set the main namespace. The string @sysprops.txt
means that I want to read additional command line arguments from a file sysprops.txt
:
(defproject syspropdemo "0.1.0-SNAPSHOT"
:description "FIXME: write description"
:url "http://example.com/FIXME"
:license {:name "EPL-2.0 OR GPL-2.0-or-later WITH Classpath-exception-2.0"
:url "https://www.eclipse.org/legal/epl-2.0/"}
:profiles {:repl {:jvm-opts ["@sysprops.txt"]}}
:main syspropdemo.core
:dependencies [[org.clojure/clojure "1.11.1"]]
:repl-options {:init-ns syspropdemo.core})
Created a basic -main
function in src/syspropdemo/core.clj
:
(ns syspropdemo.core)
(defn -main [& _args]
(println "The api key is" (System/getProperty "api_key")))
and also added a file sysprops.txt
in the project root that lists options to be used by the JVM:
-Dapi_key=xyz
where I use the -D
option to set a system property with key api_key
to have value xyz
.
$ lein run
The api key is nil
$ lein repl
nREPL server started on port 38171 on host 127.0.0.1
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Exit: Control+D or (exit) or (quit)
Results: Stored in vars *1, *2, *3, an exception in *e
syspropdemo.core=> (-main)
The api key is xyz
nil
In addition to the :repl
profile, there are other profiles too, such as :dev
, :test
, :production
, :uberjar
.
Upvotes: 0