The Pkg.test documentation states:
The tests are run by generating a temporary environment with only pkg
and its (recursive) dependencies in it.
I love this ability, it’s a entire setup and teardown of an environment, completely isolated from the environment you are currently in. I want to know how I can do this myself from within a Julia REPL?
It’s not the same as doing Pkg.activate()
, because that activated environment still exists within the current global REPL environment and all of it’s history.
I will try to read the source code of Pkg.test to find the answer, but maybe someone here knows the answer already.
I guess I would need to:
- Choose an environment (directory with Project.toml and optionally Manifest.toml)
- Pkg.instantiate it
- Startup Julia from within Julia with that environment activated, without enabling a global environment like
@v1.8
? Maybe also without startup.jl…
- run my desired code
- Shutdown the environment and return back to original Julia environment
For example I would like to do this for doctesting.
You can use the environment variable JULIA_LOAD_PATH
and the --startup-file
command-line flag to get this behavior.
In bash, it looks like this:
JULIA_LOAD_PATH="@" julia --project=. --startup-file=no run.jl
What this does:
-
sets JULIA_LOAD_PATH
so that Julia will only use the local Project.toml for finding packages, rather than also the global environment.
-
sets --startup-file=no
so that the user’s startup.jl
won’t affect the results.
-
sets the project to the current directory.
You can create a temporary environment with
]activate --temp
or
Pkg.activate(; temp = true)
I’m not sure what you mean here. The base Julia environment wouldn’t be active anymore since you’ve activated a different (temp) one, but maybe you mean the package using
s and objects created in the REPL so far?
In that case, yeah, you’d have to create a new fresh Julia process for this environment.
You can have a file, let’s say doctestsetup.jl
, with something like:
import Pkg
Pkg.activate(; temp = true)
Pkg.add("SomePackage")
and then execute
julia --startup-file=no -L doctestsetup.jl yourcodetotest.jl
(the startup-file
option shouldn’t be strictly necessary, since any code in startup.jl that you don’t want to run for normal files should be inside an atreplinit
block anyway, but let’s put that aside here.)
The temporary environment will be automatically cleaned up when that Julia process exits.
1 Like
Maybe I should simplify my question.
I want to have a function like:
sandboxed_doctest("MyPackage")
With behavior similar to Pkg.test("MyPackage")
Which we could probably generalize to something like:
run_in_sandbox_environment(project="MyPackage", subproject="/docs", file="doctest.jl")
Where doctest.jl calls Documenter.doctest or something.
I’m now down into Pkg.Operations.Test which sets up a sandbox
which seems to use the JULIA_LOAD_PATH trick proposed by @ericphanson as you can see on line 1506 in operations.jl.
P.S. I will also look into whether Documenter.doctest already sets up a sandboxed environment…