Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

only load extension triggers from the evnironment where the parent package is loaded #48703

Merged
merged 1 commit into from
Feb 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
56 changes: 33 additions & 23 deletions base/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand All @@ -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

"""
Expand Down Expand Up @@ -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}
Expand Down
23 changes: 20 additions & 3 deletions test/loading.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand All @@ -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)
Expand Down
29 changes: 29 additions & 0 deletions test/project/Extensions/EnvWithHasExtensions/Manifest.toml
Original file line number Diff line number Diff line change
@@ -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"
4 changes: 4 additions & 0 deletions test/project/Extensions/EnvWithHasExtensions/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[deps]
ExtDep = "fa069be4-f60b-4d4c-8b95-f8008775090c"
HasExtensions = "4d3288b3-3afc-4bb6-85f3-489fffe514c8"
SomePackage = "678608ae-7bb3-42c7-98b1-82102067a3d8"
25 changes: 25 additions & 0 deletions test/project/Extensions/EnvWithHasExtensionsv2/Manifest.toml
Original file line number Diff line number Diff line change
@@ -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"
4 changes: 4 additions & 0 deletions test/project/Extensions/EnvWithHasExtensionsv2/Project.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
[deps]
ExtDep = "fa069be4-f60b-4d4c-8b95-f8008775090c"
HasExtensions = "4d3288b3-3afc-4bb6-85f3-489fffe514c8"
SomePackage = "678608ae-7bb3-42c7-98b1-82102067a3d8"
9 changes: 9 additions & 0 deletions test/project/Extensions/HasExtensions_v2.jl/Project.toml
Original file line number Diff line number Diff line change
@@ -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"
3 changes: 3 additions & 0 deletions test/project/Extensions/HasExtensions_v2.jl/ext/Extension2.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module Extension2

end
10 changes: 10 additions & 0 deletions test/project/Extensions/HasExtensions_v2.jl/src/HasExtensions.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
module HasExtensions

struct HasExtensionsStruct end

foo(::HasExtensionsStruct) = 1

ext_loaded = false
ext_folder_loaded = false

end # module