diff --git a/base/loading.jl b/base/loading.jl index 447b7839980b5..374f4ccbed4fb 100644 --- a/base/loading.jl +++ b/base/loading.jl @@ -258,7 +258,7 @@ struct LoadingCache require_parsed::Set{String} identified_where::Dict{Tuple{PkgId, String}, Union{Nothing, Tuple{PkgId, Union{Nothing, String}}}} identified::Dict{String, Union{Nothing, Tuple{PkgId, Union{Nothing, String}}}} - located::Dict{Tuple{PkgId, Union{String, Nothing}}, Union{String, Nothing}} + located::Dict{Tuple{PkgId, Union{String, Nothing}}, Union{Tuple{Union{String, Nothing}, Union{String, Nothing}}, Nothing}} end const LOADING_CACHE = Ref{Union{LoadingCache, Nothing}}(nothing) LoadingCache() = LoadingCache(load_path(), Dict(), Dict(), Dict(), Set(), Dict(), Dict(), Dict()) @@ -390,30 +390,17 @@ identify_package(where::Module, name::String) = _nothing_or_first(identify_packa identify_package(where::PkgId, name::String) = _nothing_or_first(identify_package_env(where, name)) identify_package(name::String) = _nothing_or_first(identify_package_env(name)) - -""" - Base.locate_package(pkg::PkgId)::Union{String, Nothing} - -The path to the entry-point file for the package corresponding to the identifier -`pkg`, or `nothing` if not found. See also [`identify_package`](@ref). - -```julia-repl -julia> pkg = Base.identify_package("Pkg") -Pkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f] - -julia> Base.locate_package(pkg) -"/path/to/julia/stdlib/v$(VERSION.major).$(VERSION.minor)/Pkg/src/Pkg.jl" -``` -""" -function locate_package(pkg::PkgId, stopenv::Union{String, Nothing}=nothing)::Union{Nothing,String} +function locate_package_env(pkg::PkgId, stopenv::Union{String, Nothing}=nothing) cache = LOADING_CACHE[] if cache !== nothing - path = get(cache.located, (pkg, stopenv), nothing) - path === nothing || return path + pathenv = get(cache.located, (pkg, stopenv), nothing) + pathenv === nothing || return pathenv end path = nothing + env′ = nothing if pkg.uuid === nothing for env in load_path() + env′ = env # look for the toplevel pkg `pkg.name` in this entry found = project_deps_get(env, pkg.name) if found !== nothing @@ -430,6 +417,7 @@ function locate_package(pkg::PkgId, stopenv::Union{String, Nothing}=nothing)::Un end else for env in load_path() + env′ = env path = manifest_uuid_path(env, pkg) # missing is used as a sentinel to stop looking further down in envs if path === missing @@ -452,9 +440,27 @@ function locate_package(pkg::PkgId, stopenv::Union{String, Nothing}=nothing)::Un end @label done if cache !== nothing - cache.located[(pkg, stopenv)] = path + cache.located[(pkg, stopenv)] = path, env′ end - return path + return path, env′ +end + +""" + Base.locate_package(pkg::PkgId)::Union{String, Nothing} + +The path to the entry-point file for the package corresponding to the identifier +`pkg`, or `nothing` if not found. See also [`identify_package`](@ref). + +```julia-repl +julia> pkg = Base.identify_package("Pkg") +Pkg [44cfe95a-1eb2-52ea-b672-e2afdf69b78f] + +julia> Base.locate_package(pkg) +"/path/to/julia/stdlib/v$(VERSION.major).$(VERSION.minor)/Pkg/src/Pkg.jl" +``` +""" +function locate_package(pkg::PkgId, stopenv::Union{String, Nothing}=nothing)::Union{Nothing,String} + _nothing_or_first(locate_package_env(pkg, stopenv)) end """ @@ -1108,9 +1114,13 @@ const EXT_DORMITORY_FAILED = ExtensionId[] function insert_extension_triggers(pkg::PkgId) pkg.uuid === nothing && return - for env in load_path() - insert_extension_triggers(env, pkg) + path_env_loc = locate_package_env(pkg) + path_env_loc === nothing && return + path, env_loc = path_env_loc + if path === nothing || env_loc === nothing + return end + insert_extension_triggers(env_loc, pkg) end function insert_extension_triggers(env::String, pkg::PkgId)::Union{Nothing,Missing} diff --git a/test/loading.jl b/test/loading.jl index 8b3b90a9b6053..fd32eb51afee3 100644 --- a/test/loading.jl +++ b/test/loading.jl @@ -1011,10 +1011,10 @@ end begin push!(empty!(DEPOT_PATH), '$(repr(depot_path))') using HasExtensions - # Base.get_extension(HasExtensions, :Extension) === nothing || error("unexpectedly got an extension") + Base.get_extension(HasExtensions, :Extension) === nothing || error("unexpectedly got an extension") HasExtensions.ext_loaded && error("ext_loaded set") using HasDepWithExtensions - # Base.get_extension(HasExtensions, :Extension).extvar == 1 || error("extvar in Extension not set") + Base.get_extension(HasExtensions, :Extension).extvar == 1 || error("extvar in Extension not set") HasExtensions.ext_loaded || error("ext_loaded not set") HasExtensions.ext_folder_loaded && error("ext_folder_loaded set") HasDepWithExtensions.do_something() || error("do_something errored") @@ -1032,12 +1032,29 @@ end @test success(cmd) end - # 48351 sep = Sys.iswindows() ? ';' : ':' + + # 48351 cmd = gen_extension_cmd(``) cmd = addenv(cmd, "JULIA_LOAD_PATH" => join([mktempdir(), proj], sep)) cmd = pipeline(cmd; stdout, stderr) @test success(cmd) + + # Only load env from where package is loaded + envs = [joinpath(@__DIR__, "project", "Extensions", "EnvWithHasExtensionsv2"), joinpath(@__DIR__, "project", "Extensions", "EnvWithHasExtensions")] + cmd = addenv(```$(Base.julia_cmd()) --startup-file=no -e ' + begin + + + push!(empty!(DEPOT_PATH), '$(repr(depot_path))') + using HasExtensions + using ExtDep + Base.get_extension(HasExtensions, :Extension) === nothing || error("unexpectedly loaded ext from other env") + Base.get_extension(HasExtensions, :Extension2) === nothing && error("did not load ext from active env") + end + ' + ```, "JULIA_LOAD_PATH" => join(envs, sep)) + @test success(cmd) finally try rm(depot_path, force=true, recursive=true) diff --git a/test/project/Extensions/EnvWithHasExtensions/Manifest.toml b/test/project/Extensions/EnvWithHasExtensions/Manifest.toml new file mode 100644 index 0000000000000..8ac961fa1a9a9 --- /dev/null +++ b/test/project/Extensions/EnvWithHasExtensions/Manifest.toml @@ -0,0 +1,29 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.9.0-beta4" +manifest_format = "2.0" +project_hash = "caa716752e6dff3d77c3de929ebbb5d2024d04ef" + +[[deps.ExtDep]] +deps = ["SomePackage"] +path = "../ExtDep.jl" +uuid = "fa069be4-f60b-4d4c-8b95-f8008775090c" +version = "0.1.0" + +[[deps.HasExtensions]] +path = "../HasExtensions.jl" +uuid = "4d3288b3-3afc-4bb6-85f3-489fffe514c8" +version = "0.1.0" + + [deps.HasExtensions.extensions] + Extension = "ExtDep" + ExtensionFolder = ["ExtDep", "ExtDep2"] + + [deps.HasExtensions.weakdeps] + ExtDep = "fa069be4-f60b-4d4c-8b95-f8008775090c" + ExtDep2 = "55982ee5-2ad5-4c40-8cfe-5e9e1b01500d" + +[[deps.SomePackage]] +path = "../SomePackage" +uuid = "678608ae-7bb3-42c7-98b1-82102067a3d8" +version = "0.1.0" diff --git a/test/project/Extensions/EnvWithHasExtensions/Project.toml b/test/project/Extensions/EnvWithHasExtensions/Project.toml new file mode 100644 index 0000000000000..8639881ae95c0 --- /dev/null +++ b/test/project/Extensions/EnvWithHasExtensions/Project.toml @@ -0,0 +1,4 @@ +[deps] +ExtDep = "fa069be4-f60b-4d4c-8b95-f8008775090c" +HasExtensions = "4d3288b3-3afc-4bb6-85f3-489fffe514c8" +SomePackage = "678608ae-7bb3-42c7-98b1-82102067a3d8" diff --git a/test/project/Extensions/EnvWithHasExtensionsv2/Manifest.toml b/test/project/Extensions/EnvWithHasExtensionsv2/Manifest.toml new file mode 100644 index 0000000000000..66781a5701363 --- /dev/null +++ b/test/project/Extensions/EnvWithHasExtensionsv2/Manifest.toml @@ -0,0 +1,25 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.10.0-DEV" +manifest_format = "2.0" +project_hash = "caa716752e6dff3d77c3de929ebbb5d2024d04ef" + +[[deps.ExtDep]] +deps = ["SomePackage"] +path = "../ExtDep.jl" +uuid = "fa069be4-f60b-4d4c-8b95-f8008775090c" +version = "0.1.0" + +[[deps.HasExtensions]] +path = "../HasExtensions_v2.jl" +uuid = "4d3288b3-3afc-4bb6-85f3-489fffe514c8" +version = "0.2.0" +weakdeps = ["ExtDep"] + + [deps.HasExtensions.extensions] + Extension2 = "ExtDep" + +[[deps.SomePackage]] +path = "../SomePackage" +uuid = "678608ae-7bb3-42c7-98b1-82102067a3d8" +version = "0.1.0" diff --git a/test/project/Extensions/EnvWithHasExtensionsv2/Project.toml b/test/project/Extensions/EnvWithHasExtensionsv2/Project.toml new file mode 100644 index 0000000000000..8639881ae95c0 --- /dev/null +++ b/test/project/Extensions/EnvWithHasExtensionsv2/Project.toml @@ -0,0 +1,4 @@ +[deps] +ExtDep = "fa069be4-f60b-4d4c-8b95-f8008775090c" +HasExtensions = "4d3288b3-3afc-4bb6-85f3-489fffe514c8" +SomePackage = "678608ae-7bb3-42c7-98b1-82102067a3d8" diff --git a/test/project/Extensions/HasExtensions_v2.jl/Project.toml b/test/project/Extensions/HasExtensions_v2.jl/Project.toml new file mode 100644 index 0000000000000..5d92a4b138058 --- /dev/null +++ b/test/project/Extensions/HasExtensions_v2.jl/Project.toml @@ -0,0 +1,9 @@ +name = "HasExtensions" +uuid = "4d3288b3-3afc-4bb6-85f3-489fffe514c8" +version = "0.2.0" + +[weakdeps] +ExtDep = "fa069be4-f60b-4d4c-8b95-f8008775090c" + +[extensions] +Extension2 = "ExtDep" diff --git a/test/project/Extensions/HasExtensions_v2.jl/ext/Extension2.jl b/test/project/Extensions/HasExtensions_v2.jl/ext/Extension2.jl new file mode 100644 index 0000000000000..d027adec9c223 --- /dev/null +++ b/test/project/Extensions/HasExtensions_v2.jl/ext/Extension2.jl @@ -0,0 +1,3 @@ +module Extension2 + +end diff --git a/test/project/Extensions/HasExtensions_v2.jl/src/HasExtensions.jl b/test/project/Extensions/HasExtensions_v2.jl/src/HasExtensions.jl new file mode 100644 index 0000000000000..dbfaeec4f8812 --- /dev/null +++ b/test/project/Extensions/HasExtensions_v2.jl/src/HasExtensions.jl @@ -0,0 +1,10 @@ +module HasExtensions + +struct HasExtensionsStruct end + +foo(::HasExtensionsStruct) = 1 + +ext_loaded = false +ext_folder_loaded = false + +end # module