@@ -16,6 +16,7 @@ import ..can_fancyprint, ..DEFAULT_IO
1616using .. Types, .. TOML
1717using .. Types: VersionTypes
1818using Base. BinaryPlatforms
19+ import .. stderr_f, .. stdout_f
1920using .. Artifacts: artifact_paths
2021using .. MiniProgressBars
2122
@@ -73,7 +74,7 @@ for f in (:develop, :add, :rm, :up, :pin, :free, :test, :build, :status)
7374 @eval begin
7475 $ f (pkg:: Union{AbstractString, PackageSpec} ; kwargs... ) = $ f ([pkg]; kwargs... )
7576 $ f (pkgs:: Vector{<:AbstractString} ; kwargs... ) = $ f ([PackageSpec (pkg) for pkg in pkgs]; kwargs... )
76- function $f (pkgs:: Vector{PackageSpec} ; io:: IO = DEFAULT_IO[] , kwargs... )
77+ function $f (pkgs:: Vector{PackageSpec} ; io:: IO = $ (f === :status ? :stdout_f : :stderr_f )() , kwargs... )
7778 ctx = Context ()
7879 kwargs = merge ((;kwargs... ), (:io => io,))
7980 ret = $ f (ctx, pkgs; kwargs... )
@@ -261,7 +262,7 @@ function up(ctx::Context, pkgs::Vector{PackageSpec};
261262 return
262263end
263264
264- resolve (; io:: IO = DEFAULT_IO[] , kwargs... ) = resolve (Context (;io); kwargs... )
265+ resolve (; io:: IO = stderr_f () , kwargs... ) = resolve (Context (;io); kwargs... )
265266function resolve (ctx:: Context ; kwargs... )
266267 up (ctx; level= UPLEVEL_FIXED, mode= PKGMODE_MANIFEST, update_registry= false , kwargs... )
267268 return nothing
@@ -924,6 +925,7 @@ function precompile(ctx::Context; internal_call::Bool=false, strict::Bool=false,
924925 # Windows sometimes hits a ReadOnlyMemoryError, so we halve the default number of tasks. Issue #2323
925926 # TODO : Investigate why this happens in windows and restore the full task limit
926927 default_num_tasks = Sys. iswindows () ? div (Sys. CPU_THREADS:: Int , 2 ) + 1 : Sys. CPU_THREADS:: Int + 1
928+ default_num_tasks = min (default_num_tasks, 16 ) # limit for better stability on shared resource systems
927929
928930 num_tasks = parse (Int, get (ENV , " JULIA_NUM_PRECOMPILE_TASKS" , string (default_num_tasks)))
929931 parallel_limiter = Base. Semaphore (num_tasks)
@@ -1008,9 +1010,11 @@ function precompile(ctx::Context; internal_call::Bool=false, strict::Bool=false,
10081010 ansi_disablecursor = " \e [?25l"
10091011 n_done:: Int = 0
10101012 n_already_precomp:: Int = 0
1013+ n_loaded:: Int = 0
10111014
10121015 function handle_interrupt (err)
10131016 notify (interrupted_or_done)
1017+ sleep (0.2 ) # yield for a period to let the print loop cease first
10141018 if err isa InterruptException
10151019 lock (print_lock) do
10161020 println (io, " Interrupted: Exiting precompilation..." )
@@ -1054,15 +1058,16 @@ function precompile(ctx::Context; internal_call::Bool=false, strict::Bool=false,
10541058 bar. max = n_total - n_already_precomp
10551059 final_loop || print (iostr, sprint (io -> show_progress (io, bar); context= io), " \n " )
10561060 for dep in pkg_queue_show
1061+ loaded = haskey (Base. loaded_modules, dep)
10571062 name = dep in direct_deps ? dep. name : string (color_string (dep. name, :light_black ))
10581063 if dep in precomperr_deps
10591064 print (iostr, color_string (" ? " , Base. warn_color ()), name, " \n " )
10601065 elseif haskey (failed_deps, dep)
10611066 print (iostr, color_string (" ✗ " , Base. error_color ()), name, " \n " )
10621067 elseif was_recompiled[dep]
1063- interrupted_or_done. set && continue
1064- print (iostr, color_string (" ✓ " , :green ), name, " \n " )
1065- @async begin # keep successful deps visible for short period
1068+ ! loaded && interrupted_or_done. set && continue
1069+ print (iostr, color_string (" ✓ " , loaded ? Base . warn_color () : :green ), name, " \n " )
1070+ loaded || @async begin # keep successful deps visible for short period
10661071 sleep (1 );
10671072 filter! (! isequal (dep), pkg_queue)
10681073 end
@@ -1109,6 +1114,7 @@ function precompile(ctx::Context; internal_call::Bool=false, strict::Bool=false,
11091114
11101115 task = @async begin
11111116 try
1117+ loaded = haskey (Base. loaded_modules, pkg)
11121118 for dep in deps # wait for deps to finish
11131119 wait (was_processed[dep])
11141120 end
@@ -1141,7 +1147,12 @@ function precompile(ctx::Context; internal_call::Bool=false, strict::Bool=false,
11411147 end
11421148 try
11431149 ret = Logging. with_logger (Logging. NullLogger ()) do
1144- Base. compilecache (pkg, sourcepath, iob, devnull ) # capture stderr, send stdout to devnull
1150+ @static if hasmethod (Base. compilecache, Tuple{Base. PkgId, String, IO, IO, Bool})
1151+ # capture stderr, send stdout to devnull, don't skip loaded modules
1152+ Base. compilecache (pkg, sourcepath, iob, devnull , false )
1153+ else
1154+ Base. compilecache (pkg, sourcepath, iob, devnull )
1155+ end
11451156 end
11461157 if ret isa Base. PrecompilableError
11471158 push! (precomperr_deps, pkg)
@@ -1152,13 +1163,14 @@ function precompile(ctx::Context; internal_call::Bool=false, strict::Bool=false,
11521163 else
11531164 queued && (haskey (man, pkg. uuid) && precomp_dequeue! (make_pkgspec (man, pkg. uuid)))
11541165 ! fancyprint && lock (print_lock) do
1155- println (io, string (color_string (" ✓ " , :green ), name))
1166+ println (io, string (color_string (" ✓ " , loaded ? Base . warn_color () : :green ), name))
11561167 end
11571168 was_recompiled[pkg] = true
11581169 end
1170+ loaded && (n_loaded += 1 )
11591171 catch err
1160- if err isa ErrorException
1161- failed_deps[pkg] = (strict || is_direct_dep) ? String (take! (iob)) : " "
1172+ if err isa ErrorException || (err isa ArgumentError && startswith (err . msg, " Invalid header in cache file " ))
1173+ failed_deps[pkg] = (strict || is_direct_dep) ? string ( sprint (showerror, err), " \n " , String (take! (iob) )) : " "
11621174 ! fancyprint && lock (print_lock) do
11631175 println (io, string (color_string (" ✗ " , Base. error_color ()), name))
11641176 end
@@ -1211,6 +1223,15 @@ function precompile(ctx::Context; internal_call::Bool=false, strict::Bool=false,
12111223 ! isempty (skipped_deps) && (print (iostr, " , $(length (skipped_deps)) skipped during auto due to previous errors" ))
12121224 print (iostr, " )" )
12131225 end
1226+ if n_loaded > 0
1227+ plural1 = n_loaded == 1 ? " y" : " ies"
1228+ plural2 = n_loaded == 1 ? " a different version is" : " different versions are"
1229+ plural3 = n_loaded == 1 ? " " : " s"
1230+ print (iostr, " \n " ,
1231+ color_string (string (n_loaded), Base. warn_color ()),
1232+ " dependenc$(plural1) precompiled but $(plural2) currently loaded. Restart julia to access the new version$(plural3) "
1233+ )
1234+ end
12141235 if ! isempty (precomperr_deps)
12151236 plural = length (precomperr_deps) == 1 ? " y" : " ies"
12161237 print (iostr, " \n " ,
@@ -1406,9 +1427,9 @@ function status(ctx::Context, pkgs::Vector{PackageSpec}; diff::Bool=false, mode=
14061427end
14071428
14081429
1409- function activate (;temp= false , shared= false , io:: IO = DEFAULT_IO[] )
1430+ function activate (;temp= false , shared= false , io:: IO = stderr_f () )
14101431 shared && pkgerror (" Must give a name for a shared environment" )
1411- temp && return activate (mktempdir ())
1432+ temp && return activate (mktempdir (); io )
14121433 Base. ACTIVE_PROJECT[] = nothing
14131434 p = Base. active_project ()
14141435 p === nothing || printpkgstyle (io, :Activating , " environment at $(pathrepr (p)) " )
@@ -1432,7 +1453,7 @@ function _activate_dep(dep_name::AbstractString)
14321453 end
14331454 end
14341455end
1435- function activate (path:: AbstractString ; shared:: Bool = false , temp:: Bool = false , io:: IO = DEFAULT_IO[] )
1456+ function activate (path:: AbstractString ; shared:: Bool = false , temp:: Bool = false , io:: IO = stderr_f () )
14361457 temp && pkgerror (" Can not give `path` argument when creating a temporary environment" )
14371458 if ! shared
14381459 # `pkg> activate path`/`Pkg.activate(path)` does the following
0 commit comments