Skip to content

Commit

Permalink
Make loading work when stdlib deps are missing in the manifest (#56148)
Browse files Browse the repository at this point in the history
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)
  • Loading branch information
IanButterworth authored and KristofferC committed Oct 30, 2024
1 parent 5b369c7 commit 8ed198d
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 0 deletions.
37 changes: 37 additions & 0 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -305,6 +305,21 @@ function find_package(arg)
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, String} Nothing}
Expand Down Expand Up @@ -333,6 +348,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 @@ -359,6 +380,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
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 @@ -1184,6 +1184,18 @@ end
@test success(`$(Base.julia_cmd()) --startup-file=no -e 'using DelimitedFiles'`)
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 "extension path computation name collision" begin
old_load_path = copy(LOAD_PATH)
try
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"

0 comments on commit 8ed198d

Please sign in to comment.