@@ -129,12 +129,21 @@ end
129129const  ns_dummy_uuid =  UUID (" fe0723d6-3a44-4c41-8065-ee0f42c8ceab"  )
130130
131131function  dummy_uuid (project_file:: String )
132+     cache =  LOADING_CACHE[]
133+     if  cache != =  nothing 
134+         uuid =  get (cache. dummy_uuid, project_file, nothing )
135+         uuid ===  nothing  ||  return  uuid
136+     end 
132137    project_path =  try 
133138        realpath (project_file)
134139    catch 
135140        project_file
136141    end 
137-     return  uuid5 (ns_dummy_uuid, project_path)
142+     uuid =  uuid5 (ns_dummy_uuid, project_path)
143+     if  cache != =  nothing 
144+         cache. dummy_uuid[project_file] =  uuid
145+     end 
146+     return  uuid
138147end 
139148
140149# # package path slugs: turning UUID + SHA1 into a pair of 4-byte "slugs" ##
@@ -210,6 +219,16 @@ function get_updated_dict(p::TOML.Parser, f::CachedTOMLDict)
210219    return  f. d
211220end 
212221
222+ struct  LoadingCache
223+     load_path:: Vector{String} 
224+     dummy_uuid:: Dict{String, UUID} 
225+     env_project_file:: Dict{String, Union{Bool, String}} 
226+     project_file_manifest_path:: Dict{String, Union{Nothing, String}} 
227+ end 
228+ const  LOADING_CACHE =  Ref {Union{LoadingCache, Nothing}} (nothing )
229+ LoadingCache () =  LoadingCache (load_path (), Dict (), Dict (), Dict ())
230+ 
231+ 
213232struct  TOMLCache
214233    p:: TOML.Parser 
215234    d:: Dict{String, CachedTOMLDict} 
@@ -226,6 +245,10 @@ function parsed_toml(project_file::AbstractString, toml_cache::TOMLCache, toml_l
226245            return  d. d
227246        else 
228247            d =  toml_cache. d[project_file]
248+             #  We are in a require call, assume project file has not been modified
249+             if  LOADING_CACHE[] != =  nothing 
250+                 return  d. d
251+             end 
229252            return  get_updated_dict (toml_cache. p, d)
230253        end 
231254    end 
@@ -352,16 +375,29 @@ const preferences_names = ("JuliaLocalPreferences.toml", "LocalPreferences.toml"
352375#   - `true`: `env` is an implicit environment
353376#   - `path`: the path of an explicit project file
354377function  env_project_file (env:: String ):: Union{Bool,String} 
378+     cache =  LOADING_CACHE[]
379+     if  cache != =  nothing 
380+         project_file =  get (cache. env_project_file, env, nothing )
381+         project_file ===  nothing  ||  return  project_file
382+     end 
355383    if  isdir (env)
356384        for  proj in  project_names
357-             project_file =  joinpath (env, proj)
358-             isfile_casesensitive (project_file) &&  return  project_file
385+             maybe_project_file =  joinpath (env, proj)
386+             if  isfile_casesensitive (maybe_project_file)
387+                 project_file =  maybe_project_file
388+                 break 
389+             end 
359390        end 
360-         return   true 
391+         project_file  = true 
361392    elseif  basename (env) in  project_names &&  isfile_casesensitive (env)
362-         return  env
393+         project_file =  env
394+     else 
395+         project_file =  false 
396+     end 
397+     if  cache != =  nothing 
398+         cache. env_project_file[env] =  project_file
363399    end 
364-     return  false 
400+     return  project_file 
365401end 
366402
367403function  project_deps_get (env:: String , name:: String ):: Union{Nothing,PkgId} 
415451
416452#  find project file's top-level UUID entry (or nothing)
417453function  project_file_name_uuid (project_file:: String , name:: String ):: PkgId 
418-     uuid =  dummy_uuid (project_file)
419454    d =  parsed_toml (project_file)
420455    uuid′ =  get (d, " uuid"  , nothing ):: Union{String, Nothing} 
421-     uuid′ ===  nothing  ||  (uuid  =  UUID (uuid′) )
456+     uuid  =  uuid ′ ===  nothing  ?   dummy_uuid (project_file)  :  UUID (uuid′)
422457    name =  get (d, " name"  , name):: String 
423458    return  PkgId (uuid, name)
424459end 
@@ -430,18 +465,34 @@ end
430465
431466#  find project file's corresponding manifest file
432467function  project_file_manifest_path (project_file:: String ):: Union{Nothing,String} 
468+     cache =  LOADING_CACHE[]
469+     if  cache != =  nothing 
470+         manifest_path =  get (cache. project_file_manifest_path, project_file, missing )
471+         manifest_path ===  missing  ||  return  manifest_path
472+     end 
433473    dir =  abspath (dirname (project_file))
434474    d =  parsed_toml (project_file)
435475    explicit_manifest =  get (d, " manifest"  , nothing ):: Union{String, Nothing} 
476+     manifest_path =  nothing 
436477    if  explicit_manifest != =  nothing 
437478        manifest_file =  normpath (joinpath (dir, explicit_manifest))
438-         isfile_casesensitive (manifest_file) &&  return  manifest_file
479+         if  isfile_casesensitive (manifest_file)
480+             manifest_path =  manifest_file
481+         end 
482+     end 
483+     if  manifest_path ===  nothing 
484+         for  mfst in  manifest_names
485+             manifest_file =  joinpath (dir, mfst)
486+             if  isfile_casesensitive (manifest_file)
487+                 manifest_path =  manifest_file
488+                 break 
489+             end 
490+         end 
439491    end 
440-     for  mfst in  manifest_names
441-         manifest_file =  joinpath (dir, mfst)
442-         isfile_casesensitive (manifest_file) &&  return  manifest_file
492+     if  cache != =  nothing 
493+         cache. project_file_manifest_path[project_file] =  manifest_path
443494    end 
444-     return  nothing 
495+     return  manifest_path 
445496end 
446497
447498#  given a directory (implicit env from LOAD_PATH) and a name,
@@ -876,42 +927,47 @@ For more details regarding code loading, see the manual sections on [modules](@r
876927[parallel computing](@ref code-availability). 
877928""" 
878929function  require (into:: Module , mod:: Symbol )
879-     uuidkey =  identify_package (into, String (mod))
880-     #  Core.println("require($(PkgId(into)), $mod) -> $uuidkey")
881-     if  uuidkey ===  nothing 
882-         where  =  PkgId (into)
883-         if  where . uuid ===  nothing 
884-             throw (ArgumentError (""" 
885-                 Package $mod  not found in current path: 
886-                 - Run `import Pkg; Pkg.add($(repr (String (mod))) )` to install the $mod  package. 
887-                 """  ))
888-         else 
889-             s =  """ 
890-             Package $(where . name)  does not have $mod  in its dependencies: 
891-             - If you have $(where . name)  checked out for development and have 
892-               added $mod  as a dependency but haven't updated your primary 
893-               environment's manifest file, try `Pkg.resolve()`. 
894-             - Otherwise you may need to report an issue with $(where . name) """  
895- 
896-             uuidkey =  identify_package (PkgId (string (into)), String (mod))
897-             uuidkey ===  nothing  &&  throw (ArgumentError (s))
898- 
899-             #  fall back to toplevel loading with a warning
900-             if  ! (where  in  modules_warned_for)
901-                 @warn  string (
902-                     full_warning_showed[] ?  " "   :  s, " \n "  ,
903-                     string (" Loading $(mod)  into $(where . name)  from project dependency, "  ,
904-                            " future warnings for $(where . name)  are suppressed."  )
905-                 ) _module =  nothing  _file =  nothing  _group =  nothing 
906-                 push! (modules_warned_for, where )
930+     LOADING_CACHE[] =  LoadingCache ()
931+     try 
932+         uuidkey =  identify_package (into, String (mod))
933+         #  Core.println("require($(PkgId(into)), $mod) -> $uuidkey")
934+         if  uuidkey ===  nothing 
935+             where  =  PkgId (into)
936+             if  where . uuid ===  nothing 
937+                 throw (ArgumentError (""" 
938+                     Package $mod  not found in current path: 
939+                     - Run `import Pkg; Pkg.add($(repr (String (mod))) )` to install the $mod  package. 
940+                     """  ))
941+             else 
942+                 s =  """ 
943+                 Package $(where . name)  does not have $mod  in its dependencies: 
944+                 - If you have $(where . name)  checked out for development and have 
945+                   added $mod  as a dependency but haven't updated your primary 
946+                   environment's manifest file, try `Pkg.resolve()`. 
947+                 - Otherwise you may need to report an issue with $(where . name) """  
948+ 
949+                 uuidkey =  identify_package (PkgId (string (into)), String (mod))
950+                 uuidkey ===  nothing  &&  throw (ArgumentError (s))
951+ 
952+                 #  fall back to toplevel loading with a warning
953+                 if  ! (where  in  modules_warned_for)
954+                     @warn  string (
955+                         full_warning_showed[] ?  " "   :  s, " \n "  ,
956+                         string (" Loading $(mod)  into $(where . name)  from project dependency, "  ,
957+                                " future warnings for $(where . name)  are suppressed."  )
958+                     ) _module =  nothing  _file =  nothing  _group =  nothing 
959+                     push! (modules_warned_for, where )
960+                 end 
961+                 full_warning_showed[] =  true 
907962            end 
908-             full_warning_showed[] =  true 
909963        end 
964+         if  _track_dependencies[]
965+             push! (_require_dependencies, (into, binpack (uuidkey), 0.0 ))
966+         end 
967+         return  require (uuidkey)
968+     finally 
969+         LOADING_CACHE[] =  nothing 
910970    end 
911-     if  _track_dependencies[]
912-         push! (_require_dependencies, (into, binpack (uuidkey), 0.0 ))
913-     end 
914-     return  require (uuidkey)
915971end 
916972
917973mutable struct  PkgOrigin
0 commit comments