Skip to content

Commit 276e66c

Browse files
IanButterworthKristofferC
authored andcommitted
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 ... ``` (cherry picked from commit b02d671)
1 parent 709e31c commit 276e66c

File tree

4 files changed

+102
-0
lines changed

4 files changed

+102
-0
lines changed

base/loading.jl

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -309,6 +309,21 @@ function find_package(arg) # ::Union{Nothing,String}
309309
return locate_package(pkg, env)
310310
end
311311

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

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

368405
"""

test/loading.jl

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1325,6 +1325,18 @@ end
13251325
end
13261326
end
13271327

1328+
@testset "Fallback for stdlib deps if manifest deps aren't found" begin
1329+
mktempdir() do depot
1330+
# This manifest has a LibGit2 entry that is missing LibGit2_jll, which should be
1331+
# handled by falling back to the stdlib Project.toml for dependency truth.
1332+
badmanifest_test_dir = joinpath(@__DIR__, "project", "deps", "BadStdlibDeps.jl")
1333+
@test success(addenv(
1334+
`$(Base.julia_cmd()) --project=$badmanifest_test_dir --startup-file=no -e 'using LibGit2'`,
1335+
"JULIA_DEPOT_PATH" => depot * Base.Filesystem.pathsep(),
1336+
))
1337+
end
1338+
end
1339+
13281340
@testset "code coverage disabled during precompilation" begin
13291341
mktempdir() do depot
13301342
cov_test_dir = joinpath(@__DIR__, "project", "deps", "CovTest.jl")
Lines changed: 51 additions & 0 deletions
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"
Lines changed: 2 additions & 0 deletions
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)