@@ -333,62 +333,56 @@ Same as [`Base.identify_package`](@ref) except that the path to the environment
333333is also returned, except when the identity is not identified. 
334334""" 
335335identify_package_env (where :: Module , name:: String ) =  identify_package_env (PkgId (where ), name)
336- function  identify_package_env (where :: PkgId , name:: String )
337-     assert_havelock (require_lock)
338-     cache =  LOADING_CACHE[]
339-     if  cache != =  nothing 
340-         pkg_env =  get (cache. identified_where, (where , name), missing )
341-         pkg_env ===  missing  ||  return  pkg_env
342-     end 
343-     pkg_env =  nothing 
344-     if  where . name ===  name
345-         return  (where , nothing )
346-     elseif  where . uuid ===  nothing 
347-         pkg_env =  identify_package_env (name) #  ignore `where`
348-     else 
349-         for  env in  load_path ()
350-             pkgid =  manifest_deps_get (env, where , name)
351-             #  If we didn't find `where` at all, keep looking through the environment stack
352-             pkgid ===  nothing  &&  continue 
353-             if  pkgid. uuid != =  nothing 
354-                 pkg_env =  pkgid, env
355-             end 
356-             #  If we don't have pkgid.uuid, still break here - this is a sentinel that indicates
357-             #  that we've found `where` but it did not have the required dependency. We terminate the search.
358-             break 
336+ function  identify_package_env (where :: Union{PkgId, Nothing} , name:: String )
337+     #  Special cases
338+     if  where  != =  nothing 
339+         if  where . name ===  name
340+             #  Project tries to load itself
341+             return  (where , nothing )
342+         elseif  where . uuid ===  nothing 
343+             #  Project without Project.toml - treat as toplevel load
344+             where  =  nothing 
359345        end 
360-         if  pkg_env ===  nothing  &&  is_stdlib (where )
361-             #  if not found it could be that manifests are from a different julia version/commit
362-             #  where stdlib dependencies have changed, so look up deps based on the stdlib Project.toml
363-             #  as a fallback
364-             pkg_env =  identify_stdlib_project_dep (where , name)
365-         end 
366-     end 
367-     if  cache != =  nothing 
368-         cache. identified_where[(where , name)] =  pkg_env
369346    end 
370-     return  pkg_env
371- end 
372- function  identify_package_env (name:: String )
347+ 
348+     #  Check if we have a cached answer for this
373349    assert_havelock (require_lock)
374350    cache =  LOADING_CACHE[]
351+     cache_key =  where  ===  nothing  ?  name :  (where , name)
375352    if  cache != =  nothing 
376-         pkg_env =  get (cache. identified, name, missing )
353+         env_cache =  where  ===  nothing  ?  cache. identified :  cache. identified_where
354+         pkg_env =  get (env_cache, cache_key, missing )
377355        pkg_env ===  missing  ||  return  pkg_env
378356    end 
357+ 
358+     #  Main part: Search through all environments in the load path to see if we have
359+     #  a matching entry.
379360    pkg_env =  nothing 
380361    for  env in  load_path ()
381-         pkg =  project_deps_get (env, name)
382-         if  pkg != =  nothing 
383-             pkg_env =  pkg, env #  found--return it
384-             break 
362+         pkgid =  environment_deps_get (env, where , name)
363+         #  If we didn't find `where` at all, keep looking through the environment stack
364+         pkgid ===  nothing  &&  continue 
365+         if  pkgid. uuid != =  nothing  ||  where  ===  nothing 
366+             pkg_env =  pkgid, env
385367        end 
368+         #  If we don't have pkgid.uuid, still break here - this is a sentinel that indicates
369+         #  that we've found `where` but it did not have the required dependency. We terminate the search.
370+         break 
386371    end 
372+     if  pkg_env ===  nothing  &&  where  != =  nothing  &&  is_stdlib (where )
373+         #  if not found it could be that manifests are from a different julia version/commit
374+         #  where stdlib dependencies have changed, so look up deps based on the stdlib Project.toml
375+         #  as a fallback
376+         pkg_env =  identify_stdlib_project_dep (where , name)
377+     end 
378+ 
379+     #  Cache the result
387380    if  cache != =  nothing 
388-         cache . identified[name ] =  pkg_env
381+         env_cache[cache_key ] =  pkg_env
389382    end 
390383    return  pkg_env
391384end 
385+ identify_package_env (name:: String ) =  identify_package_env (nothing , name)
392386
393387function  identify_stdlib_project_dep (stdlib:: PkgId , depname:: String )
394388    @debug  """ 
@@ -447,19 +441,18 @@ function locate_package_env(pkg::PkgId, stopenv::Union{String, Nothing}=nothing)
447441    path =  nothing 
448442    env′ =  nothing 
449443    if  pkg. uuid ===  nothing 
444+         #  The project we're looking for does not have a Project.toml (n.b. - present
445+         #  `Project.toml` without UUID gets a path-based dummy UUID). It must have
446+         #  come from an implicit manifest environment, so go through those only.
450447        for  env in  load_path ()
451-             #  look for the toplevel pkg `pkg.name` in this entry
452-             found =  project_deps_get (env, pkg. name)
453-             if  found != =  nothing 
448+             project_file =  env_project_file (env)
449+             (project_file isa  Bool &&  project_file) ||  continue 
450+             found =  implicit_manifest_pkgid (env, pkg. name)
451+             if  found != =  nothing  &&  found. uuid ===  nothing 
454452                @assert  found. name ==  pkg. name
455-                 if  found. uuid ===  nothing 
456-                     #  pkg.name is present in this directory or project file,
457-                     #  return the path the entry point for the code, if it could be found
458-                     #  otherwise, signal failure
459-                     path =  implicit_manifest_uuid_path (env, pkg)
460-                     env′ =  env
461-                     @goto  done
462-                 end 
453+                 path =  implicit_manifest_uuid_path (env, pkg)
454+                 env′ =  env
455+                 @goto  done
463456            end 
464457            if  ! (loading_extension ||  precompiling_extension)
465458                stopenv ==  env &&  @goto  done
@@ -690,27 +683,18 @@ function base_project(project_file)
690683    return  nothing 
691684end 
692685
693- function  project_deps_get (env:: String , name:: String ):: Union{Nothing,PkgId} 
694-     project_file =  env_project_file (env)
695-     if  project_file isa  String
696-         pkg_uuid =  explicit_project_deps_get (project_file, name)
697-         pkg_uuid ===  nothing  ||  return  PkgId (pkg_uuid, name)
698-     elseif  project_file
699-         return  implicit_project_deps_get (env, name)
700-     end 
701-     return  nothing 
702- end 
703- 
704686function  package_get_here (project_file, name:: String )
705687    #  if `where` matches the project, use [deps] section as manifest, and stop searching
706688    pkg_uuid =  explicit_project_deps_get (project_file, name)
707689    pkg_uuid ===  nothing  &&  return  PkgId (name)
708690    return  PkgId (pkg_uuid, name)
709691end 
710692
711- function  package_get (project_file, where :: PkgId , name:: String )
712-     proj =  project_file_name_uuid (project_file, where . name)
713-     proj !=  where  &&  return  nothing 
693+ function  package_get (project_file, where :: Union{Nothing, PkgId} , name:: String )
694+     if  where  != =  nothing 
695+         proj =  project_file_name_uuid (project_file, where . name)
696+         proj !=  where  &&  return  nothing 
697+     end 
714698    return  package_get_here (project_file, name)
715699end 
716700
@@ -741,23 +725,51 @@ function package_extension_get(project_file, where::PkgId, name::String)
741725    return  nothing 
742726end 
743727
744- function  manifest_deps_get (env:: String , where :: PkgId , name:: String ):: Union{Nothing,PkgId} 
745-     @assert  where . uuid != =  nothing 
728+ function  environment_deps_get (env:: String , where :: Union{Nothing, PkgId} :: String ):: Union{Nothing,PkgId} 
729+     @assert  where   ===   nothing   ||   where . uuid != =  nothing 
746730    project_file =  env_project_file (env)
747731    implicit_manifest =  ! (project_file isa  String)
748732    if  implicit_manifest
749733        project_file ||  return  nothing 
734+         if  where  ===  nothing 
735+             #  Toplevel load with a directory (implicit manifest) - all we look for is the
736+             #  existence of the package name in the directory.
737+             pkg =  implicit_manifest_pkgid (env, name)
738+             return  pkg
739+         end 
750740        project_file =  implicit_manifest_project (env, where )
751741        project_file ===  nothing  &&  return  nothing 
752742    end 
753743
754-     #  1. Are we loading into the top-level project itself? dependencies come from [deps]
755-     #     N.B.: Here "top-level" includes package loaded from an implicit manifest, which
756-     #           uses the same code path.
744+     #  Are we
745+     #     a) loading into a top-level project itself
746+     #     b) loading into a non-top-level project that was part of an implicit
747+     #        manifest environment (and for which we found the project file above)
748+     #     c) performing a top-level load (where === nothing) - i.e. we're looking
749+     #        at an environment's project file.
750+     # 
751+     #  If so, we may load either:
752+     #    I: the project itself (if name matches where)
753+     #    II: a dependency from [deps] section of the project file
754+     # 
755+     #  N.B.: Here "top-level" includes package loaded from an implicit manifest, which
756+     #        uses the same code path. Otherwise this is the active project.
757757    pkg =  package_get (project_file, where , name)
758-     pkg ===  nothing  ||  return  pkg
758+     if  pkg != =  nothing 
759+         if  where  ===  nothing  &&  pkg. uuid ===  nothing 
760+             #  This is a top-level load - even though we didn't find the dependency
761+             #  here, we still want to keep looking through the top-level environment stack.
762+             return  nothing 
763+         end 
764+         return  pkg
765+     end 
759766
760-     #  2. Are we an extension of the top-level project? dependencies come from [weakdeps] and [deps]
767+     @assert  where  != =  nothing 
768+ 
769+     #  Are we an extension of a project from cases a), b) above
770+     #  If so, in addition to I, II above, we get:
771+     #    III: A dependency from [weakdeps] section of the project file as long
772+     #         as it is an extension trigger for `where` in the `extensions` section.
761773    pkg =  package_extension_get (project_file, where , name)
762774    pkg ===  nothing  ||  return  pkg
763775
@@ -1134,10 +1146,7 @@ function explicit_manifest_entry_path(manifest_file::String, pkg::PkgId, entry::
11341146end 
11351147
11361148# # implicit project & manifest API ##
1137- 
1138- #  look for an entry point for `name` from a top-level package (no environment)
1139- #  otherwise return `nothing` to indicate the caller should keep searching
1140- function  implicit_project_deps_get (dir:: String , name:: String ):: Union{Nothing,PkgId} 
1149+ function  implicit_manifest_pkgid (dir:: String , name:: String ):: Union{Nothing,PkgId} 
11411150    path, project_file =  entry_point_and_project_file (dir, name)
11421151    if  project_file ===  nothing 
11431152        path ===  nothing  &&  return  nothing 
@@ -1148,7 +1157,7 @@ function implicit_project_deps_get(dir::String, name::String)::Union{Nothing,Pkg
11481157    return  proj
11491158end 
11501159
1151- function  implicit_manifest_project (dir, pkg:: PkgId ):: Union{Nothing, String} 
1160+ function  implicit_manifest_project (dir:: String , pkg:: PkgId ):: Union{Nothing, String} 
11521161    @assert  pkg. uuid != =  nothing 
11531162    project_file =  entry_point_and_project_file (dir, pkg. name)[2 ]
11541163    if  project_file ===  nothing 
0 commit comments