From f90945d1ca0a7f80e9b67127e88373fb60af3ee8 Mon Sep 17 00:00:00 2001 From: Dilum Aluthge Date: Wed, 15 Nov 2023 17:30:40 -0500 Subject: [PATCH] CI: Respect `[compat]` entries for test-only deps when running in Base Julia's Buildkite CI --- test/ambiguous.jl | 115 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 102 insertions(+), 13 deletions(-) diff --git a/test/ambiguous.jl b/test/ambiguous.jl index 12c9d66f..1ffba300 100644 --- a/test/ambiguous.jl +++ b/test/ambiguous.jl @@ -8,23 +8,110 @@ original_env = copy(ENV) original_project = Base.active_project() ### +module MyTestDepsUtils + import Pkg -# Because julia CI doesn't run stdlib tests via `Pkg.test` test deps must be manually installed if missing -if Base.find_package("Aqua") === nothing - @debug "Installing Aqua.jl for SparseArrays.jl tests" - iob = IOBuffer() - Pkg.activate(; temp = true) - try - # TODO: make this version tie to compat in Project.toml - # or do this another safer way - Pkg.add(name="Aqua", version="0.8", io=iob) # Needed for custom julia version resolve tests - catch - println(String(take!(iob))) - rethrow() +function get_project_dict() + root_test = @__DIR__ # ./test/ + root = dirname(root_test) # ./ + project_filename = joinpath(root, "Project.toml") # ./Project.toml + project_dict = Pkg.TOML.parsefile(project_filename) + return project_dict +end + +# If someone makes a PR to this repo to add a +# `test/Project.toml` file, then this whole approach will break. +function assert_no_test_project_toml() + root_test = @__DIR__ # ./test/ + root_test_project_toml = joinpath(root_test, "Project.toml") # ./test/Project.toml + if ispath(root_test_project_toml) + error("Currently, we don't support test/Project.toml in this repo") + end + return nothing +end + +function get_test_deps() + project_dict = get_project_dict() + targets_section = project_dict["targets"] + test_target_list = targets_section["test"]::AbstractVector + return sort(unique(test_target_list)) +end + +function get_dep_uuid_str(pkg_name::AbstractString) + project_dict = get_project_dict() + deps_section = get(project_dict, "deps", Dict()) + extras_section = get(project_dict, "extras", Dict()) + if haskey(deps_section, pkg_name) + pkg_uuid_str = deps_section[pkg_name]::AbstractString + else + pkg_uuid_str = extras_section[pkg_name]::AbstractString + end + return pkg_uuid_str +end + +function get_compat(pkg_name::AbstractString) + project_dict = get_project_dict() + compat_section = project_dict["compat"] + pkg_compat_str = compat_section[pkg_name]::AbstractString + return pkg_compat_str +end + +# Base Julia's Buildkite CI doesn't run stdlib tests +# via `Pkg.test`. Therefore, test deps must be manually +# installed if missing. +function install_all_test_deps() + assert_no_test_project_toml() + test_deps = get_test_deps() + + # If all the test deps are already available, + # we don't even bother activating a temp project. + project = nothing + + for pkg_name in test_deps + (; project) = install_single_test_dep(pkg_name; project) + end + return nothing +end + +function install_single_test_dep(pkg_name::AbstractString; project::Union{AbstractString, Nothing}) + pkg_uuid_str = get_dep_uuid_str(pkg_name) + pkg_compat = get_compat(pkg_name) + found_package = Base.find_package(pkg_name) + if found_package === nothing + # We didn't find the package, so we need to install it. + @debug "SparseArrays.jl tests: Installing $(pkg_name).jl" + iob = IOBuffer() + if project === nothing + Pkg.activate(; temp = true) + project = Base.active_project()::AbstractString + @debug "Activated a new temp project at $(project)" + end + pkg_spec = Pkg.PackageSpec(; + name = pkg_name, + version = pkg_compat, # make sure we respect the `[compat]` entry + uuid = pkg_uuid_str, + ) + try + # To keep the logs (the Base Julia Buildkite CI logs) clean, + # we don't print the Pkg output to the log unless the `Pkg.add` + # fails. Therefore, we pass `io = iob`. + Pkg.add(pkg_spec; io = iob) + catch + println(String(take!(iob))) + rethrow() + end + else + # We found the package, so we don't need to install it. + @debug "SparseArrays.jl tests: found $(pkg_name).jl" found_package end + return (; project) end +end # module MyTestDepsUtils + +MyTestDepsUtils.install_all_test_deps() + using Test, LinearAlgebra, SparseArrays, Aqua @testset "code quality" begin @@ -46,7 +133,9 @@ using Test, LinearAlgebra, SparseArrays, Aqua @testset "Compat bounds" begin Aqua.test_deps_compat(SparseArrays) end - + @testset "Project.toml formatting" begin + Aqua.test_project_toml_formatting(SparseArrays) + end @testset "Piracy" begin @test_broken Aqua.Piracy.hunt(SparseArrays) == Method[] end