Skip to content

Activate a workspace test project directly - #103

Merged
davidanthoff merged 3 commits into
julia-testitems:mainfrom
simsurace:activate-workspace-test-env
Sep 12, 2026
Merged

davidanthoff merged 3 commits into
julia-testitems:mainfrom
simsurace:activate-workspace-test-env

Conversation

@simsurace

Copy link
Copy Markdown
Contributor

A package's test sub-project that is a Pkg workspace member is a complete, already resolved environment whose Manifest is the shared workspace Manifest, located by walking the workspace chain up from the folder. The scratch-env plus TestEnv path cannot serve it: it copies the project into a scratch directory, severing the workspace relationship, then finds no Manifest beside the copy and fails to resolve because the workspace's path-tracked packages are not registered. Activate such a project in place instead; activation is read-only, so it still never writes into the tree.

A package's test sub-project that is a Pkg workspace member is a complete,
already resolved environment whose Manifest is the shared workspace
Manifest, located by walking the workspace chain up from the folder. The
scratch-env plus TestEnv path cannot serve it: it copies the project into
a scratch directory, severing the workspace relationship, then finds no
Manifest beside the copy and fails to resolve because the workspace's
path-tracked packages are not registered. Activate such a project in place
instead; activation is read-only, so it still never writes into the tree.
@davidanthoff

Copy link
Copy Markdown
Member

I have some changes/additions coming, I'll push to this branch, ok?

Narrow the in-place activation to exactly the shape `Pkg.test` (Julia 1.12+)
runs in place: `<package>/test` that is a `[workspace]` member of the package
project, checked through `Base.base_project` the way Pkg checks membership.
The previous folder-name test also caught a `test/Project.toml` with a manifest
of its own that `dev`s the package, which Pkg sandboxes — and on Julia before
1.12, where workspaces do not exist, that was the only thing it could catch.

Do the two things Pkg's workspace branch does that activation alone skipped:
`Pkg.instantiate` (fetching into the depot only — a workspace without a
manifest is refused rather than resolved into the user's tree) and
`Pkg.precompile`, so the caches are built inside the controller's serialized
activation window rather than by every test process at its first `using`.

Compare paths case-insensitively on Windows, where the two URIs of a request
can disagree about the drive letter; handle trailing separators via
`isdirpath`, since `normpath` keeps them.

Tests: the membership helper on member/non-member layouts, an end-to-end run
of a workspace test project with an unregistered path-tracked dependency that
checks the tree is left untouched, and a non-member `test/` with its own
manifest that must still land in a scratch copy.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@davidanthoff

Copy link
Copy Markdown
Member

Thanks — the direction is right: Pkg.test itself (Julia 1.12+) has exactly this branch and runs a [workspace]-member test/ project in place instead of sandboxing it. I pushed a commit on top (30b9ab2) that aligns the details with what Pkg does:

  • Gate on workspace membership, not the folder name. Pkg checks testdir in keys(env.workspace); the PR checked only <pkg>/test. That also caught a test/Project.toml with a manifest of its own that devs the package, which Pkg sandboxes — and on Julia < 1.12, where workspaces don't exist, that was the only shape it could catch. The check now goes through Base.base_project, the same thing Pkg consults.
  • Instantiate and precompile, as Pkg's workspace branch does. Pkg.instantiate only fetches into the depot when the manifest exists, so a workspace without a resolved manifest is refused with a message rather than resolved into the user's tree. Precompiling here keeps the cache build inside the controller's serialized activation window.
  • Case-insensitive path comparison on Windows (the two URIs of a request can disagree about the drive letter) and trailing-separator handling.
  • Tests: the membership helper, an end-to-end workspace fixture with an unregistered path-tracked dependency (asserts the tree is untouched and the member project is the active one), and a non-member test/ with its own manifest that must still land in a scratch copy. Plus a CHANGELOG entry.

All of test/test_scratch_env.jl and the other activation-related test files pass on 1.13 here.

🤖 Generated with Claude Code

@davidanthoff
davidanthoff merged commit 62ae4a5 into julia-testitems:main Sep 12, 2026
18 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants