-
Notifications
You must be signed in to change notification settings - Fork 18
Julia 1.13+: Use safe_realpath(manifest_rel_path(...)) instead of project_rel_path(...)
#106
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 2 commits
Commits
Show all changes
4 commits
Select commit
Hold shift + click to select a range
ecbf79e
Copy the contents of `src/julia-1.11` to `src/julia-1.13`, and use `s…
DilumAluthge 6c02085
Julia 1.13+: Use `safe_realpath(manifest_rel_path(...))` instead of `…
DilumAluthge 55758f8
Better debug-log printing of exceptions
DilumAluthge a55a735
Add trailing newline character (for POSIX compliance)
DilumAluthge File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| using Pkg | ||
| using Pkg: PackageSpec | ||
| using Pkg.Types: Context, ensure_resolved, is_project_uuid, write_env, is_stdlib | ||
| using Pkg.Types: Types, projectfile_path, manifestfile_path | ||
| using Pkg.Operations: manifest_info, manifest_resolve!, project_deps_resolve! | ||
| using Pkg.Operations: manifest_rel_path, project_resolve! | ||
| using Pkg.Operations: sandbox, source_path, sandbox_preserve, abspath! | ||
| using Pkg.Operations: gen_target_project, isfixed | ||
|
|
||
|
|
||
| include("common.jl") | ||
| include("activate_do.jl") | ||
| include("activate_set.jl") |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,21 @@ | ||
| """ | ||
| TestEnv.activate(f, [pkg]; allow_reresolve=true) | ||
|
|
||
| Activate the test enviroment of `pkg` (defaults to current enviroment), and run `f()`, | ||
| then deactivate the enviroment. | ||
| This is not useful for many people: Julia is not really designed to have the enviroment | ||
| being changed while you are executing code. | ||
| However, this *is* useful for anyone doing something like making a alternative to | ||
| `Pkg.test()`. | ||
| Indeed this is basically extracted from what `Pkg.test()` does. | ||
| """ | ||
| function activate(f, pkg::AbstractString=current_pkg_name(); allow_reresolve=true) | ||
| ctx, pkgspec = ctx_and_pkgspec(pkg) | ||
|
|
||
| test_project_override = maybe_gen_project_override!(ctx, pkgspec) | ||
| path = pkgspec.path::String | ||
| return sandbox(ctx, pkgspec, joinpath(path, "test"), test_project_override; allow_reresolve) do | ||
| flush(stdout) | ||
| f() | ||
| end | ||
| end |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,89 @@ | ||
|
|
||
| # Originally from Pkg.Operations.sandbox | ||
|
|
||
| """ | ||
| TestEnv.activate([pkg]; allow_reresolve=true) | ||
|
|
||
| Activate the test enviroment of `pkg` (defaults to current enviroment). | ||
| """ | ||
| function activate(pkg::AbstractString=current_pkg_name(); allow_reresolve=true) | ||
| ctx, pkgspec = ctx_and_pkgspec(pkg) | ||
| # This needs to be first as `gen_target_project` fixes `pkgspec.path` if it is nothing | ||
| sandbox_project_override = maybe_gen_project_override!(ctx, pkgspec) | ||
|
|
||
| sandbox_path = joinpath(pkgspec.path::String, "test") | ||
| sandbox_project = projectfile_path(sandbox_path) | ||
|
|
||
| tmp = mktempdir() | ||
| tmp_project = projectfile_path(tmp) | ||
| tmp_manifest = manifestfile_path(tmp) | ||
|
|
||
| # Copy env info over to temp env | ||
| if sandbox_project_override !== nothing | ||
| Types.write_project(sandbox_project_override, tmp_project) | ||
| elseif isfile(sandbox_project) | ||
| cp(sandbox_project, tmp_project) | ||
| chmod(tmp_project, 0o600) | ||
| end | ||
| # create merged manifest | ||
| # - copy over active subgraph | ||
| # - abspath! to maintain location of all deved nodes | ||
| working_manifest = abspath!(ctx.env, sandbox_preserve(ctx.env, pkgspec, tmp_project)) | ||
|
|
||
| # - copy over fixed subgraphs from test subgraph | ||
| # really only need to copy over "special" nodes | ||
| sandbox_env = Types.EnvCache(projectfile_path(sandbox_path)) | ||
| sandbox_manifest = abspath!(sandbox_env, sandbox_env.manifest) | ||
| for (name, uuid) in sandbox_env.project.deps | ||
| entry = get(sandbox_manifest, uuid, nothing) | ||
| if entry !== nothing && isfixed(entry) | ||
| # Signature changed when workspaces were introduced to Pkg in v1.12 (see Pkg.jl#3841) | ||
| subgraph = Pkg.Operations.prune_manifest(sandbox_manifest, VERSION < v"1.12.0-" ? [uuid] : Set([uuid])) | ||
| for (uuid, entry) in subgraph | ||
| if haskey(working_manifest, uuid) | ||
| Pkg.Operations.pkgerror("can not merge projects") | ||
| end | ||
| working_manifest[uuid] = entry | ||
| end | ||
| end | ||
| end | ||
|
|
||
| Types.write_manifest(working_manifest, tmp_manifest) | ||
|
|
||
| Base.ACTIVE_PROJECT[] = tmp_project | ||
|
|
||
| temp_ctx = Context() | ||
| temp_ctx.env.project.deps[pkgspec.name] = pkgspec.uuid | ||
|
|
||
| # A hack to get [sources] with relative paths working. We just dive into the project | ||
| # context and replace all the relative '{path = ".."}' instances with the corresponding | ||
| # absolute paths. `pkgspec.path` is assumed to be relative to the Project.toml file | ||
| # that we are activating and has the relative paths. | ||
| for source in values(temp_ctx.env.project.sources) | ||
| isa(source, Dict) || continue | ||
| haskey(source, "path") || continue | ||
| base_path = test_dir_has_project_file(temp_ctx, pkgspec) ? joinpath(pkgspec.path, "test") : pkgspec.path | ||
| if !isabspath(source["path"]) | ||
| source["path"] = joinpath(base_path, source["path"]) | ||
| end | ||
| end | ||
|
|
||
| try | ||
| Pkg.resolve(temp_ctx; io=devnull) | ||
| @debug "Using _parent_ dep graph" | ||
| catch err# TODO | ||
| allow_reresolve || rethrow() | ||
| @debug err | ||
| @warn "Could not use exact versions of packages in manifest, re-resolving" | ||
| temp_ctx.env.manifest.deps = Dict( | ||
| uuid => entry for | ||
| (uuid, entry) in temp_ctx.env.manifest.deps if isfixed(entry) | ||
| ) | ||
| Pkg.resolve(temp_ctx; io=devnull) | ||
| @debug "Using _clean_ dep graph" | ||
| end | ||
|
|
||
| write_env(temp_ctx.env; update_undo=false) | ||
|
|
||
| return Base.active_project() | ||
| end | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,88 @@ | ||
| struct TestEnvError <: Exception | ||
| msg::AbstractString | ||
| end | ||
|
|
||
| function Base.showerror(io::IO, ex::TestEnvError, bt; backtrace=true) | ||
| printstyled(io, ex.msg, color=Base.error_color()) | ||
| end | ||
|
|
||
| function current_pkg_name() | ||
| ctx = Context() | ||
| ctx.env.pkg === nothing && throw(TestEnvError("trying to activate test environment of an unnamed project")) | ||
| return ctx.env.pkg.name | ||
| end | ||
|
|
||
| """ | ||
| ctx, pkgspec = ctx_and_pkgspec(pkg::AbstractString) | ||
|
|
||
| For a given package name `pkg`, instantiate a `Context` for it, and return that `Context`, | ||
| and it's `PackageSpec`. | ||
| """ | ||
| function ctx_and_pkgspec(pkg::AbstractString) | ||
| pkgspec = deepcopy(PackageSpec(pkg)) | ||
| ctx = Context() | ||
| isinstalled!(ctx, pkgspec) || throw(TestEnvError("$pkg not installed 👻")) | ||
| Pkg.instantiate(ctx) | ||
| return ctx, pkgspec | ||
| end | ||
|
|
||
| """ | ||
| isinstalled!(ctx::Context, pkgspec::Pkg.Types.PackageSpec) | ||
|
|
||
| Checks if the package is installed by using `ensure_resolved` from `Pkg/src/Types.jl`. | ||
| This function fails if the package is not installed, but here we wrap it in a | ||
| try-catch as we may want to test another package after the one that isn't installed. | ||
| """ | ||
| function isinstalled!(ctx::Context, pkgspec::Pkg.Types.PackageSpec) | ||
| project_resolve!(ctx.env, [pkgspec]) | ||
| project_deps_resolve!(ctx.env, [pkgspec]) | ||
| manifest_resolve!(ctx.env.manifest, [pkgspec]) | ||
|
|
||
| try | ||
| ensure_resolved(ctx, ctx.env.manifest, [pkgspec]) | ||
| catch err | ||
| err isa MethodError && rethrow() | ||
| return false | ||
| end | ||
| return true | ||
| end | ||
|
|
||
|
|
||
| function test_dir_has_project_file(ctx, pkgspec) | ||
| test_dir = get_test_dir(ctx, pkgspec) | ||
| test_dir === nothing && return false | ||
| return isfile(joinpath(test_dir, "Project.toml")) | ||
| end | ||
|
|
||
| """ | ||
| get_test_dir(ctx::Context, pkgspec::Pkg.Types.PackageSpec) | ||
|
|
||
| Gets the testfile path of the package. Code for each Julia version mirrors that found | ||
| in `Pkg/src/Operations.jl`. | ||
| """ | ||
| function get_test_dir(ctx::Context, pkgspec::Pkg.Types.PackageSpec) | ||
| if is_project_uuid(ctx.env, pkgspec.uuid) | ||
| pkgspec.path = dirname(ctx.env.project_file) | ||
| pkgspec.version = ctx.env.pkg.version | ||
| else | ||
| is_stdlib(pkgspec.uuid::Base.UUID) && return | ||
| entry = manifest_info(ctx.env.manifest, pkgspec.uuid) | ||
| pkgspec.version = entry.version | ||
| pkgspec.tree_hash = entry.tree_hash | ||
| pkgspec.repo = entry.repo | ||
| pkgspec.path = entry.path | ||
| pkgspec.pinned = entry.pinned | ||
| pkgspec.path = Pkg.safe_realpath(manifest_rel_path(ctx.env, source_path(ctx.env.project_file, pkgspec)::String)) | ||
| end | ||
| pkgfilepath = source_path(ctx.env.project_file, pkgspec)::String | ||
| return joinpath(pkgfilepath, "test") | ||
| end | ||
|
|
||
|
|
||
| function maybe_gen_project_override!(ctx, pkgspec) | ||
| if !test_dir_has_project_file(ctx, pkgspec) | ||
| gen_target_project(ctx, pkgspec, pkgspec.path::String, "test") | ||
| else | ||
| nothing | ||
| end | ||
| end |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.