leiningen

N.B. The maintainers are on #leiningen on Libera chat IRC. Go there for direct support/bug reports.
nachos 2020-06-22T13:45:08.270600Z

Is there a way to set the environment variable before lein test runs?

jumar 2020-06-22T14:07:57.271300Z

MYENV=1 lein test ?

2020-06-22T14:14:44.272400Z

There are plugins that set environment variables, I don't know which is best though. Environment variables are sadly not first class at all in the jvm without third party extensions with limited cross platform support.

nachos 2020-06-22T14:30:16.273900Z

@noisesmith Could you recommend one or two which would do this? I am looking for something that I can configure like this

:profiles {:test {:env {"MYENV" "test"
                  :dependencies [[ring/ring-mock "0.4.0"]]}}

2020-06-22T14:31:38.274300Z

lein-environ should work https://github.com/weavejester/environ#installation - it's not the only option though, I can't tell you which is better

2020-06-22T14:32:02.274800Z

note there's a lib and a plugin, for what you want the plugin is mandatory

2020-06-22T14:32:33.275300Z

(lein can only set the env vars by launching a second vm, that's what the plugin is for)

2020-06-22T14:52:05.276Z

You can be super hacky and set Java env variables at runtime in an impl-dependent way (that happens to work across any version in recent history that I’ve seen):

(defn set-env! [env-name env-val]
  (let [e (System/getenv)
        cl (.getClass e)
        field (doto (.getDeclaredField cl "m")
                (.setAccessible true))
        em (.get field e)]
    (.put em env-name env-val)))

2020-06-23T15:13:00.286400Z

@noisesmith pretty sure it works. It isn’t about setting the actual OS level. It doesn’t do that. Once these main java.lang classes load the process state from the OS - they don’t read it again - or write to it

2020-06-23T15:13:10.286600Z

At least not in terms of something like the env variables held in the hashtable

2020-06-23T15:13:37.286800Z

It looks to me to basically be a process-state-cache of env variables - and it’s always used later. If you are looking for OS-level side effects to the process state though - this above won’t work

2020-06-23T15:13:47.287Z

but things running within the same VM instance will use your changes

2020-06-23T15:13:57.287200Z

again though, it’s quite a hack

2020-06-23T15:14:19.287400Z

it made a few of our testing tools a bit more convenient to write a few things for - and we know it’s not a real API and we could have to change at some point

2020-06-23T15:18:36.287600Z

right - this was answered by your later point about the field being mutated not effecting the actual process env, just an internal representation

2020-06-23T15:18:54.287800Z

I had asked that before I figured that out

2020-06-23T15:38:51.288300Z

Oh, sorry. Misread I guess.

2020-06-23T15:41:08.288500Z

it's OK - it's thread vs. main channel timing :D

2020-06-23T15:44:24.288700Z

concurrency troubles

2020-06-22T14:52:55.276200Z

oh, wow...

nachos 2020-06-22T15:11:28.277400Z

@mikerod Is it possible to set this before lein test starts?

2020-06-22T15:18:10.277500Z

I wonder if this works on windows (my understanding was that the jvm lacked setenv because win lacked that API...)

jumar 2020-06-22T15:19:03.278900Z

How do you use those env vars? Can system properties be used instead? (I do this with our config tests)

2020-06-22T15:20:47.280Z

lein-env, linked above, supports this. And something multiple libraries offer is a merge of config from a file, the environment, and jvm system properties, so that you can set things via env in prod, and use files and programmatic property setting for local dev.

2020-06-22T15:21:07.280300Z

env and aero each support some variant of that

2020-06-22T16:01:42.281200Z

@danisam17 yeah, it could be done as a :prep-tasks or something probably. I’m not sure this is the best approach to do things - I’ve used it but only in a testing tool with important caveats that I verified it worked on like JDK8 through 11 so far on an OpenJDK based JVM

2020-06-22T16:01:58.281600Z

the funny part of Java’s env variables is just that they are loaded and stored in a mutable hashtable

2020-06-22T16:02:08.282100Z

and after that - that’s the Java “source of truth”

2020-06-22T16:02:32.282700Z

so you can mutate it… (of course this does require open security priv’s, which you’d have in cases where you’re running the system etc)

2020-06-22T16:17:23.283300Z

oh so that technique isn't actually changing the process environment, just the mutable table that's used to look it up?

2020-06-22T20:15:30.283500Z

yep