How to set environment for local Julia package in module

I have a project which depends on a private module I am having. I have a folder in which I have my project script (“playground.jl”), which imports my module MyModule and its content. How do I make environments work for MyModule, so that it has its own one separate from my project. This is how normal Julia packages work, right?

Below is an image of my project, I try to fetch MyModule, but it depends on CSV (which is only in the MyModule Project.toml file, not the main one) which for some reason causes a crash.

1 Like

you can either use Pkg.activate(...) or start julia with julia --project=<path to project>

Would I do that within the MyModule file? Can I have the functions MyModule exports depend on its local environment (containing CSV), while my main project does not (i.e. this would use the environment with Plots only)?

MyModule should be a project, and it has its own Project.toml file.

If it needs CSV, CSV.jl should be recorded as a dependency in the toml, the easiest way to do it is

julia --project=<path to MyModule/>
]add CSV

Then the using CSV in your MyModule.jl would work without relying on your home environment having CSV. (your home environment would stack, so sometimes people would forget to include something in dependency, the recommendation is to keep your home environment as clean as possible, maybe include certain dev tools like Revise.jl, OhMyREPL.jl, JET.jl, but nothing else)


To run the playrgound.jl, you can do this.

julia --project=<path to MyModule/> playground.jl

Assuming playground.jl is the script you use solely to develop this pkg

1 Like

So, I thought I managed to do just that. I navigated to the MyModule folder and ran this:

As you can see in the previous screenshot, MyModule contains a project.toml with the following content:

[deps]
CSV = "336ed68f-0bac-5ca0-87d4-7b16caf5d00b"

However, this does not seem to work?

Gaussia, here’s a workflow that performs well for my needs.

After adding Revise to your default v1.X environment, in a ~/.julia/config/startup.jl file, have the following:

using Pkg
if isfile("Project.toml") && isfile("Manifest.toml")
    Pkg.activate(".")
end
try
    using Revise
catch e
    @warn "Error initializing Revise" exception=(e, catch_backtrace())
end

Now, make a package for a project.

cd ~/Documents
julia -e 'using Pkg; Pkg.generate("example")'

cd example
julia -e 'using Pkg; Pkg.activate(".");Pkg.instantiate()'

ls -l
Manifest.toml
Project.toml
src   <-- your module lives in this subdirectory

touch playground.jl  <-- your project script

ls -l
Manifest.toml
playground.jl
Project.toml
src

ls -l src
example.jl  <-- your module

Once this is set up, when julia is launched in the example directory, it should use the example project as the environment. Any packages added in the session should then be available to the playground.jl script or the example.jl module via a using X line in those files.

Your default v1.X environment, launched outside the example directory, should have only a couple packages used everywhere, such as Revise or Infiltrator. Remove other packages added by mistake to that default environment.

2 Likes

Thanks a lot.

But if I understand it right, this case still only has one environment (+ the default one)? I have on package (MyModule) which have some functions (requiring CSV). Somewhere else, I have a project that depends on MyModule’s functions. However, it does not need access to CSV (but e.g. Plots).

So I want environment 1:

  • Contains CSV an nothing else.
  • Is the Environment which my MyModule package should depend on.

Somewhere else on my computer, I have environment 2:

  • Contains Plots.
  • Does not need to have CSV.
  • This is the environment I run palyground.jl in, which fetches MyModule.

Neither of these would be my default environment.

When I try to create you example I create a single environment with all the stuff that both my package (MyModule) depends on and my project with fetched MyModule depends on (playground.jl).

I feel I am being really stupid and missing something obvious here?

if your env2 needs to use MyModule, you can do

]dev <path to MyModule/>

from env2 and then you can use whatever works in MyModule

Basically, env2 would have Plots.jl and MyModule.jl as direct dependency, and MyModule.jl works because it knows CSV.jl is in its dependency (CSV.jl is now an indirect dependency of env2)

6 Likes

That worked fabulous! Thanks everyone for the help :slight_smile: