Skip to content

Commit e9a4230

Browse files
authored
Refactor LazyTestResult away (#237)
1 parent f3e9fd9 commit e9a4230

File tree

18 files changed

+211
-311
lines changed

18 files changed

+211
-311
lines changed

src/Aqua.jl

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ using Base: PkgId, UUID
44
using Pkg: Pkg, TOML, PackageSpec
55
using Test
66

7+
@static if VERSION < v"1.1.0-DEV.472"
8+
using Compat: isnothing
9+
end
710
@static if VERSION < v"1.3.0-DEV.349"
811
using Compat: findfirst
912
end

src/ambiguities.jl

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -29,28 +29,6 @@ test_ambiguities(packages; kwargs...) = _test_ambiguities(aspkgids(packages); kw
2929

3030
const ExcludeSpec = Pair{Base.PkgId,String}
3131

32-
aspkgids(pkg::Union{Module,PkgId}) = aspkgids([pkg])
33-
aspkgids(packages) = mapfoldl(aspkgid, push!, packages, init = PkgId[])
34-
35-
aspkgid(pkg::PkgId) = pkg
36-
function aspkgid(m::Module)
37-
if !ispackage(m)
38-
error("Non-package (non-toplevel) module is not supported. Got: $m")
39-
end
40-
return PkgId(m)
41-
end
42-
function aspkgid(name::Symbol)
43-
# Maybe `Base.depwarn()`
44-
return Base.identify_package(String(name))::PkgId
45-
end
46-
47-
ispackage(m::Module) =
48-
if m in (Base, Core)
49-
true
50-
else
51-
parentmodule(m) == m
52-
end
53-
5432
strnameof(x) = string(x)
5533
strnameof(x::Type) = string(nameof(x))
5634

src/deps_compat.jl

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -81,9 +81,8 @@ function test_julia_compat(pkg::PkgId; broken::Bool = false)
8181
end
8282

8383
function has_julia_compat(pkg::PkgId)
84-
result = root_project_or_failed_lazytest(pkg)
85-
result isa LazyTestResult && error("Unable to locate Project.toml")
86-
root_project_path = result
84+
root_project_path, found = root_project_toml(pkg)
85+
found || error("Unable to locate Project.toml")
8786
prj = TOML.parsefile(root_project_path)
8887
return has_julia_compat(prj)
8988
end
@@ -93,9 +92,8 @@ function has_julia_compat(prj::Dict{String,Any})
9392
end
9493

9594
function find_missing_deps_compat(pkg::PkgId, deps_type::String = "deps"; kwargs...)
96-
result = root_project_or_failed_lazytest(pkg)
97-
result isa LazyTestResult && error("Unable to locate Project.toml")
98-
root_project_path = result
95+
root_project_path, found = root_project_toml(pkg)
96+
found || error("Unable to locate Project.toml")
9997
missing_compat =
10098
find_missing_deps_compat(TOML.parsefile(root_project_path), deps_type; kwargs...)
10199

src/persistent_tasks.jl

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -87,9 +87,9 @@ function test_persistent_tasks(package::Module; kwargs...)
8787
end
8888

8989
function has_persistent_tasks(package::PkgId; tmax = 10)
90-
result = root_project_or_failed_lazytest(package)
91-
result isa LazyTestResult && error("Unable to locate Project.toml")
92-
return !precompile_wrapper(result, tmax)
90+
root_project_path, found = root_project_toml(package)
91+
found || error("Unable to locate Project.toml")
92+
return !precompile_wrapper(root_project_path, tmax)
9393
end
9494

9595
"""
@@ -102,9 +102,9 @@ These are likely the ones blocking precompilation of your package.
102102
Any additional kwargs (e.g., `tmax`) are passed to [`Aqua.test_persistent_tasks`](@ref).
103103
"""
104104
function find_persistent_tasks_deps(package::PkgId; kwargs...)
105-
result = root_project_or_failed_lazytest(package)
106-
result isa LazyTestResult && error("Unable to locate Project.toml")
107-
prj = TOML.parsefile(result)
105+
root_project_path, found = root_project_toml(package)
106+
found || error("Unable to locate Project.toml")
107+
prj = TOML.parsefile(root_project_path)
108108
deps = get(prj, "deps", Dict{String,Any}())
109109
filter!(deps) do (name, uuid)
110110
id = PkgId(UUID(uuid), name)
@@ -121,7 +121,7 @@ function precompile_wrapper(project, tmax)
121121
if VERSION < v"1.10.0-"
122122
return true
123123
end
124-
prev_project = Base.active_project()
124+
prev_project = Base.active_project()::String
125125
isdefined(Pkg, :respect_sysimage_versions) && Pkg.respect_sysimage_versions(false)
126126
try
127127
pkgdir = dirname(project)

src/project_extras.jl

Lines changed: 55 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -7,103 +7,85 @@ Check that test target of the root project and test project
77
Julia < 1.2 while recording test-only dependency compatibility in
88
`test/Project.toml`.
99
"""
10-
function test_project_extras(packages)
11-
@testset "$(result.label)" for result in analyze_project_extras(packages)
12-
@debug result.label result
13-
@test result true
14-
end
10+
function test_project_extras(pkg::PkgId; kwargs...)
11+
msgs = analyze_project_extras(pkg; kwargs...)
12+
@test isempty(msgs)
1513
end
1614

17-
function project_toml_path(dir)
18-
candidates = joinpath.(dir, ["Project.toml", "JuliaProject.toml"])
19-
i = findfirst(isfile, candidates)
20-
i === nothing && return candidates[1], false
21-
return candidates[i], true
15+
# Remove with next breaking version
16+
function test_project_extras(packages::Vector{<:Union{Module,PkgId}}; kwargs...)
17+
@testset "$pkg" for pkg in packages
18+
test_project_extras(pkg; kwargs...)
19+
end
2220
end
2321

24-
analyze_project_extras(packages) = map(_analyze_project_extras, aspkgids(packages))
22+
function test_project_extras(mod::Module; kwargs...)
23+
test_project_extras(aspkgid(mod); kwargs...)
24+
end
2525

2626
is_julia12_or_later(compat::AbstractString) = is_julia12_or_later(semver_spec(compat))
2727
is_julia12_or_later(compat::VersionSpec) = isempty(compat semver_spec("1.0 - 1.1"))
2828

29-
function _analyze_project_extras(pkg::PkgId)
30-
label = string(pkg)
29+
function analyze_project_extras(pkg::PkgId)
30+
root_project_path, found = root_project_toml(pkg)
31+
found || error("Unable to locate Project.toml")
3132

32-
result = root_project_or_failed_lazytest(pkg)
33-
result isa LazyTestResult && return result
34-
root_project_path = result
35-
36-
package_loc = Base.locate_package(pkg)
37-
package_loc === nothing &&
38-
return LazyTestResult(label, "Base.locate_package failed.", false)
39-
pkgpath = dirname(dirname(package_loc))
40-
test_project_path, found = project_toml_path(joinpath(pkgpath, "test"))
41-
if !found
42-
return LazyTestResult(label, "test/Project.toml file does not exist.", true)
43-
end
33+
test_project_path, found =
34+
project_toml_path(joinpath(dirname(root_project_path), "test"))
35+
found || return String[] # having no test/Project.toml is fine
4436
root_project = TOML.parsefile(root_project_path)
4537
test_project = TOML.parsefile(test_project_path)
4638

4739
# Ignore root project's extras if only supporting julia 1.2 or later.
4840
# See: # https://julialang.github.io/Pkg.jl/v1/creating-packages/#Test-specific-dependencies-in-Julia-1.2-and-above-1
49-
julia_version = get(get(root_project, "compat", Dict()), "julia", "1")
50-
if is_julia12_or_later(julia_version)
51-
return LazyTestResult(
52-
label,
53-
string(
54-
"Supporting only post-1.2 `julia` ($julia_version); ",
55-
"ignoring root project.",
56-
),
57-
true,
58-
)
59-
end
41+
julia_version = get(get(root_project, "compat", Dict{String,Any}()), "julia", nothing)
42+
isnothing(julia_version) && return String["Could not find `julia` compat."]
43+
is_julia12_or_later(julia_version) && return String[]
6044

61-
# `extras_deps`: test-only dependencies according to /Project.toml
62-
all_extras_deps = get(root_project, "extras", Dict())
63-
target = Set{String}(get(get(root_project, "targets", Dict()), "test", []))
64-
extras_deps = setdiff(
65-
Set{Pair{String,String}}(p for p in all_extras_deps if first(p) in target),
66-
Set{Pair{String,String}}(get(root_project, "deps", [])),
45+
# `extras_test_deps`: test-only dependencies according to Project.toml
46+
deps = [PkgId(UUID(v), k) for (k, v) in get(root_project, "deps", Dict{String,Any}())]
47+
target =
48+
Set{String}(get(get(root_project, "targets", Dict{String,Any}()), "test", String[]))
49+
extras_test_deps = setdiff(
50+
[
51+
PkgId(UUID(v), k) for
52+
(k, v) in get(root_project, "extras", Dict{String,Any}()) if k in target
53+
],
54+
deps,
6755
)
6856

69-
# `test_deps`: test-only dependencies according to /test/Project.toml:
57+
# `test_deps`: test-only dependencies according to test/Project.toml:
7058
test_deps = setdiff(
71-
Set{Pair{String,String}}(get(test_project, "deps", [])),
72-
Set{Pair{String,String}}(get(root_project, "deps", [])),
73-
[root_project["name"] => root_project["uuid"]],
59+
[PkgId(UUID(v), k) for (k, v) in get(test_project, "deps", Dict{String,Any}())],
60+
deps,
61+
[PkgId(UUID(root_project["uuid"]), root_project["name"])],
7462
)
7563

76-
not_in_extras = setdiff(test_deps, extras_deps)
77-
not_in_test = setdiff(extras_deps, test_deps)
64+
not_in_extras = setdiff(test_deps, extras_test_deps)
65+
not_in_test = setdiff(extras_test_deps, test_deps)
7866
if isempty(not_in_extras) && isempty(not_in_test)
79-
return LazyTestResult(
80-
label,
81-
"""
82-
Root and test projects are consistent.
83-
Root project: $root_project_path
84-
Test project: $test_project_path
85-
""",
86-
true,
87-
)
67+
return String[]
8868
else
89-
msg = sprint() do io
90-
println(
91-
io,
92-
"Root and test projects should be consistent for projects supporting Julia <= 1.1.",
93-
)
94-
if !isempty(not_in_extras)
95-
println(io, "Test dependencies not in root project ($root_project_path):")
96-
for (name, uuid) in sort!(collect(not_in_extras))
97-
println(io, " $name = \"$uuid\"")
98-
end
69+
msgs = String[]
70+
push!(
71+
msgs,
72+
"Root and test projects should be consistent for projects supporting Julia <= 1.1.",
73+
)
74+
if !isempty(not_in_extras)
75+
msg = "Test dependencies not in root project ($root_project_path):"
76+
for pkgs in sort!(collect(not_in_extras); by = (pkg -> pkg.name))
77+
msg *= "\n\t$pkgs"
9978
end
100-
if !isempty(not_in_test)
101-
println(io, "Dependencies not in test project ($test_project_path):")
102-
for (name, uuid) in sort!(collect(not_in_test))
103-
println(io, " $name = \"$uuid\"")
104-
end
79+
push!(msgs, msg)
80+
end
81+
if !isempty(not_in_test)
82+
msg = "Dependencies not in test project ($test_project_path):"
83+
for pkgs in sort!(collect(not_in_test); by = (pkg -> pkg.name))
84+
msg *= "\n\t$pkgs"
10585
end
86+
push!(msgs, msg)
10687
end
107-
return LazyTestResult(label, msg, false)
88+
89+
return msgs
10890
end
10991
end

src/stale_deps.jl

Lines changed: 20 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -26,34 +26,29 @@ directly, this can be achieved via transitivity as well.
2626
# Keyword Arguments
2727
- `ignore::Vector{Symbol}`: names of dependent packages to be ignored.
2828
"""
29-
function test_stale_deps(packages; kwargs...)
30-
@testset "$(result.label)" for result in analyze_stale_deps(packages, kwargs...)
31-
@debug result.label result
32-
@test result true
33-
end
29+
function test_stale_deps(pkg::PkgId; kwargs...)
30+
stale_deps = find_stale_deps(pkg; kwargs...)
31+
@test isempty(stale_deps)
3432
end
3533

36-
analyze_stale_deps(packages, kwargs...) =
37-
[_analyze_stale_deps_1(pkg; kwargs...) for pkg in aspkgids(packages)]
34+
function test_stale_deps(mod::Module; kwargs...)
35+
test_stale_deps(aspkgid(mod); kwargs...)
36+
end
3837

39-
function _analyze_stale_deps_1(pkg::PkgId; ignore::AbstractVector{Symbol} = Symbol[])
40-
label = "$pkg"
38+
# Remove in next breaking release
39+
function test_stale_deps(packages::Vector{<:Union{Module,PkgId}}; kwargs...)
40+
@testset "$pkg" for pkg in packages
41+
test_stale_deps(pkg; kwargs...)
42+
end
43+
end
4144

42-
result = root_project_or_failed_lazytest(pkg)
43-
result isa LazyTestResult && return result
44-
root_project_path = result
45+
function find_stale_deps(pkg::PkgId; ignore::AbstractVector{Symbol} = Symbol[])
46+
root_project_path, found = root_project_toml(pkg)
47+
found || error("Unable to locate Project.toml")
4548

46-
@debug "Parsing `$root_project_path`"
4749
prj = TOML.parsefile(root_project_path)
48-
raw_deps = get(prj, "deps", nothing)
49-
if raw_deps === nothing
50-
return LazyTestResult(label, "No `deps` table in `$root_project_path`", true)
51-
end
52-
deps = [PkgId(UUID(v), k) for (k, v) in raw_deps]
53-
54-
raw_weakdeps = get(prj, "weakdeps", nothing)
55-
weakdeps =
56-
isnothing(raw_weakdeps) ? PkgId[] : [PkgId(UUID(v), k) for (k, v) in raw_weakdeps]
50+
deps = [PkgId(UUID(v), k) for (k, v) in get(prj, "deps", Dict{String,Any}())]
51+
weakdeps = [PkgId(UUID(v), k) for (k, v) in get(prj, "weakdeps", Dict{String,Any}())]
5752

5853
marker = "_START_MARKER_"
5954
code = """
@@ -66,14 +61,12 @@ function _analyze_stale_deps_1(pkg::PkgId; ignore::AbstractVector{Symbol} = Symb
6661
"""
6762
cmd = Base.julia_cmd()
6863
output = read(`$cmd --startup-file=no --color=no -e $code`, String)
69-
@debug("Checked modules loaded in a separate process.", cmd, Text(code), Text(output))
7064
pos = findfirst(marker, output)
7165
@assert !isnothing(pos)
7266
output = output[pos.stop+1:end]
7367
loaded_uuids = map(UUID, eachline(IOBuffer(output)))
7468

75-
return _analyze_stale_deps_2(;
76-
pkg = pkg,
69+
return find_stale_deps_2(;
7770
deps = deps,
7871
weakdeps = weakdeps,
7972
loaded_uuids = loaded_uuids,
@@ -82,14 +75,12 @@ function _analyze_stale_deps_1(pkg::PkgId; ignore::AbstractVector{Symbol} = Symb
8275
end
8376

8477
# Side-effect -free part of stale dependency analysis.
85-
function _analyze_stale_deps_2(;
86-
pkg::PkgId,
78+
function find_stale_deps_2(;
8779
deps::AbstractVector{PkgId},
8880
weakdeps::AbstractVector{PkgId},
8981
loaded_uuids::AbstractVector{UUID},
9082
ignore::AbstractVector{Symbol},
9183
)
92-
label = "$pkg"
9384
deps_uuids = [p.uuid for p in deps]
9485
pkgid_from_uuid = Dict(p.uuid => p for p in deps)
9586

@@ -98,24 +89,5 @@ function _analyze_stale_deps_2(;
9889
stale_pkgs = setdiff(stale_pkgs, weakdeps)
9990
stale_pkgs = [p for p in stale_pkgs if !(Symbol(p.name) in ignore)]
10091

101-
if isempty(stale_pkgs)
102-
return LazyTestResult(
103-
label,
104-
"""
105-
All packages in `deps` are loaded via `using $(pkg.name)`.
106-
""",
107-
true,
108-
)
109-
end
110-
111-
stale_msg = join(("* $p" for p in stale_pkgs), "\n")
112-
msglines = [
113-
"Some package(s) in `deps` of $pkg are not loaded during via" *
114-
" `using $(pkg.name)`.",
115-
stale_msg,
116-
"",
117-
"To ignore from stale dependency detection, pass the package name to" *
118-
" `ignore` keyword argument of `Aqua.test_stale_deps`",
119-
]
120-
return LazyTestResult(label, join(msglines, "\n"), false)
92+
return stale_pkgs
12193
end

0 commit comments

Comments
 (0)