Understanding dependency "extras"

I have a package with a Project.toml file. In the [deps] section are listed the core dependencies of the package. In the [extras] section are listed some extra dependencies that some test and example scripts need. In particular I have the following:

[extras]
GLMakie = "e9467ef8-e4e7-5192-8a1a-b1aee30e663a"

[targets]
examples = ["GLMakie"]

The examples subfolder of my project contains some Julia scripts that depend on GLMakie. When I try to run scripts in that folder (I’m just hitting play in VSCode, on a particular file), I get an error saying the GLMakie package isn’t listed in my Project.toml file (which it clearly is). My expectation was that GLMakie would be available to files in the examples folder. The only way I’ve found to fix this, without adding GLMakie to the [deps] section, is to add it to the base environment for the version of Julia I’m currently using (v1.12). Once I do that, the scripts run as expected.

Are my expectations for how the environments should work wrong?

Per Legacy approach: target based test specific dependencies:

Note that the only supported targets are test and build , the latter of which (not recommended) can be used for any deps/build.jl scripts.

Workspaces are the current practice for more “targets”. The base environment workaround is just stacking your package’s environment on it, so there’s a risk of diverging GLMakie versions there.

Thanks. I’d seen the documentation on workspaces, and found it was lacking detail and a little unclear. I’ll have another read of it.

In super-short I would summarise the difference as follows:

With extras you specify everything in the main project file and it is a bit clumsy to add extra items – and you can just do extras for test

With Workspaces, you declare in the main folders project.toml which subfolders have their own project file – so the whole thing becomes a workspace. The sub projects maintain their own packages, but when resolving versions of packages, the whole set of projects (so all of the workspace) is used.

GLMakie becomes also available if you do:

using TestEnv; TestEnv.activate()

That requires having TestEnv in your global environment and also works with old Julia versions. If you are sure you will only use Julia 1.12, create a separate Project.toml file in your examples folder that references the main project like this:

[sources]
YourPackage = {path = ".."}

and in your main Project.toml you need to have:

[workspace]
projects = ["examples", "test"]

Then, at the top of my examples files I have:

using Pkg
if Base.active_project() != joinpath(@__DIR__, "Project.toml")
    Pkg.activate(joinpath(@__DIR__))
end

This code activates the examples project if it was not activated before, so launching Julia with julia --project and then typing "include(“examples/myexample.jl”) works.

Make sure to delete any manifest file in the examples folder. With Julia 1.12 then only one manifest file in the root folder is used for the main project and all sub-projects.

In the “fine print”, workspaces are only for Julia 1.12.x and greater.

Julia 1.10.x, the LTS version is “legacy”.

I’m not sure if the use of workspaces means that your packages won’t run
on LTS or not.

Julia 1.10 ignores the workspace information in Project.toml.

There is no problem using a package with workspaces as a dependency on Julia 1.10, or loading the package itself on 1.10, assuming the package is otherwise compatible.

Running tests, examples, etc., which are organized with workspaces, may fail on 1.10.