From 0496961b2d91e27d9b1af5d64756efe955dabc18 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Lars=20G=C3=B6ttgens?= Date: Tue, 18 Jul 2023 14:37:45 +0200 Subject: [PATCH] Test ambiguities in package extension --- src/ambiguities.jl | 81 ++++++++++++++++++++++++++++++++++++++++------ src/utils.jl | 17 ++++++++++ 2 files changed, 89 insertions(+), 9 deletions(-) diff --git a/src/ambiguities.jl b/src/ambiguities.jl index 5c9057cc..b3723372 100644 --- a/src/ambiguities.jl +++ b/src/ambiguities.jl @@ -84,27 +84,87 @@ function reprexclude(exspecs::Vector{ExcludeSpec}) return string("Aqua.ExcludeSpec[", join(itemreprs, ", "), "]") end -function _test_ambiguities(packages::Vector{PkgId}; broken::Bool = false, kwargs...) - num_ambiguities, strout, strerr = _find_ambiguities(packages; kwargs...) +function _test_ambiguities( + packages::Vector{PkgId}; + broken::Bool = false, + extension_combinations = :default, + kwargs..., +) + if extension_combinations == :default + extension_combinations = Vector{String}[] + push!(extension_combinations, String[]) + @static if JULIA_HAS_EXTENSIONS + all_exts = String[] + for pkg in setdiff(packages, [PkgId(Base), PkgId(Core)]) + exts, _, _ = get_extension_data_from_toml(pkg) + for e in keys(exts) + push!(extension_combinations, [e]) + end + push!(extension_combinations, collect(keys(exts))) + append!(all_exts, collect(keys(exts))) + end + push!(extension_combinations, all_exts) + end + unique!(extension_combinations) + end + for extensions in extension_combinations + @info "Testing ambiguities with extensions: $extensions" + num_ambiguities, strout, strerr = + _find_ambiguities(packages; extensions = extensions, kwargs...) - print(stderr, strerr) - print(stdout, strout) + print(stderr, strerr) + print(stdout, strout) - if broken - @test_broken num_ambiguities == 0 - else - @test num_ambiguities == 0 + if broken + @test_broken num_ambiguities == 0 + else + @test num_ambiguities == 0 + end end + end function _find_ambiguities( packages::Vector{PkgId}; color::Union{Bool,Nothing} = nothing, exclude::AbstractVector = [], + extensions::AbstractVector = [], # Options to be passed to `Test.detect_ambiguities`: detect_ambiguities_options..., ) + packages = copy(packages) + extdeppackages = PkgId[] + @static if JULIA_HAS_EXTENSIONS + extensions = String.(extensions) + for ext in extensions + found = false + for pkg in setdiff(packages, [PkgId(Base), PkgId(Core)]) + exts, weakdeps, deps = get_extension_data_from_toml(pkg) + if haskey(exts, ext) + found = true + extdeps = exts[ext] isa String ? [exts[ext]] : exts[ext] + for extdepname in extdeps + if haskey(deps, extdepname) + push!(extdeppackages, deps[extdepname]) + elseif haskey(weakdeps, extdepname) + push!(extdeppackages, weakdeps[extdepname]) + else + error( + "Extension $ext depends on $extdepname, but it is not found.", + ) + end + end + push!(packages, PkgId(Base.uuid5(pkg.uuid, ext), ext)) + break + end + end + found && continue + error("Extension $ext is not found.") + end + end + packages_repr = reprpkgids(collect(packages)) + extdeppackages_repr = reprpkgids(collect(extdeppackages)) options_repr = checked_repr((; recursive = true, detect_ambiguities_options...)) exclude_repr = reprexclude(normalize_and_check_exclude(exclude)) @@ -115,6 +175,7 @@ function _find_ambiguities( using Aqua Aqua.test_ambiguities_impl( $packages_repr, + $extdeppackages_repr, $options_repr, $exclude_repr, ) || exit(1) @@ -143,7 +204,7 @@ end function reprpkgids(packages::Vector{PkgId}) packages_repr = sprint() do io - println(io, '[') + println(io, "Base.PkgId[") for pkg in packages println(io, reprpkgid(pkg)) end @@ -200,9 +261,11 @@ end function test_ambiguities_impl( packages::Vector{PkgId}, + extdeppackages::Vector{PkgId}, options::NamedTuple, exspecs::Vector{ExcludeSpec}, ) + deps = map(Base.require, extdeppackages) modules = map(Base.require, packages) @debug "Testing method ambiguities" modules ambiguities = detect_ambiguities(modules...; options...) diff --git a/src/utils.jl b/src/utils.jl index 0179714e..0b1c57a4 100644 --- a/src/utils.jl +++ b/src/utils.jl @@ -96,6 +96,23 @@ catch end end +function get_extension_data_from_toml(pkg::PkgId) + root_project_path = root_project_or_failed_lazytest(pkg) + root_project_path isa LazyTestResult && + return Dict{String,Any}(), Dict{String,Any}(), Dict{String,Any}() + + @debug "Parsing `$root_project_path`" + prj = TOML.parsefile(root_project_path) + raw_exts = get(prj, "extensions", Dict{String,Any}()) + + raw_weakdeps = get(prj, "weakdeps", Dict{String,Any}()) + weakdeps = Dict(name => PkgId(UUID(uuid), name) for (name, uuid) in raw_weakdeps) + + raw_deps = get(prj, "deps", Dict{String,Any}()) + deps = Dict(name => PkgId(UUID(uuid), name) for (name, uuid) in raw_deps) + return raw_exts, weakdeps, deps +end + const _project_key_order = [ "name", "uuid",