Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 60 additions & 47 deletions docs/src/creating-packages.md
Original file line number Diff line number Diff line change
Expand Up @@ -275,58 +275,37 @@ test-specific dependencies, are available, see below.

### Test-specific dependencies

There are two ways of adding test-specific dependencies (dependencies that are not dependencies of the package but will still be available to
load when the package is tested).
Test-specific dependencies are dependencies that are not dependencies of the package itself but are available when the package is tested.

#### `target` based test specific dependencies
#### Recommended approach: Using workspaces with `test/Project.toml`

Using this method of adding test-specific dependencies, the packages are added under an `[extras]` section and to a test target,
e.g. to add `Markdown` and `Test` as test dependencies, add the following to the `Project.toml` file:

```toml
[extras]
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Markdown", "Test"]
```

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.
!!! compat
Workspaces require Julia 1.12+. For older Julia versions, see the legacy approaches below.

#### Alternative approach: `test/Project.toml` file test specific dependencies
The recommended way to add test-specific dependencies is to use workspaces. This is done by:

!!! note
The exact interaction between `Project.toml`, `test/Project.toml` and their corresponding
`Manifest.toml`s are not fully worked out and may be subject to change in future versions.
The older method of adding test-specific dependencies, described in the previous section,
will therefore be supported throughout all Julia 1.X releases.
1. Adding a `[workspace]` section to your package's `Project.toml`:

In Julia 1.2 and later test dependencies can be declared in `test/Project.toml`. When running
tests, Pkg will automatically merge this and the package Projects to create the test environment.

!!! note
If no `test/Project.toml` exists Pkg will use the `target` based test specific dependencies.
```toml
[workspace]
projects = ["test"]
```

To add a test-specific dependency, i.e. a dependency that is available only when testing,
it is thus enough to add this dependency to the `test/Project.toml` project. This can be
done from the Pkg REPL by activating this environment, and then use `add` as one normally
does. Let's add the `Test` standard library as a test dependency:
2. Creating a `test/Project.toml` file with your test dependencies:

```julia-repl
(HelloWorld) pkg> activate ./test
[ Info: activating environment at `~/HelloWorld/test/Project.toml`.

(test) pkg> add Test
(HelloWorld/test) pkg> add Test
Resolving package versions...
Updating `~/HelloWorld/test/Project.toml`
[8dfed614] + Test
Updating `~/HelloWorld/test/Manifest.toml`
[...]
```

We can now use `Test` in the test script and we can see that it gets installed when testing:
When using workspaces, the package manager resolves dependencies for all projects in the workspace together, and creates a single `Manifest.toml` next to the base `Project.toml`. This provides better dependency resolution and makes it easier to manage test-specific dependencies.

You can now use `Test` in the test script:

```julia-repl
julia> write("test/runtests.jl",
Expand All @@ -335,19 +314,53 @@ julia> write("test/runtests.jl",
@test 1 == 1
""");

(test) pkg> activate .
(HelloWorld/test) pkg> activate .

(HelloWorld) pkg> test
Testing HelloWorld
Resolving package versions...
Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Project.toml`
[d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`]
[8dfed614] + Test
Updating `/var/folders/64/76tk_g152sg6c6t0b4nkn1vw0000gn/T/tmpPzUPPw/Manifest.toml`
[d8327f2a] + HelloWorld v0.1.0 [`~/.julia/dev/Pkg/HelloWorld`]
Testing HelloWorld tests passed```
Testing HelloWorld tests passed
```

Workspaces can also be used for other purposes, such as documentation or benchmarks, by adding additional projects to the workspace:

```toml
[workspace]
projects = ["test", "docs", "benchmarks"]
```

See the section on [Workspaces](@ref) in the `Project.toml` documentation for more details.

#### Legacy approach: `target` based test specific dependencies

!!! warning
This approach is legacy and maintained for compatibility. New packages should use workspaces instead.

Using this method, test-specific dependencies are added under an `[extras]` section and to a test target:

```toml
[extras]
Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a"
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"

[targets]
test = ["Markdown", "Test"]
```

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.

#### Legacy approach: `test/Project.toml` without workspace

!!! warning
This approach is legacy and maintained for compatibility. New packages should use workspaces instead.

In Julia 1.2 and later, test dependencies can be declared in `test/Project.toml` without using a workspace. When running tests, Pkg will automatically merge the package and test projects to create the test environment.

!!! note
If no `test/Project.toml` exists, Pkg will use the `target` based test specific dependencies.

This approach works similarly to the workspace approach, but without the workspace declaration in the main `Project.toml`.

## Compatibility on dependencies

Every dependency should in general have a compatibility constraint on it.
Expand Down Expand Up @@ -450,9 +463,7 @@ Extensions can have arbitrary names (here `ContourExt`), following the format of
In `Pkg` output, extension names are always shown together with their parent package name.

!!! compat
Often you will put the extension dependencies into the `test` target so they are loaded when running e.g. `Pkg.test()`. On earlier Julia versions
this requires you to also put the package in the `[extras]` section. This is unfortunate but the project verifier on older Julia versions will
complain if this is not done.
Often you will want to load extension dependencies when testing your package. The recommended approach is to use workspaces and add the extension dependencies to your `test/Project.toml` (see [Test-specific dependencies](@ref adding-tests-to-packages)). For older Julia versions that don't support workspaces, you can put the extension dependencies into the `test` target, which requires you to also put the package in the `[extras]` section. The project verifier on older Julia versions will complain if this is not done.

!!! note
If you use a manifest generated by a Julia version that does not know about extensions with a Julia version that does
Expand Down Expand Up @@ -557,11 +568,13 @@ This is done by making the following changes (using the example above):

In the case where one wants to use an extension (without worrying about the
feature of the extension being available on older Julia versions) while still
supporting older Julia versions the packages under `[weakdeps]` should be
supporting older Julia versions without workspace support, the packages under `[weakdeps]` should be
duplicated into `[extras]`. This is an unfortunate duplication, but without
doing this the project verifier under older Julia versions will throw an error
if it finds packages under `[compat]` that is not listed in `[extras]`.

For Julia 1.13+, using workspaces is recommended and this duplication is not necessary.

## Package naming guidelines

Package names should be sensible to most Julia users, *even to those who are not domain experts*.
Expand Down
4 changes: 2 additions & 2 deletions docs/src/toml-files.md
Original file line number Diff line number Diff line change
Expand Up @@ -190,7 +190,7 @@ constraints in detail. It is also possible to list constraints on `julia` itself
julia = "1.1"
```

### The `[workspace]` section
### [The `[workspace]` section](@id Workspaces)

A project file can define a workspace by giving a set of projects that is part of that workspace.
Each project in a workspace can include their own dependencies, compatibility information, and even function as full packages.
Expand All @@ -204,7 +204,7 @@ A workspace is defined in the base project by giving a list of the projects in i
projects = ["test", "docs", "benchmarks", "PrivatePackage"]
```

This structure is particularly beneficial for developers using a monorepo approach, where a large number of unregistered packages may be involved. It's also useful for adding documentation or benchmarks to a package by including additional dependencies beyond those of the package itself.
This structure is particularly beneficial for developers using a monorepo approach, where a large number of unregistered packages may be involved. It's also useful for adding test-specific dependencies to a package by including a `test` project in the workspace (see [Test-specific dependencies](@ref adding-tests-to-packages)), or for adding documentation or benchmarks with their own dependencies.

Workspace can be nested: a project that itself defines a workspace can also be part of another workspace.
In this case, the workspaces are "merged" with a single manifest being stored alongside the "root project" (the project that doesn't have another workspace including it).
Expand Down