Skip to content

Commit 8ed198d

Browse files
IanButterworthKristofferC
authored and
KristofferC
committed
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. ``` 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> ``` ``` 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 ... ``` (cherry picked from commit b02d671)
1 parent 5b369c7 commit 8ed198d

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
@@ -305,6 +305,21 @@ function find_package(arg)
305305
return locate_package(pkg, env)
306306
end
307307

308+
# is there a better/faster ground truth?
309+
function is_stdlib(pkgid::PkgId)
310+
pkgid.name in readdir(Sys.STDLIB) || return false
311+
stdlib_root = joinpath(Sys.STDLIB, pkgid.name)
312+
project_file = locate_project_file(stdlib_root)
313+
if project_file isa String
314+
d = parsed_toml(project_file)
315+
uuid = get(d, "uuid", nothing)
316+
if uuid !== nothing
317+
return UUID(uuid) == pkgid.uuid
318+
end
319+
end
320+
return false
321+
end
322+
308323
"""
309324
Base.identify_package_env(name::String)::Union{Tuple{PkgId, String}, Nothing}
310325
Base.identify_package_env(where::Union{Module,PkgId}, name::String)::Union{Tuple{PkgId, String} Nothing}
@@ -333,6 +348,12 @@ function identify_package_env(where::PkgId, name::String)
333348
end
334349
break # found in implicit environment--return "not found"
335350
end
351+
if pkg_env === nothing && is_stdlib(where)
352+
# if not found it could be that manifests are from a different julia version/commit
353+
# where stdlib dependencies have changed, so look up deps based on the stdlib Project.toml
354+
# as a fallback
355+
pkg_env = identify_stdlib_project_dep(where, name)
356+
end
336357
end
337358
if cache !== nothing
338359
cache.identified_where[(where, name)] = pkg_env
@@ -359,6 +380,22 @@ function identify_package_env(name::String)
359380
return pkg_env
360381
end
361382

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

364401
"""

test/loading.jl

+12
Original file line numberDiff line numberDiff line change
@@ -1184,6 +1184,18 @@ end
11841184
@test success(`$(Base.julia_cmd()) --startup-file=no -e 'using DelimitedFiles'`)
11851185
end
11861186

1187+
@testset "Fallback for stdlib deps if manifest deps aren't found" begin
1188+
mktempdir() do depot
1189+
# This manifest has a LibGit2 entry that is missing LibGit2_jll, which should be
1190+
# handled by falling back to the stdlib Project.toml for dependency truth.
1191+
badmanifest_test_dir = joinpath(@__DIR__, "project", "deps", "BadStdlibDeps.jl")
1192+
@test success(addenv(
1193+
`$(Base.julia_cmd()) --project=$badmanifest_test_dir --startup-file=no -e 'using LibGit2'`,
1194+
"JULIA_DEPOT_PATH" => depot * Base.Filesystem.pathsep(),
1195+
))
1196+
end
1197+
end
1198+
11871199
@testset "extension path computation name collision" begin
11881200
old_load_path = copy(LOAD_PATH)
11891201
try
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)