Skip to content

Commit b02d671

Browse files
Make loading work when stdlib deps are missing in the manifest (#56148)
Closes #56109 Simulating a bad manifest by having `LibGit2_jll` missing as a dep of `LibGit2` in my default env, say because the manifest was generated by a different julia version or different master julia commit. ## This PR, it just works ``` julia> using Revise julia> ``` i.e. ``` % JULIA_DEBUG=loading ./julia --startup-file=no julia> using Revise ... ┌ Debug: Stdlib LibGit2 [76f85450-5226-5b5a-8eaa-529ad045b433] is trying to load `LibGit2_jll` │ which is not listed as a dep in the load path manifests, so resorting to search │ in the stdlib Project.tomls for true deps └ @ Base loading.jl:387 ┌ Debug: LibGit2 [76f85450-5226-5b5a-8eaa-529ad045b433] indeed depends on LibGit2_jll in project /Users/ian/Documents/GitHub/julia/usr/share/julia/stdlib/v1.12/LibGit2/Project.toml └ @ Base loading.jl:395 ... julia> ``` ## Master ``` julia> using Revise Info Given Revise was explicitly requested, output will be shown live ERROR: LoadError: ArgumentError: Package LibGit2 does not have LibGit2_jll in its dependencies: - Note that the following manifests in the load path were resolved with a potentially different DEV version of the current version, which may be the cause of the error. Try to re-resolve them in the current version, or consider deleting them if that fails: /Users/ian/.julia/environments/v1.12/Manifest.toml - You may have a partially installed environment. Try `Pkg.instantiate()` to ensure all packages in the environment are installed. - Or, if you have LibGit2 checked out for development and have added LibGit2_jll as a dependency but haven't updated your primary environment's manifest file, try `Pkg.resolve()`. - Otherwise you may need to report an issue with LibGit2 ... ```
1 parent d09abe5 commit b02d671

File tree

4 files changed

+102
-0
lines changed

4 files changed

+102
-0
lines changed

base/loading.jl

+37
Original file line numberDiff line numberDiff line change
@@ -308,6 +308,21 @@ function find_package(arg) # ::Union{Nothing,String}
308308
return locate_package(pkg, env)
309309
end
310310

311+
# is there a better/faster ground truth?
312+
function is_stdlib(pkgid::PkgId)
313+
pkgid.name in readdir(Sys.STDLIB) || return false
314+
stdlib_root = joinpath(Sys.STDLIB, pkgid.name)
315+
project_file = locate_project_file(stdlib_root)
316+
if project_file isa String
317+
d = parsed_toml(project_file)
318+
uuid = get(d, "uuid", nothing)
319+
if uuid !== nothing
320+
return UUID(uuid) == pkgid.uuid
321+
end
322+
end
323+
return false
324+
end
325+
311326
"""
312327
Base.identify_package_env(name::String)::Union{Tuple{PkgId, String}, Nothing}
313328
Base.identify_package_env(where::Union{Module,PkgId}, name::String)::Union{Tuple{PkgId, Union{String, Nothing}}, Nothing}
@@ -336,6 +351,12 @@ function identify_package_env(where::PkgId, name::String)
336351
end
337352
break # found in implicit environment--return "not found"
338353
end
354+
if pkg_env === nothing && is_stdlib(where)
355+
# if not found it could be that manifests are from a different julia version/commit
356+
# where stdlib dependencies have changed, so look up deps based on the stdlib Project.toml
357+
# as a fallback
358+
pkg_env = identify_stdlib_project_dep(where, name)
359+
end
339360
end
340361
if cache !== nothing
341362
cache.identified_where[(where, name)] = pkg_env
@@ -362,6 +383,22 @@ function identify_package_env(name::String)
362383
return pkg_env
363384
end
364385

386+
function identify_stdlib_project_dep(stdlib::PkgId, depname::String)
387+
@debug """
388+
Stdlib $(repr("text/plain", stdlib)) is trying to load `$depname`
389+
which is not listed as a dep in the load path manifests, so resorting to search
390+
in the stdlib Project.tomls for true deps"""
391+
stdlib_projfile = locate_project_file(joinpath(Sys.STDLIB, stdlib.name))
392+
stdlib_projfile === nothing && return nothing
393+
found = explicit_project_deps_get(stdlib_projfile, depname)
394+
if found !== nothing
395+
@debug "$(repr("text/plain", stdlib)) indeed depends on $depname in project $stdlib_projfile"
396+
pkgid = PkgId(found, depname)
397+
return pkgid, stdlib_projfile
398+
end
399+
return nothing
400+
end
401+
365402
_nothing_or_first(x) = x === nothing ? nothing : first(x)
366403

367404
"""

test/loading.jl

+12
Original file line numberDiff line numberDiff line change
@@ -1341,6 +1341,18 @@ end
13411341
end
13421342
end
13431343

1344+
@testset "Fallback for stdlib deps if manifest deps aren't found" begin
1345+
mktempdir() do depot
1346+
# This manifest has a LibGit2 entry that is missing LibGit2_jll, which should be
1347+
# handled by falling back to the stdlib Project.toml for dependency truth.
1348+
badmanifest_test_dir = joinpath(@__DIR__, "project", "deps", "BadStdlibDeps.jl")
1349+
@test success(addenv(
1350+
`$(Base.julia_cmd()) --project=$badmanifest_test_dir --startup-file=no -e 'using LibGit2'`,
1351+
"JULIA_DEPOT_PATH" => depot * Base.Filesystem.pathsep(),
1352+
))
1353+
end
1354+
end
1355+
13441356
@testset "code coverage disabled during precompilation" begin
13451357
mktempdir() do depot
13461358
cov_test_dir = joinpath(@__DIR__, "project", "deps", "CovTest.jl")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
# This file is machine-generated - editing it directly is not advised
2+
3+
julia_version = "1.12.0-DEV"
4+
manifest_format = "2.0"
5+
project_hash = "dc9d33b0ee13d9466bdb75b8d375808a534a79ec"
6+
7+
[[deps.Artifacts]]
8+
uuid = "56f22d72-fd6d-98f1-02f0-08ddc0907c33"
9+
version = "1.11.0"
10+
11+
# This is intentionally missing LibGit2_jll for testing purposes
12+
[[deps.LibGit2]]
13+
deps = ["NetworkOptions", "Printf", "SHA"]
14+
uuid = "76f85450-5226-5b5a-8eaa-529ad045b433"
15+
version = "1.11.0"
16+
17+
[[deps.LibGit2_jll]]
18+
deps = ["Artifacts", "LibSSH2_jll", "Libdl", "MbedTLS_jll"]
19+
uuid = "e37daf67-58a4-590a-8e99-b0245dd2ffc5"
20+
version = "1.8.0+0"
21+
22+
[[deps.LibSSH2_jll]]
23+
deps = ["Artifacts", "Libdl", "MbedTLS_jll"]
24+
uuid = "29816b5a-b9ab-546f-933c-edad1886dfa8"
25+
version = "1.11.0+1"
26+
27+
[[deps.Libdl]]
28+
uuid = "8f399da3-3557-5675-b5ff-fb832c97cbdb"
29+
version = "1.11.0"
30+
31+
[[deps.MbedTLS_jll]]
32+
deps = ["Artifacts", "Libdl"]
33+
uuid = "c8ffd9c3-330d-5841-b78e-0817d7145fa1"
34+
version = "2.28.6+1"
35+
36+
[[deps.NetworkOptions]]
37+
uuid = "ca575930-c2e3-43a9-ace4-1e988b2c1908"
38+
version = "1.2.0"
39+
40+
[[deps.Printf]]
41+
deps = ["Unicode"]
42+
uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7"
43+
version = "1.11.0"
44+
45+
[[deps.SHA]]
46+
uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce"
47+
version = "0.7.0"
48+
49+
[[deps.Unicode]]
50+
uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5"
51+
version = "1.11.0"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
[deps]
2+
LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433"

0 commit comments

Comments
 (0)