From be7df16274d517a7446e45fe117dcc228d8ad6d4 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Tue, 3 Aug 2021 21:16:22 +0100 Subject: [PATCH 1/4] Clean-up release 1.4 branch include new tests --- Project.toml | 6 +- src/TestEnv.jl | 31 ++------- src/activate.jl | 19 ++---- src/make_test_env.jl | 159 ++++++++++++++++++------------------------- src/sandbox.jl | 55 +++------------ src/test_dir.jl | 70 ++----------------- test/activate_do.jl | 21 ++++++ test/activate_set.jl | 30 ++++++++ test/runner.jl | 55 --------------- test/runtests.jl | 3 +- 10 files changed, 149 insertions(+), 300 deletions(-) create mode 100644 test/activate_do.jl create mode 100644 test/activate_set.jl delete mode 100644 test/runner.jl diff --git a/Project.toml b/Project.toml index 1ff93a7..14bae96 100644 --- a/Project.toml +++ b/Project.toml @@ -7,11 +7,15 @@ Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" [compat] ChainRulesCore = "=1.0.2" +MCMCDiagnosticTools = "=0.1.0" +YAXArrays = "0.1.3" julia = "~1.4, ~1.5, ~1.6" [extras] ChainRulesCore = "d360d2e6-b24c-11e9-a2a3-2a2ae2dbcce4" +MCMCDiagnosticTools = "be115224-59cd-429b-ad48-344e309966f0" Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" +YAXArrays = "c21b50f5-aa40-41ea-b809-c0f5e47bfa5c" [targets] -test = ["ChainRulesCore", "Test"] +test = ["ChainRulesCore", "MCMCDiagnosticTools", "Test", "YAXArrays"] diff --git a/src/TestEnv.jl b/src/TestEnv.jl index 792774d..d66fe0b 100644 --- a/src/TestEnv.jl +++ b/src/TestEnv.jl @@ -6,33 +6,10 @@ using Pkg.Operations: manifest_info, manifest_resolve!, project_deps_resolve! using Pkg.Operations: project_rel_path, project_resolve! using Pkg.Types: Types, projectfile_path, manifestfile_path - -# Version specific imports -@static if VERSION >= v"1.4.0" - using Pkg.Operations: gen_target_project -else - using Pkg.Operations: with_dependencies_loadable_at_toplevel -end -@static if isdefined(Pkg.Operations, :update_package_test!) - using Pkg.Operations: update_package_test! -else - function update_package_test!(pkg, entry) - is_stdlib(pkg.uuid) && return - pkg.version = entry.version - pkg.tree_hash = entry.tree_hash - pkg.repo = entry.repo - pkg.path = entry.path - pkg.pinned = entry.pinned - end -end - -@static if VERSION >= v"1.2.0" - using Pkg.Types: is_stdlib - using Pkg.Operations: sandbox, source_path, sandbox_preserve, abspath! -else - using Pkg.Operations: find_installed - using Pkg.Types: SHA1 -end +using Pkg.Operations: gen_target_project +using Pkg.Operations: update_package_test! +using Pkg.Types: is_stdlib +using Pkg.Operations: sandbox, source_path, sandbox_preserve, abspath! include("exceptions.jl") diff --git a/src/activate.jl b/src/activate.jl index 41ba616..3351f51 100644 --- a/src/activate.jl +++ b/src/activate.jl @@ -44,23 +44,12 @@ is of type `Pkg.Types.Context`. For earlier versions, they are of type `Pkg.Types.EnvCache`. """ function isinstalled!(ctx::Context, pkgspec::Pkg.Types.PackageSpec) - var = @static if v"1.4.0" <= VERSION < v"1.7.0-" - ctx - else - ctx.env - end - project_resolve!(var, [pkgspec]) - project_deps_resolve!(var, [pkgspec]) - - manifest = @static if VERSION < v"1.7.0-" - var - else - var.manifest - end - manifest_resolve!(manifest, [pkgspec]) + project_resolve!(ctx, [pkgspec]) + project_deps_resolve!(ctx, [pkgspec]) + manifest_resolve!(ctx, [pkgspec]) try - ensure_resolved(manifest, [pkgspec]) + ensure_resolved(ctx, [pkgspec]) catch err err isa MethodError && rethrow() return false diff --git a/src/make_test_env.jl b/src/make_test_env.jl index a4d8b8c..4fb56a7 100644 --- a/src/make_test_env.jl +++ b/src/make_test_env.jl @@ -1,108 +1,85 @@ # Originally from Pkg.Operations.sandbox -@static if VERSION <= v"1.1" # 1.0 or 1.1 - # For now will just abuse that we solved sandbox - function make_test_env(ctx::Context, pkgspec) - safe_dir = mktempdir() - _sandbox(ctx, pkgspec) do - cp(Base.active_project(), joinpath(safe_dir, "Project.toml")) - end - Pkg.activate(safe_dir) - Pkg.resolve() - return nothing +function make_test_env(ctx::Context, target) + # This needs to be first as `gen_target_project` fixes `target.path` if it is nothing + sandbox_project_override = if !test_dir_has_project_file(ctx, target) + sandbox_project_override = gen_target_project(ctx, target, target.path, "test") + else + nothing end -else - function make_test_env(ctx::Context, target) - # This needs to be first as `gen_target_project` fixes `target.path` if it is nothing - sandbox_project_override = if !test_dir_has_project_file(ctx, target) - sandbox_project_override = @static if VERSION < v"1.7-a" - gen_target_project(ctx, target, target.path, "test") - else - gen_target_project(ctx.env, ctx.registries, target, target.path, "test") - end - else - nothing - end - sandbox_path = joinpath(target.path, "test") - sandbox_project = projectfile_path(sandbox_path) + sandbox_path = joinpath(target.path, "test") + sandbox_project = projectfile_path(sandbox_path) - tmp = mktempdir() - tmp_project = projectfile_path(tmp) - tmp_manifest = manifestfile_path(tmp) + 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 = if VERSION <= v"1.7-a" - abspath!(ctx, sandbox_preserve(ctx, target, tmp_project)) - else - abspath!(ctx.env, sandbox_preserve(ctx.env, target, tmp_project)) - end - # - 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 = if VERSION <= v"1.7-a" - abspath!(sandbox_path, sandbox_env.manifest) - else - abspath!(sandbox_env, sandbox_env.manifest) - end - for (name, uuid) in sandbox_env.project.deps - entry = get(sandbox_manifest, uuid, nothing) - if entry !== nothing && isfixed(entry) - subgraph = prune_manifest(sandbox_manifest, [uuid]) - for (uuid, entry) in subgraph - if haskey(working_manifest, uuid) - pkgerror("can not merge projects") - end - working_manifest[uuid] = entry + # 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, sandbox_preserve(ctx, target, 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_path, sandbox_env.manifest) + + for (name, uuid) in sandbox_env.project.deps + entry = get(sandbox_manifest, uuid, nothing) + if entry !== nothing && isfixed(entry) + subgraph = prune_manifest(sandbox_manifest, [uuid]) + for (uuid, entry) in subgraph + if haskey(working_manifest, uuid) + pkgerror("can not merge projects") end + working_manifest[uuid] = entry end end + end - Types.write_manifest(working_manifest, tmp_manifest) + Types.write_manifest(working_manifest, tmp_manifest) - # sandbox - push!(empty!(LOAD_PATH), "@", tmp) - Base.ACTIVE_PROJECT[] = nothing + # sandbox + push!(empty!(LOAD_PATH), "@", tmp) + Base.ACTIVE_PROJECT[] = nothing - temp_ctx = Context() - temp_ctx.env.project.deps[target.name] = target.uuid + temp_ctx = Context() + temp_ctx.env.project.deps[target.name] = target.uuid - try - Pkg.resolve(temp_ctx; io=devnull) - @debug "Using _parent_ dep graph" - catch err# TODO - @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 + try + Pkg.resolve(temp_ctx; io=devnull) + @debug "Using _parent_ dep graph" + catch err# TODO + @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 - # Absolutify stdlibs paths - for (uuid, entry) in temp_ctx.env.manifest - if is_stdlib(uuid) - entry.path = Types.stdlib_path(entry.name) - end + # Absolutify stdlibs paths + for (uuid, entry) in temp_ctx.env.manifest + if is_stdlib(uuid) + entry.path = Types.stdlib_path(entry.name) end - write_env(temp_ctx.env; update_undo=false) - - # update enviroment variables - path_sep = Sys.iswindows() ? ';' : ':' - ENV["JULIA_LOAD_PATH"] = "@$(path_sep)$(tmp)" - delete!(ENV, "JULIA_PROJECT") - - return Base.active_project() end + write_env(temp_ctx.env; update_undo=false) + + # update enviroment variables + path_sep = Sys.iswindows() ? ';' : ':' + ENV["JULIA_LOAD_PATH"] = "@$(path_sep)$(tmp)" + delete!(ENV, "JULIA_PROJECT") + + return Base.active_project() end \ No newline at end of file diff --git a/src/sandbox.jl b/src/sandbox.jl index 1c8a52e..3735575 100644 --- a/src/sandbox.jl +++ b/src/sandbox.jl @@ -1,50 +1,11 @@ - - -if VERSION <= v"1.1" # 1.0 or 1.1 - _sandbox(f, ctx, pkgspec) = _manual_sandbox(f, ctx, pkgspec) -elseif VERSION <= v"1.3" # 1.2 or 1.3 - function _sandbox(f, ctx, pkgspec) - test_dir_has_project_file(ctx, pkgspec) || return _manual_sandbox(f, ctx, pkgspec) - return sandbox(ctx, pkgspec, pkgspec.path, joinpath(pkgspec.path, "test")) do - flush(stdout) - f() - end +function _sandbox(f, ctx, pkgspec) + test_project_override = if !test_dir_has_project_file(ctx, pkgspec) + gen_target_project(ctx, pkgspec, pkgspec.path, "test") + else + nothing end -elseif VERSION >= v"1.7-a" - function _sandbox(f, ctx, pkgspec) - test_project_override = if !test_dir_has_project_file(ctx, pkgspec) - gen_target_project(ctx.env, ctx.registries, pkgspec, pkgspec.path, "test") - else - nothing - end - return sandbox(ctx, pkgspec, pkgspec.path, joinpath(pkgspec.path, "test"), test_project_override) do - flush(stdout) - f() - end - end -else - @assert VERSION >= v"1.3" - function _sandbox(f, ctx, pkgspec) - test_project_override = if !test_dir_has_project_file(ctx, pkgspec) - gen_target_project(ctx, pkgspec, pkgspec.path, "test") - else - nothing - end - return sandbox(ctx, pkgspec, pkgspec.path, joinpath(pkgspec.path, "test"), test_project_override) do - flush(stdout) - f() - end + return sandbox(ctx, pkgspec, pkgspec.path, joinpath(pkgspec.path, "test"), test_project_override) do + flush(stdout) + f() end end -#sandbox(ctx::Context, target::PackageSpec, target_path::String,sandbox_path::String, sandbox_project_override) - -function _manual_sandbox(f, ctx, pkgspec) - with_dependencies_loadable_at_toplevel(ctx, pkgspec; might_need_to_resolve=true) do localctx - Pkg.activate(localctx.env.project_file) - try - f() - finally - Pkg.activate(ctx.env.project_file) - end - end -end \ No newline at end of file diff --git a/src/test_dir.jl b/src/test_dir.jl index 59d42e5..b1613aa 100644 --- a/src/test_dir.jl +++ b/src/test_dir.jl @@ -1,4 +1,4 @@ -[function test_dir_has_project_file(ctx, pkgspec) +function test_dir_has_project_file(ctx, pkgspec) return isfile(joinpath(get_test_dir(ctx, pkgspec), "Project.toml")) end @@ -9,69 +9,13 @@ Gets the testfile path of the package. Code for each Julia version mirrors that in `Pkg/src/Operations.jl`. """ function get_test_dir(ctx::Context, pkgspec::Pkg.Types.PackageSpec) - @static if VERSION >= v"1.7.0-a" - if is_project_uuid(ctx.env, pkgspec.uuid) - pkgspec.path = dirname(ctx.env.project_file) - pkgspec.version = ctx.env.pkg.version - else - update_package_test!(pkgspec, manifest_info(ctx.env.manifest, pkgspec.uuid)) - pkgspec.path = project_rel_path(ctx.env, source_path(ctx.env.project_file, pkgspec)) - end - pkgfilepath = source_path(ctx.env.project_file, pkgspec) - elseif VERSION >= v"1.4.0" - if is_project_uuid(ctx, pkgspec.uuid) - pkgspec.path = dirname(ctx.env.project_file) - pkgspec.version = ctx.env.pkg.version - else - update_package_test!(pkgspec, manifest_info(ctx, pkgspec.uuid)) - pkgspec.path = project_rel_path(ctx, source_path(ctx, pkgspec)) - end - pkgfilepath = source_path(ctx, pkgspec) - elseif VERSION >= v"1.2.0" - pkgspec.special_action = Pkg.Types.PKGSPEC_TESTED - if is_project_uuid(ctx.env, pkgspec.uuid) - pkgspec.path = dirname(ctx.env.project_file) - pkgspec.version = ctx.env.pkg.version - else - update_package_test!(pkgspec, manifest_info(ctx.env, pkgspec.uuid)) - pkgspec.path = joinpath(project_rel_path(ctx, source_path(pkgspec))) - end - pkgfilepath = project_rel_path(ctx, source_path(pkgspec)) - elseif VERSION >= v"1.1.0" - pkgspec.special_action = Pkg.Types.PKGSPEC_TESTED - if is_project_uuid(ctx.env, pkgspec.uuid) - pkgspec.version = ctx.env.pkg.version - pkgfilepath = dirname(ctx.env.project_file) - else - entry = manifest_info(ctx.env, pkg.uuid) - if entry.repo.tree_sha !== nothing - pkgfilepath = find_installed(pkgspec.name, pkgspec.uuid, entry.repo.tree_sha) - elseif entry.path !== nothing - pkgfilepath = project_rel_path(ctx, entry.path) - elseif pkgspec.uuid in keys(ctx.stdlibs) - pkgfilepath = Pkg.Types.stdlib_path(pkgspec.name) - else - throw(TestEnvError("Could not find either `git-tree-sha1` or `path` for package $(pkgspec.name)")) - end - end + if is_project_uuid(ctx, pkgspec.uuid) + pkgspec.path = dirname(ctx.env.project_file) + pkgspec.version = ctx.env.pkg.version else - pkgspec.special_action = Pkg.Types.PKGSPEC_TESTED - if is_project_uuid(ctx.env, pkgspec.uuid) - pkgspec.version = ctx.env.pkg.version - pkgfilepath = dirname(ctx.env.project_file) - else - info = manifest_info(ctx.env, pkgspec.uuid) - if haskey(info, "git-tree-sha1") - pkgfilepath = find_installed(pkgspec.name, pkgspec.uuid, SHA1(info["git-tree-sha1"])) - elseif haskey(info, "path") - pkgfilepath = project_rel_path(ctx, info["path"]) - elseif pkgspec.uuid in keys(ctx.stdlibs) - pkgfilepath = Pkg.Types.stdlib_path(pkgspec.name) - else - throw(TestEnvError("Could not find either `git-tree-sha1` or `path` for package $(pkgspec.name)")) - end - end + update_package_test!(pkgspec, manifest_info(ctx, pkgspec.uuid)) + pkgspec.path = project_rel_path(ctx, source_path(ctx, pkgspec)) end + pkgfilepath = source_path(ctx, pkgspec) return joinpath(pkgfilepath, "test") end -] \ No newline at end of file diff --git a/test/activate_do.jl b/test/activate_do.jl new file mode 100644 index 0000000..310b55f --- /dev/null +++ b/test/activate_do.jl @@ -0,0 +1,21 @@ +@testset "activate_do.jl" begin + @testset "activate do f [extras]" begin + direct_deps() = [v.name for (_,v) in Pkg.dependencies() if v.is_direct_dep] + crc_deps = TestEnv.activate(direct_deps, "ChainRulesCore") + @test "ChainRulesCore" ∈ crc_deps + @test "FiniteDifferences" ∈ crc_deps + + TestEnv.activate("ChainRulesCore") do + @eval using FiniteDifferences + end + @test isdefined(@__MODULE__, :FiniteDifferences) + end + + @testset "activate do test/Project" begin + # MCMCDiagnosticTools has a test/Project.toml, which contains FFTW + TestEnv.activate("MCMCDiagnosticTools") do + @eval using FFTW + end + @test isdefined(@__MODULE__, :FFTW) + end +end \ No newline at end of file diff --git a/test/activate_set.jl b/test/activate_set.jl new file mode 100644 index 0000000..7f2e1ed --- /dev/null +++ b/test/activate_set.jl @@ -0,0 +1,30 @@ +@testset "activate_set.jl" begin + @testset "activate [extras]" begin + orig_project_toml_path = Base.active_project() + try + TestEnv.activate("ChainRulesCore") + new_project_toml_path = Base.active_project() + @test new_project_toml_path != orig_project_toml_path + + @eval using StaticArrays + @test isdefined(@__MODULE__, :StaticArrays) + finally + Pkg.activate(orig_project_toml_path) + end + end + + @testset "activate test/Project" begin + orig_project_toml_path = Base.active_project() + try + # YAXArrays has a test/Project.toml, which contains CSV + TestEnv.activate("YAXArrays") + new_project_toml_path = Base.active_project() + @test new_project_toml_path != orig_project_toml_path + + @eval using CSV + @test isdefined(@__MODULE__, :CSV) + finally + Pkg.activate(orig_project_toml_path) + end + end +end \ No newline at end of file diff --git a/test/runner.jl b/test/runner.jl deleted file mode 100644 index cb8294c..0000000 --- a/test/runner.jl +++ /dev/null @@ -1,55 +0,0 @@ - -if VERSION < v"1.2.0" - @testset "get_test_dir - V1.0.5" begin - # Stdlibs are not tested by other functions for V1.0.5 - stdlibname = "Pkg" - ctx = Pkg.Types.Context() - pkg = Pkg.PackageSpec(stdlibname) - TestEnv.isinstalled!(ctx, pkg) - delete!(ctx.env.manifest[stdlibname][1], "path") # Remove path to force stdlib check - testdir = joinpath(abspath(joinpath(dirname(Base.find_package(stdlibname)), "..")), "test") - @test TestEnv.get_test_dir(ctx, pkg) == testdir - end -end - -@testset "activate do f [extras]" begin - if VERSION >= v"1.4" # can't check dependencies until julia 1.4 - direct_deps() = [v.name for (_,v) in Pkg.dependencies() if v.is_direct_dep] - crc_deps = TestEnv.activate(direct_deps, "ChainRulesCore") - @test "ChainRulesCore" ∈ crc_deps - @test "FiniteDifferences" ∈ crc_deps - end - - - TestEnv.activate(()->(@eval using FiniteDifferences), "ChainRulesCore") - @test isdefined(@__MODULE__, :FiniteDifferences) -end - -@testset "activate [extras]" begin - orig_project_toml_path = Base.active_project() - TestEnv.activate("ChainRulesCore") - new_project_toml_path = Base.active_project() - @test new_project_toml_path != orig_project_toml_path - - @eval using StaticArrays - @test isdefined(@__MODULE__, :StaticArrays) -end - - -VERSION >= v"1.3" && @testset "activate test/Project" begin - Pkg.activate(mktempdir()) - # YAXArrays has a test/Project.toml, which contains CSV - Pkg.add("YAXArrays") - TestEnv.activate("YAXArrays") - @eval using CSV - @test isdefined(@__MODULE__, :CSV) -end - -VERSION >= v"1.2" && @testset "activate do test/Project" begin - Pkg.activate(mktempdir()) - # MCMCDiagnosticTools has a test/Project.toml, which contains FFTW - Pkg.add("MCMCDiagnosticTools") - - TestEnv.activate(()->(@eval using FFTW), "MCMCDiagnosticTools") - @test isdefined(@__MODULE__, :FFTW) -end \ No newline at end of file diff --git a/test/runtests.jl b/test/runtests.jl index 889f146..98654dd 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -3,5 +3,6 @@ using TestEnv using Test @testset "TestEnv.jl" begin - include("runner.jl") + include("activate_do.jl") + include("activate_set.jl") end From 236d37ac4bc2621f4ca8b48d84ce1c8937976faf Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Wed, 4 Aug 2021 20:19:21 +0100 Subject: [PATCH 2/4] Fully align code structure with other branchs --- src/TestEnv.jl | 19 ++---- src/activate.jl | 58 ---------------- src/activate_do.jl | 19 ++++++ src/{make_test_env.jl => activate_set.jl} | 22 +++--- src/common.jl | 81 +++++++++++++++++++++++ src/exceptions.jl | 7 -- src/sandbox.jl | 11 --- src/test_dir.jl | 21 ------ 8 files changed, 117 insertions(+), 121 deletions(-) delete mode 100644 src/activate.jl create mode 100644 src/activate_do.jl rename src/{make_test_env.jl => activate_set.jl} (80%) create mode 100644 src/common.jl delete mode 100644 src/exceptions.jl delete mode 100644 src/sandbox.jl delete mode 100644 src/test_dir.jl diff --git a/src/TestEnv.jl b/src/TestEnv.jl index d66fe0b..463cc13 100644 --- a/src/TestEnv.jl +++ b/src/TestEnv.jl @@ -1,22 +1,15 @@ module TestEnv using Pkg using Pkg: PackageSpec -using Pkg.Types: Context, ensure_resolved, is_project_uuid, write_env +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: project_rel_path, project_resolve! - -using Pkg.Types: Types, projectfile_path, manifestfile_path -using Pkg.Operations: gen_target_project -using Pkg.Operations: update_package_test! -using Pkg.Types: is_stdlib using Pkg.Operations: sandbox, source_path, sandbox_preserve, abspath! +using Pkg.Operations: gen_target_project, update_package_test! - -include("exceptions.jl") - -include("activate.jl") -include("make_test_env.jl") -include("sandbox.jl") -include("test_dir.jl") +include("common.jl") +include("activate_do.jl") +include("activate_set.jl") end \ No newline at end of file diff --git a/src/activate.jl b/src/activate.jl deleted file mode 100644 index 3351f51..0000000 --- a/src/activate.jl +++ /dev/null @@ -1,58 +0,0 @@ -""" - TestEnv.activate(f, [pkg]) - -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()) - pkgspec = deepcopy(PackageSpec(pkg)) - ctx = Context() - isinstalled!(ctx, pkgspec) || throw(TestEnvError("$pkg not installed 👻")) - Pkg.instantiate(ctx) - return _sandbox(f, ctx, pkgspec) -end - -""" - TestEnv.activate([pkg]) - -Activate the test enviroment of `pkg` (defaults to current enviroment). -""" -function activate(pkg::AbstractString=current_pkg_name()) - pkgspec = deepcopy(PackageSpec(pkg)) - ctx = Context() - isinstalled!(ctx, pkgspec) || throw(TestEnvError("$pkg not installed 👻")) - Pkg.instantiate(ctx) - return make_test_env(ctx, pkgspec) -end - -current_pkg_name() = Context().env.pkg.name - -""" - 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. - -For Julia versions V1.4 and later, the first arguments of the Pkg functions used -is of type `Pkg.Types.Context`. For earlier versions, they are of type -`Pkg.Types.EnvCache`. -""" -function isinstalled!(ctx::Context, pkgspec::Pkg.Types.PackageSpec) - project_resolve!(ctx, [pkgspec]) - project_deps_resolve!(ctx, [pkgspec]) - manifest_resolve!(ctx, [pkgspec]) - - try - ensure_resolved(ctx, [pkgspec]) - catch err - err isa MethodError && rethrow() - return false - end - return true -end \ No newline at end of file diff --git a/src/activate_do.jl b/src/activate_do.jl new file mode 100644 index 0000000..b5bfab3 --- /dev/null +++ b/src/activate_do.jl @@ -0,0 +1,19 @@ +""" + TestEnv.activate(f, [pkg]) + +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()) + ctx, pkgspec = ctx_and_pkgspec(pkg) + test_project_override = maybe_gen_project_override!(ctx, pkgspec) + return sandbox(ctx, pkgspec, pkgspec.path, joinpath(pkgspec.path, "test"), test_project_override) do + flush(stdout) + f() + end +end \ No newline at end of file diff --git a/src/make_test_env.jl b/src/activate_set.jl similarity index 80% rename from src/make_test_env.jl rename to src/activate_set.jl index 4fb56a7..1dbb227 100644 --- a/src/make_test_env.jl +++ b/src/activate_set.jl @@ -1,14 +1,14 @@ +""" + TestEnv.activate([pkg]) -# Originally from Pkg.Operations.sandbox -function make_test_env(ctx::Context, target) - # This needs to be first as `gen_target_project` fixes `target.path` if it is nothing - sandbox_project_override = if !test_dir_has_project_file(ctx, target) - sandbox_project_override = gen_target_project(ctx, target, target.path, "test") - else - nothing - end +Activate the test enviroment of `pkg` (defaults to current enviroment). +""" +function activate(pkg::AbstractString=current_pkg_name()) + 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(target.path, "test") + sandbox_path = joinpath(pkgspec.path, "test") sandbox_project = projectfile_path(sandbox_path) tmp = mktempdir() @@ -25,7 +25,7 @@ function make_test_env(ctx::Context, target) # create merged manifest # - copy over active subgraph # - abspath! to maintain location of all deved nodes - working_manifest = abspath!(ctx, sandbox_preserve(ctx, target, tmp_project)) + working_manifest = abspath!(ctx, sandbox_preserve(ctx, pkgspec, tmp_project)) # - copy over fixed subgraphs from test subgraph # really only need to copy over "special" nodes @@ -52,7 +52,7 @@ function make_test_env(ctx::Context, target) Base.ACTIVE_PROJECT[] = nothing temp_ctx = Context() - temp_ctx.env.project.deps[target.name] = target.uuid + temp_ctx.env.project.deps[pkgspec.name] = pkgspec.uuid try Pkg.resolve(temp_ctx; io=devnull) diff --git a/src/common.jl b/src/common.jl new file mode 100644 index 0000000..a637237 --- /dev/null +++ b/src/common.jl @@ -0,0 +1,81 @@ +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 + + +current_pkg_name() = Context().env.pkg.name + +""" + 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. + +For Julia versions V1.4 and later, the first arguments of the Pkg functions used +is of type `Pkg.Types.Context`. For earlier versions, they are of type +`Pkg.Types.EnvCache`. +""" +function isinstalled!(ctx::Context, pkgspec::Pkg.Types.PackageSpec) + project_resolve!(ctx, [pkgspec]) + project_deps_resolve!(ctx, [pkgspec]) + manifest_resolve!(ctx, [pkgspec]) + + try + ensure_resolved(ctx, [pkgspec]) + catch err + err isa MethodError && rethrow() + return false + end + return true +end + +function test_dir_has_project_file(ctx, pkgspec) + return isfile(joinpath(get_test_dir(ctx, pkgspec), "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, pkgspec.uuid) + pkgspec.path = dirname(ctx.env.project_file) + pkgspec.version = ctx.env.pkg.version + else + update_package_test!(pkgspec, manifest_info(ctx, pkgspec.uuid)) + pkgspec.path = project_rel_path(ctx, source_path(ctx, pkgspec)) + end + pkgfilepath = source_path(ctx, pkgspec) + return joinpath(pkgfilepath, "test") +end + + +function maybe_gen_project_override!(ctx, pkgspec) + if !test_dir_has_project_file(ctx, pkgspec) + sandbox_project_override = gen_target_project(ctx, pkgspec, pkgspec.path, "test") + else + nothing + end +end \ No newline at end of file diff --git a/src/exceptions.jl b/src/exceptions.jl deleted file mode 100644 index d4ffc12..0000000 --- a/src/exceptions.jl +++ /dev/null @@ -1,7 +0,0 @@ -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 \ No newline at end of file diff --git a/src/sandbox.jl b/src/sandbox.jl deleted file mode 100644 index 3735575..0000000 --- a/src/sandbox.jl +++ /dev/null @@ -1,11 +0,0 @@ -function _sandbox(f, ctx, pkgspec) - test_project_override = if !test_dir_has_project_file(ctx, pkgspec) - gen_target_project(ctx, pkgspec, pkgspec.path, "test") - else - nothing - end - return sandbox(ctx, pkgspec, pkgspec.path, joinpath(pkgspec.path, "test"), test_project_override) do - flush(stdout) - f() - end -end diff --git a/src/test_dir.jl b/src/test_dir.jl deleted file mode 100644 index b1613aa..0000000 --- a/src/test_dir.jl +++ /dev/null @@ -1,21 +0,0 @@ -function test_dir_has_project_file(ctx, pkgspec) - return isfile(joinpath(get_test_dir(ctx, pkgspec), "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, pkgspec.uuid) - pkgspec.path = dirname(ctx.env.project_file) - pkgspec.version = ctx.env.pkg.version - else - update_package_test!(pkgspec, manifest_info(ctx, pkgspec.uuid)) - pkgspec.path = project_rel_path(ctx, source_path(ctx, pkgspec)) - end - pkgfilepath = source_path(ctx, pkgspec) - return joinpath(pkgfilepath, "test") -end From add38c65f0867bb29104f9602d99323025c43484 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Tue, 3 Aug 2021 20:46:05 +0100 Subject: [PATCH 3/4] Make activate set not mess with LOAD_PATH Make sure it really deactivated Apply suggestions from code review --- src/activate_set.jl | 9 +-------- test/activate_set.jl | 16 ++++++++++++++-- 2 files changed, 15 insertions(+), 10 deletions(-) diff --git a/src/activate_set.jl b/src/activate_set.jl index 1dbb227..853a60b 100644 --- a/src/activate_set.jl +++ b/src/activate_set.jl @@ -47,9 +47,7 @@ function activate(pkg::AbstractString=current_pkg_name()) Types.write_manifest(working_manifest, tmp_manifest) - # sandbox - push!(empty!(LOAD_PATH), "@", tmp) - Base.ACTIVE_PROJECT[] = nothing + Base.ACTIVE_PROJECT[] = tmp_project temp_ctx = Context() temp_ctx.env.project.deps[pkgspec.name] = pkgspec.uuid @@ -75,11 +73,6 @@ function activate(pkg::AbstractString=current_pkg_name()) end end write_env(temp_ctx.env; update_undo=false) - - # update enviroment variables - path_sep = Sys.iswindows() ? ';' : ':' - ENV["JULIA_LOAD_PATH"] = "@$(path_sep)$(tmp)" - delete!(ENV, "JULIA_PROJECT") return Base.active_project() end \ No newline at end of file diff --git a/test/activate_set.jl b/test/activate_set.jl index 7f2e1ed..f41f2f7 100644 --- a/test/activate_set.jl +++ b/test/activate_set.jl @@ -1,30 +1,42 @@ @testset "activate_set.jl" begin @testset "activate [extras]" begin orig_project_toml_path = Base.active_project() + push!(LOAD_PATH, mktempdir()) # put something weird in LOAD_PATH for testing + orig_load_path = Base.LOAD_PATH try TestEnv.activate("ChainRulesCore") new_project_toml_path = Base.active_project() @test new_project_toml_path != orig_project_toml_path + @test orig_load_path == Base.LOAD_PATH - @eval using StaticArrays + @eval using StaticArrays # From ChainRulesCore [extras] Project.toml + @test isdefined(@__MODULE__, :StaticArrays) + + @eval using Compat # from ChainRulesCore Project.toml @test isdefined(@__MODULE__, :StaticArrays) finally Pkg.activate(orig_project_toml_path) + # No longer is enviroment active + @test_throws ArgumentError @eval using OffsetArrays end end @testset "activate test/Project" begin orig_project_toml_path = Base.active_project() + push!(LOAD_PATH, mktempdir()) # put something weird in LOAD_PATH for testing + orig_load_path = Base.LOAD_PATH try # YAXArrays has a test/Project.toml, which contains CSV TestEnv.activate("YAXArrays") new_project_toml_path = Base.active_project() @test new_project_toml_path != orig_project_toml_path + @test orig_load_path == Base.LOAD_PATH @eval using CSV @test isdefined(@__MODULE__, :CSV) + finally Pkg.activate(orig_project_toml_path) end end -end \ No newline at end of file +end From cc0000e1830c62d3037977b4cdf3ed857acd8cb7 Mon Sep 17 00:00:00 2001 From: Lyndon White Date: Wed, 4 Aug 2021 21:15:35 +0100 Subject: [PATCH 4/4] bump version --- Project.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Project.toml b/Project.toml index 14bae96..a451fee 100644 --- a/Project.toml +++ b/Project.toml @@ -1,6 +1,6 @@ name = "TestEnv" uuid = "1e6cf692-eddd-4d53-88a5-2d735e33781b" -version = "1.4.0" +version = "1.4.1" [deps] Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f"