|
| 1 | + |
| 2 | +# Originally from Pkg.Operations.sandbox |
| 3 | + |
| 4 | +""" |
| 5 | + TestEnv.activate([pkg]; allow_reresolve=true) |
| 6 | +
|
| 7 | +Activate the test enviroment of `pkg` (defaults to current enviroment). |
| 8 | +""" |
| 9 | +function activate(pkg::AbstractString=current_pkg_name(); allow_reresolve=true) |
| 10 | + ctx, pkgspec = ctx_and_pkgspec(pkg) |
| 11 | + # This needs to be first as `gen_target_project` fixes `pkgspec.path` if it is nothing |
| 12 | + sandbox_project_override = maybe_gen_project_override!(ctx, pkgspec) |
| 13 | + |
| 14 | + sandbox_path = joinpath(pkgspec.path::String, "test") |
| 15 | + sandbox_project = projectfile_path(sandbox_path) |
| 16 | + |
| 17 | + tmp = mktempdir() |
| 18 | + tmp_project = projectfile_path(tmp) |
| 19 | + tmp_manifest = manifestfile_path(tmp) |
| 20 | + |
| 21 | + # Copy env info over to temp env |
| 22 | + if sandbox_project_override !== nothing |
| 23 | + Types.write_project(sandbox_project_override, tmp_project) |
| 24 | + elseif isfile(sandbox_project) |
| 25 | + cp(sandbox_project, tmp_project) |
| 26 | + chmod(tmp_project, 0o600) |
| 27 | + end |
| 28 | + # create merged manifest |
| 29 | + # - copy over active subgraph |
| 30 | + # - abspath! to maintain location of all deved nodes |
| 31 | + working_manifest = abspath!(ctx.env, sandbox_preserve(ctx.env, pkgspec, tmp_project)) |
| 32 | + |
| 33 | + # - copy over fixed subgraphs from test subgraph |
| 34 | + # really only need to copy over "special" nodes |
| 35 | + sandbox_env = Types.EnvCache(projectfile_path(sandbox_path)) |
| 36 | + sandbox_manifest = abspath!(sandbox_env, sandbox_env.manifest) |
| 37 | + for (name, uuid) in sandbox_env.project.deps |
| 38 | + entry = get(sandbox_manifest, uuid, nothing) |
| 39 | + if entry !== nothing && isfixed(entry) |
| 40 | + # Signature changed when workspaces were introduced to Pkg in v1.12 (see Pkg.jl#3841) |
| 41 | + subgraph = Pkg.Operations.prune_manifest(sandbox_manifest, VERSION < v"1.12.0-" ? [uuid] : Set([uuid])) |
| 42 | + for (uuid, entry) in subgraph |
| 43 | + if haskey(working_manifest, uuid) |
| 44 | + Pkg.Operations.pkgerror("can not merge projects") |
| 45 | + end |
| 46 | + working_manifest[uuid] = entry |
| 47 | + end |
| 48 | + end |
| 49 | + end |
| 50 | + |
| 51 | + Types.write_manifest(working_manifest, tmp_manifest) |
| 52 | + |
| 53 | + Base.ACTIVE_PROJECT[] = tmp_project |
| 54 | + |
| 55 | + temp_ctx = Context() |
| 56 | + temp_ctx.env.project.deps[pkgspec.name] = pkgspec.uuid |
| 57 | + |
| 58 | + # A hack to get [sources] with relative paths working. We just dive into the project |
| 59 | + # context and replace all the relative '{path = ".."}' instances with the corresponding |
| 60 | + # absolute paths. `pkgspec.path` is assumed to be relative to the Project.toml file |
| 61 | + # that we are activating and has the relative paths. |
| 62 | + for source in values(temp_ctx.env.project.sources) |
| 63 | + isa(source, Dict) || continue |
| 64 | + haskey(source, "path") || continue |
| 65 | + base_path = test_dir_has_project_file(temp_ctx, pkgspec) ? joinpath(pkgspec.path, "test") : pkgspec.path |
| 66 | + if !isabspath(source["path"]) |
| 67 | + source["path"] = joinpath(base_path, source["path"]) |
| 68 | + end |
| 69 | + end |
| 70 | + |
| 71 | + try |
| 72 | + Pkg.resolve(temp_ctx; io=devnull) |
| 73 | + @debug "Using _parent_ dep graph" |
| 74 | + catch err# TODO |
| 75 | + allow_reresolve || rethrow() |
| 76 | + @debug exception=err |
| 77 | + @warn "Could not use exact versions of packages in manifest, re-resolving" |
| 78 | + temp_ctx.env.manifest.deps = Dict( |
| 79 | + uuid => entry for |
| 80 | + (uuid, entry) in temp_ctx.env.manifest.deps if isfixed(entry) |
| 81 | + ) |
| 82 | + Pkg.resolve(temp_ctx; io=devnull) |
| 83 | + @debug "Using _clean_ dep graph" |
| 84 | + end |
| 85 | + |
| 86 | + write_env(temp_ctx.env; update_undo=false) |
| 87 | + |
| 88 | + return Base.active_project() |
| 89 | +end |
0 commit comments