|
| 1 | +struct TestEnvError <: Exception |
| 2 | + msg::AbstractString |
| 3 | +end |
| 4 | + |
| 5 | +function Base.showerror(io::IO, ex::TestEnvError, bt; backtrace=true) |
| 6 | + printstyled(io, ex.msg, color=Base.error_color()) |
| 7 | +end |
| 8 | + |
| 9 | +function current_pkg_name() |
| 10 | + ctx = Context() |
| 11 | + ctx.env.pkg === nothing && throw(TestEnvError("trying to activate test environment of an unnamed project")) |
| 12 | + return ctx.env.pkg.name |
| 13 | +end |
| 14 | + |
| 15 | +""" |
| 16 | + ctx, pkgspec = ctx_and_pkgspec(pkg::AbstractString) |
| 17 | +
|
| 18 | +For a given package name `pkg`, instantiate a `Context` for it, and return that `Context`, |
| 19 | +and it's `PackageSpec`. |
| 20 | +""" |
| 21 | +function ctx_and_pkgspec(pkg::AbstractString) |
| 22 | + pkgspec = deepcopy(PackageSpec(pkg)) |
| 23 | + ctx = Context() |
| 24 | + isinstalled!(ctx, pkgspec) || throw(TestEnvError("$pkg not installed 👻")) |
| 25 | + Pkg.instantiate(ctx) |
| 26 | + return ctx, pkgspec |
| 27 | +end |
| 28 | + |
| 29 | +""" |
| 30 | + isinstalled!(ctx::Context, pkgspec::Pkg.Types.PackageSpec) |
| 31 | +
|
| 32 | +Checks if the package is installed by using `ensure_resolved` from `Pkg/src/Types.jl`. |
| 33 | +This function fails if the package is not installed, but here we wrap it in a |
| 34 | +try-catch as we may want to test another package after the one that isn't installed. |
| 35 | +""" |
| 36 | +function isinstalled!(ctx::Context, pkgspec::Pkg.Types.PackageSpec) |
| 37 | + project_resolve!(ctx.env, [pkgspec]) |
| 38 | + project_deps_resolve!(ctx.env, [pkgspec]) |
| 39 | + manifest_resolve!(ctx.env.manifest, [pkgspec]) |
| 40 | + |
| 41 | + try |
| 42 | + ensure_resolved(ctx, ctx.env.manifest, [pkgspec]) |
| 43 | + catch err |
| 44 | + err isa MethodError && rethrow() |
| 45 | + return false |
| 46 | + end |
| 47 | + return true |
| 48 | +end |
| 49 | + |
| 50 | + |
| 51 | +function test_dir_has_project_file(ctx, pkgspec) |
| 52 | + test_dir = get_test_dir(ctx, pkgspec) |
| 53 | + test_dir === nothing && return false |
| 54 | + return isfile(joinpath(test_dir, "Project.toml")) |
| 55 | +end |
| 56 | + |
| 57 | +""" |
| 58 | + get_test_dir(ctx::Context, pkgspec::Pkg.Types.PackageSpec) |
| 59 | +
|
| 60 | +Gets the testfile path of the package. Code for each Julia version mirrors that found |
| 61 | +in `Pkg/src/Operations.jl`. |
| 62 | +""" |
| 63 | +function get_test_dir(ctx::Context, pkgspec::Pkg.Types.PackageSpec) |
| 64 | + if is_project_uuid(ctx.env, pkgspec.uuid) |
| 65 | + pkgspec.path = dirname(ctx.env.project_file) |
| 66 | + pkgspec.version = ctx.env.pkg.version |
| 67 | + else |
| 68 | + is_stdlib(pkgspec.uuid::Base.UUID) && return |
| 69 | + entry = manifest_info(ctx.env.manifest, pkgspec.uuid) |
| 70 | + pkgspec.version = entry.version |
| 71 | + pkgspec.tree_hash = entry.tree_hash |
| 72 | + pkgspec.repo = entry.repo |
| 73 | + pkgspec.path = entry.path |
| 74 | + pkgspec.pinned = entry.pinned |
| 75 | + pkgspec.path = project_rel_path(ctx.env, source_path(ctx.env.project_file, pkgspec)::String) |
| 76 | + end |
| 77 | + pkgfilepath = source_path(ctx.env.project_file, pkgspec)::String |
| 78 | + return joinpath(pkgfilepath, "test") |
| 79 | +end |
| 80 | + |
| 81 | + |
| 82 | +function maybe_gen_project_override!(ctx, pkgspec) |
| 83 | + if !test_dir_has_project_file(ctx, pkgspec) |
| 84 | + gen_target_project(ctx, pkgspec, pkgspec.path::String, "test") |
| 85 | + else |
| 86 | + nothing |
| 87 | + end |
| 88 | +end |
0 commit comments