Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make loading work when stdlib deps are missing in the manifest #56148

Merged
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 37 additions & 0 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,21 @@ function find_package(arg) # ::Union{Nothing,String}
return locate_package(pkg, env)
end

# is there a better/faster ground truth?
function is_stdlib(pkgid::PkgId)
pkgid.name in readdir(Sys.STDLIB) || return false
stdlib_root = joinpath(Sys.STDLIB, pkgid.name)
project_file = locate_project_file(stdlib_root)
if project_file isa String
d = parsed_toml(project_file)
uuid = get(d, "uuid", nothing)
if uuid !== nothing
return UUID(uuid) == pkgid.uuid
end
end
return false
end

"""
Base.identify_package_env(name::String)::Union{Tuple{PkgId, String}, Nothing}
Base.identify_package_env(where::Union{Module,PkgId}, name::String)::Union{Tuple{PkgId, Union{String, Nothing}}, Nothing}
Expand Down Expand Up @@ -336,6 +351,12 @@ function identify_package_env(where::PkgId, name::String)
end
break # found in implicit environment--return "not found"
end
if pkg_env === nothing && is_stdlib(where)
# if not found it could be that manifests are from a different julia version/commit
# where stdlib dependencies have changed, so look up deps based on the stdlib Project.toml
# as a fallback
pkg_env = identify_stdlib_project_dep(where, name)
end
end
if cache !== nothing
cache.identified_where[(where, name)] = pkg_env
Expand All @@ -362,6 +383,22 @@ function identify_package_env(name::String)
return pkg_env
end

function identify_stdlib_project_dep(stdlib::PkgId, depname::String)
@debug """
Stdlib $(repr("text/plain", stdlib)) is trying to load `$depname`
which is not listed as a dep in the load path manifests, so resorting to search
in the stdlib Project.tomls for true deps"""
stdlib_projfile = locate_project_file(joinpath(Sys.STDLIB, stdlib.name))
stdlib_projfile === nothing && return nothing
found = explicit_project_deps_get(stdlib_projfile, depname)
if found !== nothing
@debug "$(repr("text/plain", stdlib)) indeed depends on $depname in project $stdlib_projfile"
pkgid = PkgId(found, depname)
return pkgid, stdlib_projfile
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure that we want to return stdlib_projfile as the env it was found in.. could that have unintended consequences for say extensions?

end
return nothing
end

_nothing_or_first(x) = x === nothing ? nothing : first(x)

"""
Expand Down
12 changes: 12 additions & 0 deletions test/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -1341,6 +1341,18 @@ end
end
end

@testset "Fallback for stdlib deps if manifest deps aren't found" begin
mktempdir() do depot
# This manifest has a LibGit2 entry that is missing LibGit2_jll, which should be
# handled by falling back to the stdlib Project.toml for dependency truth.
badmanifest_test_dir = joinpath(@__DIR__, "project", "deps", "BadStdlibDeps.jl")
@test success(addenv(
`$(Base.julia_cmd()) --project=$badmanifest_test_dir --startup-file=no -e 'using LibGit2'`,
"JULIA_DEPOT_PATH" => depot * Base.Filesystem.pathsep(),
))
end
end

@testset "code coverage disabled during precompilation" begin
mktempdir() do depot
cov_test_dir = joinpath(@__DIR__, "project", "deps", "CovTest.jl")
Expand Down
51 changes: 51 additions & 0 deletions test/project/deps/BadStdlibDeps/Manifest.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
# This file is machine-generated - editing it directly is not advised

julia_version = "1.12.0-DEV"
manifest_format = "2.0"
project_hash = "dc9d33b0ee13d9466bdb75b8d375808a534a79ec"

[[deps.Artifacts]]
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
version = "1.11.0"

# This is intentionally missing LibGit2_jll for testing purposes
[[deps.LibGit2]]
deps = ["NetworkOptions", "Printf", "SHA"]
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
version = "1.11.0"

[[deps.LibGit2_jll]]
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"]
uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5"
version = "1.8.0+0"

[[deps.LibSSH2_jll]]
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
version = "1.11.0+1"

[[deps.Libdl]]
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
version = "1.11.0"

[[deps.MbedTLS_jll]]
deps = ["Artifacts", "Libdl"]
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
version = "2.28.6+1"

[[deps.NetworkOptions]]
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
version = "1.2.0"

[[deps.Printf]]
deps = ["Unicode"]
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
version = "1.11.0"

[[deps.SHA]]
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
version = "0.7.0"

[[deps.Unicode]]
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
version = "1.11.0"
2 changes: 2 additions & 0 deletions test/project/deps/BadStdlibDeps/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[deps]
LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"