@@ -413,7 +413,9 @@ function locate_package_env(pkg::PkgId, stopenv::Union{String, Nothing}=nothing)
413413 @goto done
414414 end
415415 end
416- stopenv == env && @goto done
416+ if ! (loading_extension || precompiling_extension)
417+ stopenv == env && @goto done
418+ end
417419 end
418420 else
419421 for env in load_path ()
@@ -428,7 +430,9 @@ function locate_package_env(pkg::PkgId, stopenv::Union{String, Nothing}=nothing)
428430 path = entry_path (path, pkg. name)
429431 @goto done
430432 end
431- stopenv == env && break
433+ if ! (loading_extension || precompiling_extension)
434+ stopenv == env && break
435+ end
432436 end
433437 # Allow loading of stdlibs if the name/uuid are given
434438 # e.g. if they have been explicitly added to the project/manifest
@@ -619,6 +623,24 @@ function manifest_deps_get(env::String, where::PkgId, name::String)::Union{Nothi
619623 pkg_uuid = explicit_project_deps_get (project_file, name)
620624 return PkgId (pkg_uuid, name)
621625 end
626+ d = parsed_toml (project_file)
627+ exts = get (d, " extensions" , nothing ):: Union{Dict{String, Any}, Nothing}
628+ if exts != = nothing
629+ # Check if `where` is an extension of the project
630+ if where . name in keys (exts) && where . uuid == uuid5 (proj. uuid, where . name)
631+ # Extensions can load weak deps...
632+ weakdeps = get (d, " weakdeps" , nothing ):: Union{Dict{String, Any}, Nothing}
633+ if weakdeps != = nothing
634+ wuuid = get (weakdeps, name, nothing ):: Union{String, Nothing}
635+ if wuuid != = nothing
636+ return PkgId (UUID (wuuid), name)
637+ end
638+ end
639+ # ... and they can load same deps as the project itself
640+ mby_uuid = explicit_project_deps_get (project_file, name)
641+ mby_uuid === nothing || return PkgId (mby_uuid, name)
642+ end
643+ end
622644 # look for manifest file and `where` stanza
623645 return explicit_manifest_deps_get (project_file, where , name)
624646 elseif project_file
@@ -636,6 +658,8 @@ function manifest_uuid_path(env::String, pkg::PkgId)::Union{Nothing,String,Missi
636658 # if `pkg` matches the project, return the project itself
637659 return project_file_path (project_file)
638660 end
661+ mby_ext = project_file_ext_path (project_file, pkg. name)
662+ mby_ext === nothing || return mby_ext
639663 # look for manifest file and `where` stanza
640664 return explicit_manifest_uuid_path (project_file, pkg)
641665 elseif project_file
@@ -645,6 +669,25 @@ function manifest_uuid_path(env::String, pkg::PkgId)::Union{Nothing,String,Missi
645669 return nothing
646670end
647671
672+
673+ function find_ext_path (project_path:: String , extname:: String )
674+ extfiledir = joinpath (project_path, " ext" , extname, extname * " .jl" )
675+ isfile (extfiledir) && return extfiledir
676+ return joinpath (project_path, " ext" , extname * " .jl" )
677+ end
678+
679+ function project_file_ext_path (project_file:: String , name:: String )
680+ d = parsed_toml (project_file)
681+ p = project_file_path (project_file)
682+ exts = get (d, " extensions" , nothing ):: Union{Dict{String, Any}, Nothing}
683+ if exts != = nothing
684+ if name in keys (exts)
685+ return find_ext_path (p, name)
686+ end
687+ end
688+ return nothing
689+ end
690+
648691# find project file's top-level UUID entry (or nothing)
649692function project_file_name_uuid (project_file:: String , name:: String ):: PkgId
650693 d = parsed_toml (project_file)
@@ -876,9 +919,7 @@ function explicit_manifest_uuid_path(project_file::String, pkg::PkgId)::Union{No
876919 error (" failed to find source of parent package: \" $name \" " )
877920 end
878921 p = normpath (dirname (parent_path), " .." )
879- extfiledir = joinpath (p, " ext" , pkg. name, pkg. name * " .jl" )
880- isfile (extfiledir) && return extfiledir
881- return joinpath (p, " ext" , pkg. name * " .jl" )
922+ return find_ext_path (p, pkg. name)
882923 end
883924 end
884925 end
@@ -1160,6 +1201,18 @@ end
11601201function insert_extension_triggers (env:: String , pkg:: PkgId ):: Union{Nothing,Missing}
11611202 project_file = env_project_file (env)
11621203 if project_file isa String
1204+ # Look in project for extensions to insert
1205+ proj_pkg = project_file_name_uuid (project_file, pkg. name)
1206+ if pkg == proj_pkg
1207+ d_proj = parsed_toml (project_file)
1208+ weakdeps = get (d_proj, " weakdeps" , nothing ):: Union{Nothing, Vector{String}, Dict{String,Any}}
1209+ extensions = get (d_proj, " extensions" , nothing ):: Union{Nothing, Dict{String, Any}}
1210+ extensions === nothing && return
1211+ weakdeps === nothing && return
1212+ return _insert_extension_triggers (pkg, extensions, weakdeps)
1213+ end
1214+
1215+ # Now look in manifest
11631216 manifest_file = project_file_manifest_path (project_file)
11641217 manifest_file === nothing && return
11651218 d = get_deps (parsed_toml (manifest_file))
@@ -1224,6 +1277,7 @@ function _insert_extension_triggers(parent::PkgId, extensions::Dict{String, <:An
12241277end
12251278
12261279loading_extension:: Bool = false
1280+ precompiling_extension:: Bool = false
12271281function run_extension_callbacks (extid:: ExtensionId )
12281282 assert_havelock (require_lock)
12291283 succeeded = try
@@ -1251,30 +1305,8 @@ function run_extension_callbacks(pkgid::PkgId)
12511305 extids === nothing && return
12521306 for extid in extids
12531307 if extid. ntriggers > 0
1254- # It is possible that pkgid was loaded in an environment
1255- # below the one of the parent. This will cause a load failure when the
1256- # pkg ext tries to load the triggers. Therefore, check this first
1257- # before loading the pkg ext.
1258- pkgenv = identify_package_env (extid. id, pkgid. name)
1259- ext_not_allowed_load = false
1260- if pkgenv === nothing
1261- ext_not_allowed_load = true
1262- else
1263- pkg, env = pkgenv
1264- path = locate_package (pkg, env)
1265- if path === nothing
1266- ext_not_allowed_load = true
1267- end
1268- end
1269- if ext_not_allowed_load
1270- @debug " Extension $(extid. id. name) of $(extid. parentid. name) will not be loaded \
1271- since $(pkgid. name) loaded in environment lower in load path"
1272- # indicate extid is expected to fail
1273- extid. ntriggers *= - 1
1274- else
1275- # indicate pkgid is loaded
1276- extid. ntriggers -= 1
1277- end
1308+ # indicate pkgid is loaded
1309+ extid. ntriggers -= 1
12781310 end
12791311 if extid. ntriggers < 0
12801312 # indicate pkgid is loaded
@@ -2148,6 +2180,7 @@ function create_expr_cache(pkg::PkgId, input::String, output::String, output_o::
21482180 # write data over stdin to avoid the (unlikely) case of exceeding max command line size
21492181 write (io. in, """
21502182 empty!(Base.EXT_DORMITORY) # If we have a custom sysimage with `EXT_DORMITORY` prepopulated
2183+ Base.precompiling_extension = $(loading_extension)
21512184 Base.include_package_for_output($(pkg_str (pkg)) , $(repr (abspath (input))) , $(repr (depot_path)) , $(repr (dl_load_path)) ,
21522185 $(repr (load_path)) , $deps , $(repr (source_path (nothing ))) )
21532186 """ )
0 commit comments