From bea51c4a83a6621a4fb44174864025eac2092e5d Mon Sep 17 00:00:00 2001 From: Ian Date: Tue, 6 Oct 2020 17:39:17 -0400 Subject: [PATCH 01/43] fix unsuspending precomp errored pkgs (fix #2077) --- src/Operations.jl | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Operations.jl b/src/Operations.jl index f9cc7d3ac6..35458a8581 100644 --- a/src/Operations.jl +++ b/src/Operations.jl @@ -20,10 +20,10 @@ import ...Pkg: pkg_server ######### const pkgs_precompile_suspended = Base.PkgId[] -precomp_suspend!(pkg) = push!(pkgs_precompile_suspended, pkg) -precomp_unsuspend!(pkg) = filter!(!isequal(pkg), pkgs_precompile_suspended) +precomp_suspend!(pkg::Base.PkgId) = push!(pkgs_precompile_suspended, pkg) +precomp_unsuspend!(pkg::Base.PkgId) = filter!(!isequal(pkg), pkgs_precompile_suspended) precomp_unsuspend!() = empty!(pkgs_precompile_suspended) -precomp_suspended(pkg) = pkg in pkgs_precompile_suspended +precomp_suspended(pkg::Base.PkgId) = pkg in pkgs_precompile_suspended function find_installed(name::String, uuid::UUID, sha1::SHA1) slug_default = Base.version_slug(uuid, sha1) @@ -136,7 +136,7 @@ function update_manifest!(ctx::Context, pkgs::Vector{PackageSpec}, deps_map) entry.deps = deps_map[pkg.uuid] end ctx.env.manifest[pkg.uuid] = entry - precomp_unsuspend!(pkg) + precomp_unsuspend!(Base.PkgId(pkg.uuid, pkg.name)) end prune_manifest(ctx) end From e91d70a67cc8c55df1cc807c35e75e67c4358968 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 7 Oct 2020 01:13:43 -0400 Subject: [PATCH 02/43] pretty printing precomp ideas --- src/API.jl | 111 ++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 89 insertions(+), 22 deletions(-) diff --git a/src/API.jl b/src/API.jl index 2337868660..c2d429ff7b 100644 --- a/src/API.jl +++ b/src/API.jl @@ -7,6 +7,7 @@ using Printf import Random using Dates import LibGit2 +import Logging import ..depots, ..depots1, ..logdir, ..devdir import ..Operations, ..GitTools, ..Pkg, ..UPDATED_REGISTRY_THIS_SESSION @@ -922,7 +923,7 @@ function precompile(ctx::Context; internal_call::Bool=false) Base.PkgId(uuid, name) for (name, uuid) in ctx.env.project.deps if !Base.in_sysimage(Base.PkgId(uuid, name)) ] - + man = Pkg.Types.read_manifest(ctx.env.manifest_file) deps_pair_or_nothing = Iterators.map(man) do dep pkg = Base.PkgId(first(dep), last(dep).name) @@ -938,10 +939,12 @@ function precompile(ctx::Context; internal_call::Bool=false) for x in ctx.env.project.deps if !Base.in_sysimage(Base.PkgId(last(x), first(x))) ] end - + + started = Dict{Base.PkgId,Bool}() was_processed = Dict{Base.PkgId,Base.Event}() was_recompiled = Dict{Base.PkgId,Bool}() for pkgid in keys(depsmap) + started[pkgid] = false was_processed[pkgid] = Base.Event() was_recompiled[pkgid] = false end @@ -959,9 +962,77 @@ function precompile(ctx::Context; internal_call::Bool=false) !internal_call && @warn "Circular dependency detected. Precompilation skipped for $pkg" end end - + + pkg_queue = Base.PkgId[] + failed_direct_deps = Base.PkgId[] + failed_indirect_deps = Base.PkgId[] + print_lock = stdout isa Base.LibuvStream ? stdout.lock : ReentrantLock() - errored = false + first_started = Base.Event() + finished = false + should_exit = false + num_deps_show = 20 + t_print = @async begin + anim_chars = ["◐","◓","◑","◒"] + wait(first_started) + isempty(pkg_queue) && return + lock(print_lock) do + printpkgstyle(ctx, :Precompiling, "project...") + end + t = Timer(0; interval=1/10) + i = 1 + last_length = 0 + while !should_exit + pkg_queue_show = if length(pkg_queue) > num_deps_show + pkg_queue[end-num_deps_show:end] + else + pkg_queue + end + str = "" + if i > 1 + str *= "\e[$(last_length)A\e[1G\e[0J" + end + for dep in pkg_queue_show + finished && was_recompiled[dep] && continue + name = dep in direct_deps ? dep.name : " \e[38;5;244m$(dep.name)\e[0m" + if Operations.precomp_suspended(dep) + str *= string(name, " \e[38;5;160m✗\e[0m\n") + elseif was_recompiled[dep] + str *= string(name, " \e[38;5;46m✓\e[0m\n") + @async begin + sleep(0.5); + lock(print_lock) do + filter!(!isequal(dep), pkg_queue) + end + end + elseif started[dep] + anim_char = anim_chars[i % length(anim_chars) + 1] + anim_char_colored = dep in direct_deps ? anim_char : "\e[38;5;244m$(anim_char)\e[0m" + str *= string(name, " $anim_char_colored\n") + else + str *= name * "\n" + end + end + last_length = length(pkg_queue_show) + lock(print_lock) do + print(str) + end + should_exit = finished + i += 1 + wait(t) + end + ndeps = count(values(was_recompiled)) + println("$(ndeps) dependencies successfully precompiled ($(length(depsmap) - ndeps - length(failed_indirect_deps) - length(failed_direct_deps)) already precompiled)") + # if !isempty(failed_indirect_deps) + # println("\n\e[38;5;190mWarning:\e[0m The following indirect dependencies failed to precompile:") + # println.(failed_indirect_deps) + # end + # if !isempty(failed_direct_deps) + # println("\n\e[38;5;160mError:\e[0m The following direct dependencies failed to precompile:") + # println.(failed_direct_deps) + # end + end + toml_c = Base.TOMLCache() @sync for (pkg, deps) in depsmap paths = Base.find_all_in_cache_path(pkg) @@ -980,30 +1051,23 @@ function precompile(ctx::Context; internal_call::Bool=false) # skip stale checking and force compilation if any dep was recompiled in this session any_dep_recompiled = any(map(dep->was_recompiled[dep], deps)) - if !errored && !Operations.precomp_suspended(pkg) && (any_dep_recompiled || _is_stale(paths, sourcepath, toml_c)) - + if !Operations.precomp_suspended(pkg) && (any_dep_recompiled || _is_stale(paths, sourcepath, toml_c)) Base.acquire(parallel_limiter) - if errored # catch things queued before error occurred - notify(was_processed[pkg]) - Base.release(parallel_limiter) - return - end - is_direct_dep = pkg in direct_deps + is_direct_dep = pkg in direct_deps try - lock(print_lock) do - if !any(values(was_recompiled)) - printpkgstyle(ctx, :Precompiling, "project...") - end - was_recompiled[pkg] = true # needs to be in lock to prevent async race on printing + push!(pkg_queue, pkg) + notify(first_started) + started[pkg] = true + Logging.with_logger(Logging.NullLogger()) do + Base.compilecache(pkg, sourcepath, toml_c, false) # don't print errors from indirect deps end - Base.compilecache(pkg, sourcepath, toml_c, is_direct_dep) # don't print errors from indirect deps + was_recompiled[pkg] = true catch err Operations.precomp_suspend!(pkg) - if is_direct_dep # only throw errors for direct dependencies (in Project) - errored = true - throw(err) + if is_direct_dep + push!(failed_direct_deps, pkg) else - @warn "Precompilation failed for indirect dependency $(pkg)" + push!(failed_indirect_deps, pkg) end finally notify(was_processed[pkg]) @@ -1014,6 +1078,9 @@ function precompile(ctx::Context; internal_call::Bool=false) end end end + finished = true + notify(first_started) + wait(t_print) nothing end From 320fb0f0450f356ac4f1b7c41239be85e987aed6 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 7 Oct 2020 01:13:58 -0400 Subject: [PATCH 03/43] add Logging to deps --- Project.toml | 1 + 1 file changed, 1 insertion(+) diff --git a/Project.toml b/Project.toml index ee04bbd3e9..44226c4341 100644 --- a/Project.toml +++ b/Project.toml @@ -10,6 +10,7 @@ Artifacts = "56f22d72-fd6d-98f1-02f0-08ddc0907c33" Dates = "ade2ca70-3891-5945-98fb-dc099432e06a" LibGit2 = "76f85450-5226-5b5a-8eaa-529ad045b433" Libdl = "8f399da3-3557-5675-b5ff-fb832c97cbdb" +Logging = "56ddb016-857b-54e1-b83d-db4d58db5568" Markdown = "d6f4376e-aef5-505a-96c1-9c027394607a" Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" From 79f96b696181ba74808339c44c859e3344164055 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 7 Oct 2020 09:04:01 -0400 Subject: [PATCH 04/43] better terminal height management --- src/API.jl | 70 +++++++++++++++++++++++++----------------------------- 1 file changed, 32 insertions(+), 38 deletions(-) diff --git a/src/API.jl b/src/API.jl index c2d429ff7b..8f6ea30bc1 100644 --- a/src/API.jl +++ b/src/API.jl @@ -971,7 +971,7 @@ function precompile(ctx::Context; internal_call::Bool=false) first_started = Base.Event() finished = false should_exit = false - num_deps_show = 20 + t_print = @async begin anim_chars = ["◐","◓","◑","◒"] wait(first_started) @@ -983,38 +983,40 @@ function precompile(ctx::Context; internal_call::Bool=false) i = 1 last_length = 0 while !should_exit - pkg_queue_show = if length(pkg_queue) > num_deps_show - pkg_queue[end-num_deps_show:end] - else - pkg_queue - end - str = "" - if i > 1 - str *= "\e[$(last_length)A\e[1G\e[0J" - end - for dep in pkg_queue_show - finished && was_recompiled[dep] && continue - name = dep in direct_deps ? dep.name : " \e[38;5;244m$(dep.name)\e[0m" - if Operations.precomp_suspended(dep) - str *= string(name, " \e[38;5;160m✗\e[0m\n") - elseif was_recompiled[dep] - str *= string(name, " \e[38;5;46m✓\e[0m\n") - @async begin - sleep(0.5); - lock(print_lock) do - filter!(!isequal(dep), pkg_queue) + lock(print_lock) do + term_size = Base.displaysize(stdout)::Tuple{Int,Int} + num_deps_show = term_size[1] - 2 + pkg_queue_show = if !finished && length(pkg_queue) > num_deps_show + last(pkg_queue, num_deps_show) + else + pkg_queue + end + str = "" + if i > 1 + str *= "\e[$(last_length)A\e[1G\e[0J" + end + for dep in pkg_queue_show + finished && was_recompiled[dep] && continue + name = dep in direct_deps ? dep.name : " \e[38;5;244m$(dep.name)\e[0m" + if Operations.precomp_suspended(dep) + str *= string(name, " \e[38;5;160m✗\e[0m\n") + elseif was_recompiled[dep] + str *= string(name, " \e[38;5;46m✓\e[0m\n") + @async begin + sleep(1); + lock(print_lock) do + filter!(!isequal(dep), pkg_queue) + end end + elseif started[dep] + anim_char = anim_chars[i % length(anim_chars) + 1] + anim_char_colored = dep in direct_deps ? anim_char : "\e[38;5;244m$(anim_char)\e[0m" + str *= string(name, " $anim_char_colored\n") + else + str *= name * "\n" end - elseif started[dep] - anim_char = anim_chars[i % length(anim_chars) + 1] - anim_char_colored = dep in direct_deps ? anim_char : "\e[38;5;244m$(anim_char)\e[0m" - str *= string(name, " $anim_char_colored\n") - else - str *= name * "\n" end - end - last_length = length(pkg_queue_show) - lock(print_lock) do + last_length = length(pkg_queue_show) print(str) end should_exit = finished @@ -1023,14 +1025,6 @@ function precompile(ctx::Context; internal_call::Bool=false) end ndeps = count(values(was_recompiled)) println("$(ndeps) dependencies successfully precompiled ($(length(depsmap) - ndeps - length(failed_indirect_deps) - length(failed_direct_deps)) already precompiled)") - # if !isempty(failed_indirect_deps) - # println("\n\e[38;5;190mWarning:\e[0m The following indirect dependencies failed to precompile:") - # println.(failed_indirect_deps) - # end - # if !isempty(failed_direct_deps) - # println("\n\e[38;5;160mError:\e[0m The following direct dependencies failed to precompile:") - # println.(failed_direct_deps) - # end end toml_c = Base.TOMLCache() From 7ee8f1a795449eeebe3978c2aa5f910bb8d64714 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 7 Oct 2020 09:28:52 -0400 Subject: [PATCH 05/43] tweaks --- src/API.jl | 23 +++++++++-------------- 1 file changed, 9 insertions(+), 14 deletions(-) diff --git a/src/API.jl b/src/API.jl index 8f6ea30bc1..3853962594 100644 --- a/src/API.jl +++ b/src/API.jl @@ -964,8 +964,7 @@ function precompile(ctx::Context; internal_call::Bool=false) end pkg_queue = Base.PkgId[] - failed_direct_deps = Base.PkgId[] - failed_indirect_deps = Base.PkgId[] + failed_deps = Base.PkgId[] print_lock = stdout isa Base.LibuvStream ? stdout.lock : ReentrantLock() first_started = Base.Event() @@ -973,13 +972,13 @@ function precompile(ctx::Context; internal_call::Bool=false) should_exit = false t_print = @async begin - anim_chars = ["◐","◓","◑","◒"] wait(first_started) isempty(pkg_queue) && return lock(print_lock) do printpkgstyle(ctx, :Precompiling, "project...") end t = Timer(0; interval=1/10) + anim_chars = ["◐","◓","◑","◒"] i = 1 last_length = 0 while !should_exit @@ -998,14 +997,14 @@ function precompile(ctx::Context; internal_call::Bool=false) for dep in pkg_queue_show finished && was_recompiled[dep] && continue name = dep in direct_deps ? dep.name : " \e[38;5;244m$(dep.name)\e[0m" - if Operations.precomp_suspended(dep) + if dep in failed_deps str *= string(name, " \e[38;5;160m✗\e[0m\n") elseif was_recompiled[dep] str *= string(name, " \e[38;5;46m✓\e[0m\n") - @async begin - sleep(1); + @async begin # keep successful deps visible for short period + sleep(1); lock(print_lock) do - filter!(!isequal(dep), pkg_queue) + filter!(!isequal(dep), pkg_queue) end end elseif started[dep] @@ -1024,7 +1023,7 @@ function precompile(ctx::Context; internal_call::Bool=false) wait(t) end ndeps = count(values(was_recompiled)) - println("$(ndeps) dependencies successfully precompiled ($(length(depsmap) - ndeps - length(failed_indirect_deps) - length(failed_direct_deps)) already precompiled)") + println("$(ndeps) dependencies successfully precompiled ($(length(depsmap) - ndeps - length(failed_deps)) already precompiled)") end toml_c = Base.TOMLCache() @@ -1058,11 +1057,7 @@ function precompile(ctx::Context; internal_call::Bool=false) was_recompiled[pkg] = true catch err Operations.precomp_suspend!(pkg) - if is_direct_dep - push!(failed_direct_deps, pkg) - else - push!(failed_indirect_deps, pkg) - end + push!(failed_deps, pkg) finally notify(was_processed[pkg]) Base.release(parallel_limiter) @@ -1073,7 +1068,7 @@ function precompile(ctx::Context; internal_call::Bool=false) end end finished = true - notify(first_started) + notify(first_started) # in case of no-op wait(t_print) nothing end From df6af039573a66e3f126c057af3bf0391df58316 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 7 Oct 2020 13:00:28 -0400 Subject: [PATCH 06/43] fix suspension --- src/API.jl | 5 +++-- src/Operations.jl | 5 ++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/API.jl b/src/API.jl index 3853962594..bf4d034ba2 100644 --- a/src/API.jl +++ b/src/API.jl @@ -1023,9 +1023,10 @@ function precompile(ctx::Context; internal_call::Bool=false) wait(t) end ndeps = count(values(was_recompiled)) - println("$(ndeps) dependencies successfully precompiled ($(length(depsmap) - ndeps - length(failed_deps)) already precompiled)") + print("$(ndeps) dependencies successfully precompiled") + !isempty(failed_deps) && print(", $(length(failed_deps)) errored") + println(" ($(length(depsmap) - ndeps - length(failed_deps)) already precompiled)") end - toml_c = Base.TOMLCache() @sync for (pkg, deps) in depsmap paths = Base.find_all_in_cache_path(pkg) diff --git a/src/Operations.jl b/src/Operations.jl index 35458a8581..c112c1e5c7 100644 --- a/src/Operations.jl +++ b/src/Operations.jl @@ -121,6 +121,7 @@ function is_instantiated(ctx::Context)::Bool end function update_manifest!(ctx::Context, pkgs::Vector{PackageSpec}, deps_map) + manifest_before = deepcopy(ctx.env.manifest) manifest = ctx.env.manifest empty!(manifest) if ctx.env.pkg !== nothing @@ -135,8 +136,10 @@ function update_manifest!(ctx::Context, pkgs::Vector{PackageSpec}, deps_map) else entry.deps = deps_map[pkg.uuid] end + if !haskey(manifest_before, pkg.uuid) || manifest_before[pkg.uuid] != entry + precomp_unsuspend!(Base.PkgId(pkg.uuid, pkg.name)) + end ctx.env.manifest[pkg.uuid] = entry - precomp_unsuspend!(Base.PkgId(pkg.uuid, pkg.name)) end prune_manifest(ctx) end From 445819152af4cd6024dd5285c63763e83d091444 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 7 Oct 2020 14:00:09 -0400 Subject: [PATCH 07/43] better reporting at end --- src/API.jl | 52 ++++++++++++++++++++++++++++++++-------------------- 1 file changed, 32 insertions(+), 20 deletions(-) diff --git a/src/API.jl b/src/API.jl index bf4d034ba2..9dcf832655 100644 --- a/src/API.jl +++ b/src/API.jl @@ -965,6 +965,7 @@ function precompile(ctx::Context; internal_call::Bool=false) pkg_queue = Base.PkgId[] failed_deps = Base.PkgId[] + skipped_deps = Base.PkgId[] print_lock = stdout isa Base.LibuvStream ? stdout.lock : ReentrantLock() first_started = Base.Event() @@ -1023,9 +1024,18 @@ function precompile(ctx::Context; internal_call::Bool=false) wait(t) end ndeps = count(values(was_recompiled)) - print("$(ndeps) dependencies successfully precompiled") - !isempty(failed_deps) && print(", $(length(failed_deps)) errored") - println(" ($(length(depsmap) - ndeps - length(failed_deps)) already precompiled)") + str = "$(ndeps) dependencies successfully precompiled" + !isempty(failed_deps) && (str *= ", $(length(failed_deps)) errored") + n_already = length(depsmap) - ndeps - length(failed_deps) + if n_already > 0 || length(skipped_deps) > 0 + str *= " (" + n_already > 0 && (str *= "$n_already already precompiled") + isempty(skipped_deps) && (str *= ", $(length(skipped_deps)) packages skipped due to previous errors") + str *= ")" + end + lock(print_lock) do + println(str) + end end toml_c = Base.TOMLCache() @sync for (pkg, deps) in depsmap @@ -1045,27 +1055,29 @@ function precompile(ctx::Context; internal_call::Bool=false) # skip stale checking and force compilation if any dep was recompiled in this session any_dep_recompiled = any(map(dep->was_recompiled[dep], deps)) - if !Operations.precomp_suspended(pkg) && (any_dep_recompiled || _is_stale(paths, sourcepath, toml_c)) - Base.acquire(parallel_limiter) - is_direct_dep = pkg in direct_deps - try - push!(pkg_queue, pkg) - notify(first_started) - started[pkg] = true - Logging.with_logger(Logging.NullLogger()) do - Base.compilecache(pkg, sourcepath, toml_c, false) # don't print errors from indirect deps + if !Operations.precomp_suspended(pkg) + if (any_dep_recompiled || _is_stale(paths, sourcepath, toml_c)) + Base.acquire(parallel_limiter) + is_direct_dep = pkg in direct_deps + try + push!(pkg_queue, pkg) + notify(first_started) + started[pkg] = true + Logging.with_logger(Logging.NullLogger()) do + Base.compilecache(pkg, sourcepath, toml_c, false) # don't print errors from indirect deps + end + was_recompiled[pkg] = true + catch err + Operations.precomp_suspend!(pkg) + push!(failed_deps, pkg) + finally + Base.release(parallel_limiter) end - was_recompiled[pkg] = true - catch err - Operations.precomp_suspend!(pkg) - push!(failed_deps, pkg) - finally - notify(was_processed[pkg]) - Base.release(parallel_limiter) end else - notify(was_processed[pkg]) + push!(skipped_deps, pkg) end + notify(was_processed[pkg]) end end finished = true From 21e485d0c8781c4b642b5d7bd1b487a94bc7e85f Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 7 Oct 2020 14:04:24 -0400 Subject: [PATCH 08/43] tweak --- src/API.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/API.jl b/src/API.jl index 9dcf832655..750ab48ff9 100644 --- a/src/API.jl +++ b/src/API.jl @@ -1030,7 +1030,7 @@ function precompile(ctx::Context; internal_call::Bool=false) if n_already > 0 || length(skipped_deps) > 0 str *= " (" n_already > 0 && (str *= "$n_already already precompiled") - isempty(skipped_deps) && (str *= ", $(length(skipped_deps)) packages skipped due to previous errors") + !isempty(skipped_deps) && (str *= ", $(length(skipped_deps)) skipped due to previous errors") str *= ")" end lock(print_lock) do From eeccec435ac2e39bd25dd60ee9658b743ea27140 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 7 Oct 2020 14:26:33 -0400 Subject: [PATCH 09/43] wording tweak --- src/API.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/API.jl b/src/API.jl index 750ab48ff9..9d3c006bc4 100644 --- a/src/API.jl +++ b/src/API.jl @@ -1030,7 +1030,7 @@ function precompile(ctx::Context; internal_call::Bool=false) if n_already > 0 || length(skipped_deps) > 0 str *= " (" n_already > 0 && (str *= "$n_already already precompiled") - !isempty(skipped_deps) && (str *= ", $(length(skipped_deps)) skipped due to previous errors") + !isempty(skipped_deps) && (str *= ", $(length(skipped_deps)) skipped in auto mode due to previous errors") str *= ")" end lock(print_lock) do From b723b3a6c34e961aba96b6038c3aa726256a79c8 Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 7 Oct 2020 16:26:49 -0400 Subject: [PATCH 10/43] remove indent on indirect deps --- src/API.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/API.jl b/src/API.jl index 9d3c006bc4..daa116ce52 100644 --- a/src/API.jl +++ b/src/API.jl @@ -997,7 +997,7 @@ function precompile(ctx::Context; internal_call::Bool=false) end for dep in pkg_queue_show finished && was_recompiled[dep] && continue - name = dep in direct_deps ? dep.name : " \e[38;5;244m$(dep.name)\e[0m" + name = dep in direct_deps ? dep.name : "\e[38;5;244m$(dep.name)\e[0m" if dep in failed_deps str *= string(name, " \e[38;5;160m✗\e[0m\n") elseif was_recompiled[dep] From 07778c14cc150f5197813232053170d3100849ec Mon Sep 17 00:00:00 2001 From: Ian Date: Wed, 7 Oct 2020 17:16:25 -0400 Subject: [PATCH 11/43] actually, add indent to both. WIth indent looks better --- src/API.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/API.jl b/src/API.jl index daa116ce52..060e739477 100644 --- a/src/API.jl +++ b/src/API.jl @@ -997,7 +997,7 @@ function precompile(ctx::Context; internal_call::Bool=false) end for dep in pkg_queue_show finished && was_recompiled[dep] && continue - name = dep in direct_deps ? dep.name : "\e[38;5;244m$(dep.name)\e[0m" + name = dep in direct_deps ? " $(dep.name)" : " \e[38;5;244m$(dep.name)\e[0m" if dep in failed_deps str *= string(name, " \e[38;5;160m✗\e[0m\n") elseif was_recompiled[dep] From 4a08f1e7ea32eb67619396822c89acf69442afc8 Mon Sep 17 00:00:00 2001 From: Ian Date: Thu, 8 Oct 2020 11:03:22 -0400 Subject: [PATCH 12/43] clearer ansi code usage --- src/API.jl | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/API.jl b/src/API.jl index 060e739477..5ca37d1d04 100644 --- a/src/API.jl +++ b/src/API.jl @@ -971,6 +971,15 @@ function precompile(ctx::Context; internal_call::Bool=false) first_started = Base.Event() finished = false should_exit = false + + function color_string(str::String, col::Symbol) + enable_ansi = get(Base.text_colors, col, Base.text_colors[:default]) + disable_ansi = get(Base.disable_text_style, col, Base.text_colors[:default]) + return string(enable_ansi, str, disable_ansi) + end + ansi_moveup(n::Int) = string("\e[", n, "A") + ansi_movecol1 = "\e[1G" + ansi_cleartoend = "\e[0J" t_print = @async begin wait(first_started) @@ -993,15 +1002,16 @@ function precompile(ctx::Context; internal_call::Bool=false) end str = "" if i > 1 - str *= "\e[$(last_length)A\e[1G\e[0J" + str *= string(ansi_moveup(last_length), ansi_movecol1, ansi_cleartoend) end for dep in pkg_queue_show finished && was_recompiled[dep] && continue - name = dep in direct_deps ? " $(dep.name)" : " \e[38;5;244m$(dep.name)\e[0m" + name = dep in direct_deps ? " $(dep.name)" : string(" ", color_string(dep.name, :light_black)) if dep in failed_deps - str *= string(name, " \e[38;5;160m✗\e[0m\n") + ansi_s, ansi_e = gen_ansi(col::Symbol) + str *= string(name, " ", color_string("✗", Base.error_color()), "\n") elseif was_recompiled[dep] - str *= string(name, " \e[38;5;46m✓\e[0m\n") + str *= string(name, " ", color_string("✓", :green), "\n") @async begin # keep successful deps visible for short period sleep(1); lock(print_lock) do @@ -1010,7 +1020,7 @@ function precompile(ctx::Context; internal_call::Bool=false) end elseif started[dep] anim_char = anim_chars[i % length(anim_chars) + 1] - anim_char_colored = dep in direct_deps ? anim_char : "\e[38;5;244m$(anim_char)\e[0m" + anim_char_colored = dep in direct_deps ? anim_char : color_string(anim_char, :light_black) str *= string(name, " $anim_char_colored\n") else str *= name * "\n" From aa02ca9e31a91d6a770ef0e9885bcaecb0b9f4ca Mon Sep 17 00:00:00 2001 From: Ian Date: Thu, 8 Oct 2020 21:35:08 -0400 Subject: [PATCH 13/43] remove dead code --- src/API.jl | 1 - 1 file changed, 1 deletion(-) diff --git a/src/API.jl b/src/API.jl index 5ca37d1d04..f61e671869 100644 --- a/src/API.jl +++ b/src/API.jl @@ -1008,7 +1008,6 @@ function precompile(ctx::Context; internal_call::Bool=false) finished && was_recompiled[dep] && continue name = dep in direct_deps ? " $(dep.name)" : string(" ", color_string(dep.name, :light_black)) if dep in failed_deps - ansi_s, ansi_e = gen_ansi(col::Symbol) str *= string(name, " ", color_string("✗", Base.error_color()), "\n") elseif was_recompiled[dep] str *= string(name, " ", color_string("✓", :green), "\n") From e5c1901697de668614cc50db5f6bdbaa4f63f98c Mon Sep 17 00:00:00 2001 From: Ian Date: Thu, 8 Oct 2020 21:35:21 -0400 Subject: [PATCH 14/43] throw error if any direct deps fail --- src/API.jl | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/API.jl b/src/API.jl index f61e671869..e8d134ff62 100644 --- a/src/API.jl +++ b/src/API.jl @@ -1043,7 +1043,7 @@ function precompile(ctx::Context; internal_call::Bool=false) str *= ")" end lock(print_lock) do - println(str) + println(str, "\n") end end toml_c = Base.TOMLCache() @@ -1092,6 +1092,14 @@ function precompile(ctx::Context; internal_call::Bool=false) finished = true notify(first_started) # in case of no-op wait(t_print) + failed_direct = filter(in(direct_deps), failed_deps) + if !isempty(failed_direct) + failed_list = "" + for d in failed_direct + failed_list *= " $d\n" + end + throw(ErrorException("The following direct dependencies failed to precompile:\n$(failed_list)")) + end nothing end From 1a8585163bd562d2f331c614f297ed655e131e88 Mon Sep 17 00:00:00 2001 From: Ian Date: Thu, 8 Oct 2020 23:36:19 -0400 Subject: [PATCH 15/43] do basic printing when not in a Base.TTY --- src/API.jl | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) diff --git a/src/API.jl b/src/API.jl index e8d134ff62..aa28e5b10b 100644 --- a/src/API.jl +++ b/src/API.jl @@ -915,7 +915,8 @@ precompile(;internal_call::Bool=false) = precompile(Context(), internal_call=int function precompile(ctx::Context; internal_call::Bool=false) num_tasks = parse(Int, get(ENV, "JULIA_NUM_PRECOMPILE_TASKS", string(Sys.CPU_THREADS + 1))) parallel_limiter = Base.Semaphore(num_tasks) - + fancy_print = stdout isa Base.TTY + # when manually called, unsuspend all packages that were suspended due to precomp errors !internal_call && Operations.precomp_unsuspend!() @@ -970,7 +971,7 @@ function precompile(ctx::Context; internal_call::Bool=false) print_lock = stdout isa Base.LibuvStream ? stdout.lock : ReentrantLock() first_started = Base.Event() finished = false - should_exit = false + should_exit = !fancy_print # exit print loop immediately if not fancy printing function color_string(str::String, col::Symbol) enable_ansi = get(Base.text_colors, col, Base.text_colors[:default]) @@ -984,7 +985,7 @@ function precompile(ctx::Context; internal_call::Bool=false) t_print = @async begin wait(first_started) isempty(pkg_queue) && return - lock(print_lock) do + fancy_print && lock(print_lock) do printpkgstyle(ctx, :Precompiling, "project...") end t = Timer(0; interval=1/10) @@ -1036,7 +1037,7 @@ function precompile(ctx::Context; internal_call::Bool=false) str = "$(ndeps) dependencies successfully precompiled" !isempty(failed_deps) && (str *= ", $(length(failed_deps)) errored") n_already = length(depsmap) - ndeps - length(failed_deps) - if n_already > 0 || length(skipped_deps) > 0 + if n_already > 0 || !isempty(skipped_deps) str *= " (" n_already > 0 && (str *= "$n_already already precompiled") !isempty(skipped_deps) && (str *= ", $(length(skipped_deps)) skipped in auto mode due to previous errors") @@ -1069,14 +1070,25 @@ function precompile(ctx::Context; internal_call::Bool=false) Base.acquire(parallel_limiter) is_direct_dep = pkg in direct_deps try + !fancy_print && lock(print_lock) do + isempty(pkg_queue) && printpkgstyle(ctx, :Precompiling, "project...") + end push!(pkg_queue, pkg) - notify(first_started) started[pkg] = true + fancy_print && notify(first_started) Logging.with_logger(Logging.NullLogger()) do Base.compilecache(pkg, sourcepath, toml_c, false) # don't print errors from indirect deps end + !fancy_print && lock(print_lock) do + str = string(pkg, color_string(" ✓", :green)) + println(" ", is_direct_dep ? str : color_string(str, :light_black)) + end was_recompiled[pkg] = true catch err + !fancy_print && lock(print_lock) do + str = string(pkg, color_string(" ✗", Base.error_color())) + println(" ", is_direct_dep ? str : color_string(str, :light_black)) + end Operations.precomp_suspend!(pkg) push!(failed_deps, pkg) finally @@ -1090,7 +1102,7 @@ function precompile(ctx::Context; internal_call::Bool=false) end end finished = true - notify(first_started) # in case of no-op + notify(first_started) # in cases of no-op or !fancy_print wait(t_print) failed_direct = filter(in(direct_deps), failed_deps) if !isempty(failed_direct) From 520c1e900d70afdb85fc31699ef3bcdff3cd3834 Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 9 Oct 2020 00:29:54 -0400 Subject: [PATCH 16/43] add Pkg.precompile_auto for controlling auto precompilation --- src/API.jl | 7 +++++++ src/Pkg.jl | 9 +++++++++ src/REPLMode/command_declarations.jl | 12 ++++++++++++ 3 files changed, 28 insertions(+) diff --git a/src/API.jl b/src/API.jl index aa28e5b10b..28a589b79d 100644 --- a/src/API.jl +++ b/src/API.jl @@ -905,6 +905,13 @@ function _is_stale(paths::Vector{String}, sourcepath::String, toml_c::Base.TOMLC return true end +precompile_auto(b::Union{Bool,String}) = precompile_auto(Context(), b) +precompile_auto(ctx::Context, s::String) = precompile_auto(ctx, parse(Bool, s)) +function precompile_auto(ctx::Context, b::Bool) + ENV["JULIA_PKG_PRECOMPILE_AUTO"] = b ? "1" : "0" + nothing +end + function _auto_precompile() if parse(Int, get(ENV, "JULIA_PKG_PRECOMPILE_AUTO", "0")) == 1 Pkg.precompile(internal_call=true) diff --git a/src/Pkg.jl b/src/Pkg.jl index 8110346a7a..c7c3947711 100644 --- a/src/Pkg.jl +++ b/src/Pkg.jl @@ -142,6 +142,15 @@ Pkg.precompile() """ const precompile = API.precompile +""" + Pkg.precompile_auto(b::Bool) + +Enable or disable whether Pkg actions will auto-precompile packages, which is enabled by default. + +This can also be controlled by setting the environment variable `JULIA_PKG_PRECOMPILE_AUTO` to "1" or "0" +""" +const precompile_auto = API.precompile_auto + """ Pkg.rm(pkg::Union{String, Vector{String}}) Pkg.rm(pkg::Union{PackageSpec, Vector{PackageSpec}}) diff --git a/src/REPLMode/command_declarations.jl b/src/REPLMode/command_declarations.jl index 9663237470..5b9cd03ea9 100644 --- a/src/REPLMode/command_declarations.jl +++ b/src/REPLMode/command_declarations.jl @@ -312,6 +312,18 @@ Precompile all the dependencies of the project by running `import` on all of the The `startup.jl` file is disabled during precompilation unless julia is started with `--startup-file=yes`. """, ], +PSA[:name => "precompile_auto", + :api => API.precompile_auto, + :arg_count => 1 => 1, + :arg_parser => ((x,y) -> map(expanduser, unwrap(x))), + :description => "control whether auto-precompilation is enabled during pkg activities", + :help => md""" + precompile_auto + +Enable or disable whether Pkg actions will auto-precompile packages, which is enabled by default. +This can also be controlled by setting the environment variable `JULIA_PKG_PRECOMPILE_AUTO` to "1" or "0" +""", +], PSA[:name => "status", :short_name => "st", :api => API.status, From 168f7d0d160c94222f637aba34a81983e2e87d8e Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 9 Oct 2020 00:31:05 -0400 Subject: [PATCH 17/43] enable auto-precompilation by default --- src/API.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/API.jl b/src/API.jl index 28a589b79d..6fd6d9f9f4 100644 --- a/src/API.jl +++ b/src/API.jl @@ -913,7 +913,7 @@ function precompile_auto(ctx::Context, b::Bool) end function _auto_precompile() - if parse(Int, get(ENV, "JULIA_PKG_PRECOMPILE_AUTO", "0")) == 1 + if parse(Int, get(ENV, "JULIA_PKG_PRECOMPILE_AUTO", "1")) == 1 Pkg.precompile(internal_call=true) end end From a2f99822a28bb294f3908d3ed3a5f87f40343684 Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 9 Oct 2020 00:31:27 -0400 Subject: [PATCH 18/43] disable auto-precompilation during tests --- test/runtests.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index 7901f79d5b..e3cec2ccdc 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,6 +4,8 @@ module PkgTests import Pkg +ENV["JULIA_PKG_PRECOMPILE_AUTO"] = "0" + # Make sure to not start with an outdated registry rm(joinpath(@__DIR__, "registries"); force = true, recursive = true) From 71945621b9060e45f4b0f829253033c466059b3a Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 9 Oct 2020 01:12:35 -0400 Subject: [PATCH 19/43] add settings tip to auto calls --- src/API.jl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/API.jl b/src/API.jl index 6fd6d9f9f4..2da21b7d4a 100644 --- a/src/API.jl +++ b/src/API.jl @@ -926,6 +926,7 @@ function precompile(ctx::Context; internal_call::Bool=false) # when manually called, unsuspend all packages that were suspended due to precomp errors !internal_call && Operations.precomp_unsuspend!() + action_help = internal_call ? " (tip: control auto with `pkg> precompile_auto true/false`)" : "" direct_deps = [ Base.PkgId(uuid, name) @@ -993,7 +994,7 @@ function precompile(ctx::Context; internal_call::Bool=false) wait(first_started) isempty(pkg_queue) && return fancy_print && lock(print_lock) do - printpkgstyle(ctx, :Precompiling, "project...") + printpkgstyle(ctx, :Precompiling, "project...$action_help") end t = Timer(0; interval=1/10) anim_chars = ["◐","◓","◑","◒"] @@ -1078,7 +1079,7 @@ function precompile(ctx::Context; internal_call::Bool=false) is_direct_dep = pkg in direct_deps try !fancy_print && lock(print_lock) do - isempty(pkg_queue) && printpkgstyle(ctx, :Precompiling, "project...") + isempty(pkg_queue) && printpkgstyle(ctx, :Precompiling, "project...$action_help") end push!(pkg_queue, pkg) started[pkg] = true From f59b3ed6bb426d0276805b9719f198c506bc085c Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Fri, 9 Oct 2020 01:51:49 -0400 Subject: [PATCH 20/43] =?UTF-8?q?Don=E2=80=99t=20print=20uuids=20in=20basi?= =?UTF-8?q?c=20print=20mode?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- src/API.jl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/API.jl b/src/API.jl index 2da21b7d4a..4400a1a488 100644 --- a/src/API.jl +++ b/src/API.jl @@ -1088,13 +1088,13 @@ function precompile(ctx::Context; internal_call::Bool=false) Base.compilecache(pkg, sourcepath, toml_c, false) # don't print errors from indirect deps end !fancy_print && lock(print_lock) do - str = string(pkg, color_string(" ✓", :green)) + str = string(pkg.name, color_string(" ✓", :green)) println(" ", is_direct_dep ? str : color_string(str, :light_black)) end was_recompiled[pkg] = true catch err !fancy_print && lock(print_lock) do - str = string(pkg, color_string(" ✗", Base.error_color())) + str = string(pkg.name, color_string(" ✗", Base.error_color())) println(" ", is_direct_dep ? str : color_string(str, :light_black)) end Operations.precomp_suspend!(pkg) From 6acc6a312ee0dc5d311b64ba575068a256b5fef1 Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Fri, 9 Oct 2020 08:32:56 -0400 Subject: [PATCH 21/43] switch to throwing pkgerror Co-authored-by: Kristoffer Carlsson --- src/API.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/API.jl b/src/API.jl index 4400a1a488..be1dac1de3 100644 --- a/src/API.jl +++ b/src/API.jl @@ -1118,7 +1118,7 @@ function precompile(ctx::Context; internal_call::Bool=false) for d in failed_direct failed_list *= " $d\n" end - throw(ErrorException("The following direct dependencies failed to precompile:\n$(failed_list)")) + pkgerror("The following direct dependencies failed to precompile:\n$(failed_list)") end nothing end From e66dd7e704c9b299779cc3736d874a0dea4531a3 Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 9 Oct 2020 12:29:23 -0400 Subject: [PATCH 22/43] add io control to precompile --- src/API.jl | 20 +++++++++----------- 1 file changed, 9 insertions(+), 11 deletions(-) diff --git a/src/API.jl b/src/API.jl index be1dac1de3..936bc89c69 100644 --- a/src/API.jl +++ b/src/API.jl @@ -918,8 +918,8 @@ function _auto_precompile() end end -precompile(;internal_call::Bool=false) = precompile(Context(), internal_call=internal_call) -function precompile(ctx::Context; internal_call::Bool=false) +precompile(; kwargs...) = precompile(Context(); kwargs...) +function precompile(ctx::Context; internal_call::Bool=false, io::IO=stdout) num_tasks = parse(Int, get(ENV, "JULIA_NUM_PRECOMPILE_TASKS", string(Sys.CPU_THREADS + 1))) parallel_limiter = Base.Semaphore(num_tasks) fancy_print = stdout isa Base.TTY @@ -994,7 +994,7 @@ function precompile(ctx::Context; internal_call::Bool=false) wait(first_started) isempty(pkg_queue) && return fancy_print && lock(print_lock) do - printpkgstyle(ctx, :Precompiling, "project...$action_help") + printpkgstyle(io, :Precompiling, "project...$action_help") end t = Timer(0; interval=1/10) anim_chars = ["◐","◓","◑","◒"] @@ -1022,9 +1022,7 @@ function precompile(ctx::Context; internal_call::Bool=false) str *= string(name, " ", color_string("✓", :green), "\n") @async begin # keep successful deps visible for short period sleep(1); - lock(print_lock) do - filter!(!isequal(dep), pkg_queue) - end + filter!(!isequal(dep), pkg_queue) end elseif started[dep] anim_char = anim_chars[i % length(anim_chars) + 1] @@ -1035,7 +1033,7 @@ function precompile(ctx::Context; internal_call::Bool=false) end end last_length = length(pkg_queue_show) - print(str) + print(io, str) end should_exit = finished i += 1 @@ -1052,7 +1050,7 @@ function precompile(ctx::Context; internal_call::Bool=false) str *= ")" end lock(print_lock) do - println(str, "\n") + println(io, str, "\n") end end toml_c = Base.TOMLCache() @@ -1079,7 +1077,7 @@ function precompile(ctx::Context; internal_call::Bool=false) is_direct_dep = pkg in direct_deps try !fancy_print && lock(print_lock) do - isempty(pkg_queue) && printpkgstyle(ctx, :Precompiling, "project...$action_help") + isempty(pkg_queue) && printpkgstyle(io, :Precompiling, "project...$action_help") end push!(pkg_queue, pkg) started[pkg] = true @@ -1089,13 +1087,13 @@ function precompile(ctx::Context; internal_call::Bool=false) end !fancy_print && lock(print_lock) do str = string(pkg.name, color_string(" ✓", :green)) - println(" ", is_direct_dep ? str : color_string(str, :light_black)) + println(io, " ", is_direct_dep ? str : color_string(str, :light_black)) end was_recompiled[pkg] = true catch err !fancy_print && lock(print_lock) do str = string(pkg.name, color_string(" ✗", Base.error_color())) - println(" ", is_direct_dep ? str : color_string(str, :light_black)) + println(io, " ", is_direct_dep ? str : color_string(str, :light_black))s end Operations.precomp_suspend!(pkg) push!(failed_deps, pkg) From 5bd91ec69f41f45daeb85deba592b782b5cf063c Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 9 Oct 2020 12:30:47 -0400 Subject: [PATCH 23/43] add tests for controlling auto precompilation --- test/api.jl | 12 ++++++++++++ test/repl.jl | 2 ++ 2 files changed, 14 insertions(+) diff --git a/test/api.jl b/test/api.jl index 235f03ec15..b627e4f27a 100644 --- a/test/api.jl +++ b/test/api.jl @@ -124,6 +124,8 @@ end Pkg.generate("Dep1") Pkg.generate("Dep2") Pkg.generate("Dep3") + Pkg.generate("Dep4") + Pkg.generate("Dep5") end Pkg.develop(Pkg.PackageSpec(path="packages/Dep1")) @@ -135,6 +137,16 @@ end Pkg.activate(".") Pkg.resolve() Pkg.precompile() + + iob = IOBuffer() + Pkg.precompile_auto(true) + Pkg.develop(Pkg.PackageSpec(path="packages/Dep4")) + Pkg.precompile(io = iob) + @test String(take!(iob)) == "" # test that the previous precompile was a no-op + Pkg.precompile_auto(false) + Pkg.develop(Pkg.PackageSpec(path="packages/Dep5")) + Pkg.precompile(io = iob) + @test String(take!(iob)) != "" # test that the previous precompile did some work end # ignoring circular deps, to avoid deadlock diff --git a/test/repl.jl b/test/repl.jl index de7855bdf7..1fbfa55adb 100644 --- a/test/repl.jl +++ b/test/repl.jl @@ -160,6 +160,8 @@ temp_pkg_dir() do project_path; cd(project_path) do cp(p1_path, p1_new_path) Pkg.REPLMode.pkgstr("develop $(p1_new_path)") Pkg.REPLMode.pkgstr("build; precompile") + Pkg.REPLMode.pkgstr("precompile_auto true") + Pkg.REPLMode.pkgstr("precompile_auto false") @test realpath(Base.find_package("UnregisteredWithProject")) == realpath(joinpath(p1_new_path, "src", "UnregisteredWithProject.jl")) @test Pkg.dependencies()[UUID("58262bb0-2073-11e8-3727-4fe182c12249")].version == v"0.1.0" Pkg.test("UnregisteredWithProject") From c10d8b13edeb14318d670850daf98350963fda60 Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 9 Oct 2020 12:32:28 -0400 Subject: [PATCH 24/43] check correct io --- src/API.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/API.jl b/src/API.jl index 936bc89c69..05a14f9616 100644 --- a/src/API.jl +++ b/src/API.jl @@ -922,7 +922,7 @@ precompile(; kwargs...) = precompile(Context(); kwargs...) function precompile(ctx::Context; internal_call::Bool=false, io::IO=stdout) num_tasks = parse(Int, get(ENV, "JULIA_NUM_PRECOMPILE_TASKS", string(Sys.CPU_THREADS + 1))) parallel_limiter = Base.Semaphore(num_tasks) - fancy_print = stdout isa Base.TTY + fancy_print = io isa Base.TTY # when manually called, unsuspend all packages that were suspended due to precomp errors !internal_call && Operations.precomp_unsuspend!() From bf805d363d7fe951d147bd33ed6fd954355e87c4 Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 9 Oct 2020 15:19:06 -0400 Subject: [PATCH 25/43] check CI terminal type --- test/runtests.jl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/runtests.jl b/test/runtests.jl index 449883fad3..3b9ddc2661 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,6 +6,8 @@ import Pkg ENV["JULIA_PKG_PRECOMPILE_AUTO"] = "0" +@show stdout isa Base.TTY + if (server = Pkg.pkg_server()) !== nothing && Sys.which("curl") !== nothing s = read(`curl -sLI $(server)`, String); @info "Pkg Server metadata:\n$s" From a761f481ee7d38680f1eab33ec089232ad7a1fa0 Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 9 Oct 2020 23:12:41 -0400 Subject: [PATCH 26/43] don't fancy print on CI --- src/API.jl | 2 +- test/runtests.jl | 2 -- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/src/API.jl b/src/API.jl index 05a14f9616..5ac9f7c959 100644 --- a/src/API.jl +++ b/src/API.jl @@ -922,7 +922,7 @@ precompile(; kwargs...) = precompile(Context(); kwargs...) function precompile(ctx::Context; internal_call::Bool=false, io::IO=stdout) num_tasks = parse(Int, get(ENV, "JULIA_NUM_PRECOMPILE_TASKS", string(Sys.CPU_THREADS + 1))) parallel_limiter = Base.Semaphore(num_tasks) - fancy_print = io isa Base.TTY + fancy_print = (io isa Base.TTY) && (get(ENV, "CI", nothing) != "true") # when manually called, unsuspend all packages that were suspended due to precomp errors !internal_call && Operations.precomp_unsuspend!() diff --git a/test/runtests.jl b/test/runtests.jl index 3b9ddc2661..449883fad3 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -6,8 +6,6 @@ import Pkg ENV["JULIA_PKG_PRECOMPILE_AUTO"] = "0" -@show stdout isa Base.TTY - if (server = Pkg.pkg_server()) !== nothing && Sys.which("curl") !== nothing s = read(`curl -sLI $(server)`, String); @info "Pkg Server metadata:\n$s" From f20c999b592958648bdb0a947c0b9c07b45ab1e9 Mon Sep 17 00:00:00 2001 From: Ian Date: Fri, 9 Oct 2020 23:25:31 -0400 Subject: [PATCH 27/43] do auto precompilation after Pkg.dev --- src/API.jl | 2 +- test/api.jl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/API.jl b/src/API.jl index 5ac9f7c959..fe4f4c2be6 100644 --- a/src/API.jl +++ b/src/API.jl @@ -67,7 +67,7 @@ for f in (:develop, :add, :rm, :up, :pin, :free, :test, :build, :status) $f(pkgs::Vector{<:AbstractString}; kwargs...) = $f([PackageSpec(pkg) for pkg in pkgs]; kwargs...) function $f(pkgs::Vector{PackageSpec}; kwargs...) ret = $f(Context(), pkgs; kwargs...) - $(f in (:add, :up, :pin, :free, :build)) && _auto_precompile() + $(f in (:develop, :add, :up, :pin, :free, :build)) && _auto_precompile() return ret end $f(ctx::Context; kwargs...) = $f(ctx, PackageSpec[]; kwargs...) diff --git a/test/api.jl b/test/api.jl index b627e4f27a..d100769a50 100644 --- a/test/api.jl +++ b/test/api.jl @@ -141,11 +141,11 @@ end iob = IOBuffer() Pkg.precompile_auto(true) Pkg.develop(Pkg.PackageSpec(path="packages/Dep4")) - Pkg.precompile(io = iob) + Pkg.precompile(io=iob) @test String(take!(iob)) == "" # test that the previous precompile was a no-op Pkg.precompile_auto(false) Pkg.develop(Pkg.PackageSpec(path="packages/Dep5")) - Pkg.precompile(io = iob) + Pkg.precompile(io=iob) @test String(take!(iob)) != "" # test that the previous precompile did some work end From f226388fc934e61bfc3959389435cb168487fb3e Mon Sep 17 00:00:00 2001 From: Ian Butterworth Date: Sat, 10 Oct 2020 21:56:14 -0400 Subject: [PATCH 28/43] use stderr Co-authored-by: Fredrik Ekre --- src/API.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/API.jl b/src/API.jl index fe4f4c2be6..48625bb987 100644 --- a/src/API.jl +++ b/src/API.jl @@ -919,7 +919,7 @@ function _auto_precompile() end precompile(; kwargs...) = precompile(Context(); kwargs...) -function precompile(ctx::Context; internal_call::Bool=false, io::IO=stdout) +function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) num_tasks = parse(Int, get(ENV, "JULIA_NUM_PRECOMPILE_TASKS", string(Sys.CPU_THREADS + 1))) parallel_limiter = Base.Semaphore(num_tasks) fancy_print = (io isa Base.TTY) && (get(ENV, "CI", nothing) != "true") From 2b5a59f53383aa91bbd84ef74249d2c901ace300 Mon Sep 17 00:00:00 2001 From: Ian Date: Sat, 10 Oct 2020 22:40:55 -0400 Subject: [PATCH 29/43] pass ctx through --- src/API.jl | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/API.jl b/src/API.jl index 48625bb987..be13b47089 100644 --- a/src/API.jl +++ b/src/API.jl @@ -66,8 +66,9 @@ for f in (:develop, :add, :rm, :up, :pin, :free, :test, :build, :status) $f(pkg::Union{AbstractString, PackageSpec}; kwargs...) = $f([pkg]; kwargs...) $f(pkgs::Vector{<:AbstractString}; kwargs...) = $f([PackageSpec(pkg) for pkg in pkgs]; kwargs...) function $f(pkgs::Vector{PackageSpec}; kwargs...) - ret = $f(Context(), pkgs; kwargs...) - $(f in (:develop, :add, :up, :pin, :free, :build)) && _auto_precompile() + ctx = Context() + ret = $f(ctx, pkgs; kwargs...) + $(f in (:develop, :add, :up, :pin, :free, :build)) && _auto_precompile(ctx) return ret end $f(ctx::Context; kwargs...) = $f(ctx, PackageSpec[]; kwargs...) @@ -912,9 +913,9 @@ function precompile_auto(ctx::Context, b::Bool) nothing end -function _auto_precompile() +function _auto_precompile(ctx::Context) if parse(Int, get(ENV, "JULIA_PKG_PRECOMPILE_AUTO", "1")) == 1 - Pkg.precompile(internal_call=true) + Pkg.precompile(ctx, internal_call=true) end end @@ -1168,7 +1169,7 @@ function instantiate(ctx::Context; manifest::Union{Bool, Nothing}=nothing, Operations.download_artifacts(ctx, [dirname(ctx.env.manifest_file)]; platform=platform, verbose=verbose) # check if all source code and artifacts are downloaded to exit early if Operations.is_instantiated(ctx) - _auto_precompile() + _auto_precompile(ctx) return end @@ -1223,7 +1224,7 @@ function instantiate(ctx::Context; manifest::Union{Bool, Nothing}=nothing, # Run build scripts Operations.build_versions(ctx, union(UUID[pkg.uuid for pkg in new_apply], new_git); verbose=verbose) - _auto_precompile() + _auto_precompile(ctx) end From 4c77b50220588489d469a7e5513a27540342e061 Mon Sep 17 00:00:00 2001 From: Ian Date: Sat, 10 Oct 2020 22:41:09 -0400 Subject: [PATCH 30/43] change tip --- src/API.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/API.jl b/src/API.jl index be13b47089..2adce7d782 100644 --- a/src/API.jl +++ b/src/API.jl @@ -927,7 +927,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) # when manually called, unsuspend all packages that were suspended due to precomp errors !internal_call && Operations.precomp_unsuspend!() - action_help = internal_call ? " (tip: control auto with `pkg> precompile_auto true/false`)" : "" + action_help = internal_call ? " (tip: to disable auto set ENV[\"JULIA_PKG_PRECOMPILE_AUTO\"]=0)" : "" direct_deps = [ Base.PkgId(uuid, name) From b307cbd472d052938fc396baa93b3f260b3f7943 Mon Sep 17 00:00:00 2001 From: Ian Date: Sat, 10 Oct 2020 23:22:45 -0400 Subject: [PATCH 31/43] precompile_auto -> autoprecompile --- src/API.jl | 6 +++--- src/Pkg.jl | 6 +++--- src/REPLMode/command_declarations.jl | 6 +++--- test/api.jl | 4 ++-- test/repl.jl | 4 ++-- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/API.jl b/src/API.jl index 2adce7d782..0906e1bafa 100644 --- a/src/API.jl +++ b/src/API.jl @@ -906,9 +906,9 @@ function _is_stale(paths::Vector{String}, sourcepath::String, toml_c::Base.TOMLC return true end -precompile_auto(b::Union{Bool,String}) = precompile_auto(Context(), b) -precompile_auto(ctx::Context, s::String) = precompile_auto(ctx, parse(Bool, s)) -function precompile_auto(ctx::Context, b::Bool) +autoprecompile(b::Union{Bool,String}) = autoprecompile(Context(), b) +autoprecompile(ctx::Context, s::String) = autoprecompile(ctx, parse(Bool, s)) +function autoprecompile(ctx::Context, b::Bool) ENV["JULIA_PKG_PRECOMPILE_AUTO"] = b ? "1" : "0" nothing end diff --git a/src/Pkg.jl b/src/Pkg.jl index c7c3947711..8ae5f9c128 100644 --- a/src/Pkg.jl +++ b/src/Pkg.jl @@ -143,13 +143,13 @@ Pkg.precompile() const precompile = API.precompile """ - Pkg.precompile_auto(b::Bool) + Pkg.autoprecompile(b::Bool) Enable or disable whether Pkg actions will auto-precompile packages, which is enabled by default. -This can also be controlled by setting the environment variable `JULIA_PKG_PRECOMPILE_AUTO` to "1" or "0" +This can also be disabled by setting the environment variable `JULIA_PKG_PRECOMPILE_AUTO` to "0" """ -const precompile_auto = API.precompile_auto +const autoprecompile = API.autoprecompile """ Pkg.rm(pkg::Union{String, Vector{String}}) diff --git a/src/REPLMode/command_declarations.jl b/src/REPLMode/command_declarations.jl index 5b9cd03ea9..5d79b65dc4 100644 --- a/src/REPLMode/command_declarations.jl +++ b/src/REPLMode/command_declarations.jl @@ -312,13 +312,13 @@ Precompile all the dependencies of the project by running `import` on all of the The `startup.jl` file is disabled during precompilation unless julia is started with `--startup-file=yes`. """, ], -PSA[:name => "precompile_auto", - :api => API.precompile_auto, +PSA[:name => "autoprecompile", + :api => API.autoprecompile, :arg_count => 1 => 1, :arg_parser => ((x,y) -> map(expanduser, unwrap(x))), :description => "control whether auto-precompilation is enabled during pkg activities", :help => md""" - precompile_auto + autoprecompile Enable or disable whether Pkg actions will auto-precompile packages, which is enabled by default. This can also be controlled by setting the environment variable `JULIA_PKG_PRECOMPILE_AUTO` to "1" or "0" diff --git a/test/api.jl b/test/api.jl index d100769a50..4a15eb6952 100644 --- a/test/api.jl +++ b/test/api.jl @@ -139,11 +139,11 @@ end Pkg.precompile() iob = IOBuffer() - Pkg.precompile_auto(true) + Pkg.autoprecompile(true) Pkg.develop(Pkg.PackageSpec(path="packages/Dep4")) Pkg.precompile(io=iob) @test String(take!(iob)) == "" # test that the previous precompile was a no-op - Pkg.precompile_auto(false) + Pkg.autoprecompile(false) Pkg.develop(Pkg.PackageSpec(path="packages/Dep5")) Pkg.precompile(io=iob) @test String(take!(iob)) != "" # test that the previous precompile did some work diff --git a/test/repl.jl b/test/repl.jl index 1fbfa55adb..909f67a5a8 100644 --- a/test/repl.jl +++ b/test/repl.jl @@ -160,8 +160,8 @@ temp_pkg_dir() do project_path; cd(project_path) do cp(p1_path, p1_new_path) Pkg.REPLMode.pkgstr("develop $(p1_new_path)") Pkg.REPLMode.pkgstr("build; precompile") - Pkg.REPLMode.pkgstr("precompile_auto true") - Pkg.REPLMode.pkgstr("precompile_auto false") + Pkg.REPLMode.pkgstr("autoprecompile true") + Pkg.REPLMode.pkgstr("autoprecompile false") @test realpath(Base.find_package("UnregisteredWithProject")) == realpath(joinpath(p1_new_path, "src", "UnregisteredWithProject.jl")) @test Pkg.dependencies()[UUID("58262bb0-2073-11e8-3727-4fe182c12249")].version == v"0.1.0" Pkg.test("UnregisteredWithProject") From dab522d3cb5230dd532a77fe6e117e83ee35acc2 Mon Sep 17 00:00:00 2001 From: Ian Date: Sun, 11 Oct 2020 07:44:17 -0400 Subject: [PATCH 32/43] remove autoprecompile control functions --- src/API.jl | 7 ------- src/Pkg.jl | 9 --------- src/REPLMode/command_declarations.jl | 12 ------------ test/api.jl | 4 ++-- test/repl.jl | 2 -- 5 files changed, 2 insertions(+), 32 deletions(-) diff --git a/src/API.jl b/src/API.jl index 0906e1bafa..db7a15e395 100644 --- a/src/API.jl +++ b/src/API.jl @@ -906,13 +906,6 @@ function _is_stale(paths::Vector{String}, sourcepath::String, toml_c::Base.TOMLC return true end -autoprecompile(b::Union{Bool,String}) = autoprecompile(Context(), b) -autoprecompile(ctx::Context, s::String) = autoprecompile(ctx, parse(Bool, s)) -function autoprecompile(ctx::Context, b::Bool) - ENV["JULIA_PKG_PRECOMPILE_AUTO"] = b ? "1" : "0" - nothing -end - function _auto_precompile(ctx::Context) if parse(Int, get(ENV, "JULIA_PKG_PRECOMPILE_AUTO", "1")) == 1 Pkg.precompile(ctx, internal_call=true) diff --git a/src/Pkg.jl b/src/Pkg.jl index 8ae5f9c128..8110346a7a 100644 --- a/src/Pkg.jl +++ b/src/Pkg.jl @@ -142,15 +142,6 @@ Pkg.precompile() """ const precompile = API.precompile -""" - Pkg.autoprecompile(b::Bool) - -Enable or disable whether Pkg actions will auto-precompile packages, which is enabled by default. - -This can also be disabled by setting the environment variable `JULIA_PKG_PRECOMPILE_AUTO` to "0" -""" -const autoprecompile = API.autoprecompile - """ Pkg.rm(pkg::Union{String, Vector{String}}) Pkg.rm(pkg::Union{PackageSpec, Vector{PackageSpec}}) diff --git a/src/REPLMode/command_declarations.jl b/src/REPLMode/command_declarations.jl index 5d79b65dc4..9663237470 100644 --- a/src/REPLMode/command_declarations.jl +++ b/src/REPLMode/command_declarations.jl @@ -312,18 +312,6 @@ Precompile all the dependencies of the project by running `import` on all of the The `startup.jl` file is disabled during precompilation unless julia is started with `--startup-file=yes`. """, ], -PSA[:name => "autoprecompile", - :api => API.autoprecompile, - :arg_count => 1 => 1, - :arg_parser => ((x,y) -> map(expanduser, unwrap(x))), - :description => "control whether auto-precompilation is enabled during pkg activities", - :help => md""" - autoprecompile - -Enable or disable whether Pkg actions will auto-precompile packages, which is enabled by default. -This can also be controlled by setting the environment variable `JULIA_PKG_PRECOMPILE_AUTO` to "1" or "0" -""", -], PSA[:name => "status", :short_name => "st", :api => API.status, diff --git a/test/api.jl b/test/api.jl index 4a15eb6952..83405d2694 100644 --- a/test/api.jl +++ b/test/api.jl @@ -139,11 +139,11 @@ end Pkg.precompile() iob = IOBuffer() - Pkg.autoprecompile(true) + ENV["JULIA_PKG_PRECOMPILE_AUTO"]=1 Pkg.develop(Pkg.PackageSpec(path="packages/Dep4")) Pkg.precompile(io=iob) @test String(take!(iob)) == "" # test that the previous precompile was a no-op - Pkg.autoprecompile(false) + ENV["JULIA_PKG_PRECOMPILE_AUTO"]=0 Pkg.develop(Pkg.PackageSpec(path="packages/Dep5")) Pkg.precompile(io=iob) @test String(take!(iob)) != "" # test that the previous precompile did some work diff --git a/test/repl.jl b/test/repl.jl index 909f67a5a8..de7855bdf7 100644 --- a/test/repl.jl +++ b/test/repl.jl @@ -160,8 +160,6 @@ temp_pkg_dir() do project_path; cd(project_path) do cp(p1_path, p1_new_path) Pkg.REPLMode.pkgstr("develop $(p1_new_path)") Pkg.REPLMode.pkgstr("build; precompile") - Pkg.REPLMode.pkgstr("autoprecompile true") - Pkg.REPLMode.pkgstr("autoprecompile false") @test realpath(Base.find_package("UnregisteredWithProject")) == realpath(joinpath(p1_new_path, "src", "UnregisteredWithProject.jl")) @test Pkg.dependencies()[UUID("58262bb0-2073-11e8-3727-4fe182c12249")].version == v"0.1.0" Pkg.test("UnregisteredWithProject") From ce43ef3f094ddef16e1857562df84a3f2637caa4 Mon Sep 17 00:00:00 2001 From: Ian Date: Sun, 11 Oct 2020 07:58:11 -0400 Subject: [PATCH 33/43] handle plurality properly in message --- src/API.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/API.jl b/src/API.jl index db7a15e395..3205bbe261 100644 --- a/src/API.jl +++ b/src/API.jl @@ -1034,7 +1034,8 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) wait(t) end ndeps = count(values(was_recompiled)) - str = "$(ndeps) dependencies successfully precompiled" + plural = ndeps == 1 ? "y" : "ies" + str = "$(ndeps) dependenc$(plural) successfully precompiled" !isempty(failed_deps) && (str *= ", $(length(failed_deps)) errored") n_already = length(depsmap) - ndeps - length(failed_deps) if n_already > 0 || !isempty(skipped_deps) From cfb4b26b4aaa1660ee718c45921ac70d2399c02a Mon Sep 17 00:00:00 2001 From: Ian Date: Sun, 11 Oct 2020 08:20:17 -0400 Subject: [PATCH 34/43] remove tip --- src/API.jl | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/API.jl b/src/API.jl index 3205bbe261..4a491aa39e 100644 --- a/src/API.jl +++ b/src/API.jl @@ -919,8 +919,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) fancy_print = (io isa Base.TTY) && (get(ENV, "CI", nothing) != "true") # when manually called, unsuspend all packages that were suspended due to precomp errors - !internal_call && Operations.precomp_unsuspend!() - action_help = internal_call ? " (tip: to disable auto set ENV[\"JULIA_PKG_PRECOMPILE_AUTO\"]=0)" : "" + !internal_call && Operations.precomp_unsuspend!() direct_deps = [ Base.PkgId(uuid, name) @@ -988,7 +987,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) wait(first_started) isempty(pkg_queue) && return fancy_print && lock(print_lock) do - printpkgstyle(io, :Precompiling, "project...$action_help") + printpkgstyle(io, :Precompiling, "project...") end t = Timer(0; interval=1/10) anim_chars = ["◐","◓","◑","◒"] From 027e3f52adfd5af9539a1127ae64cfd51a57453e Mon Sep 17 00:00:00 2001 From: Ian Date: Sun, 11 Oct 2020 08:20:44 -0400 Subject: [PATCH 35/43] add auto note to `Pkg.precompile` docs --- src/Pkg.jl | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Pkg.jl b/src/Pkg.jl index 8110346a7a..9a2ccb5af6 100644 --- a/src/Pkg.jl +++ b/src/Pkg.jl @@ -131,6 +131,11 @@ Precompile all the dependencies of the project in parallel. Errors will only throw when precompiling the top-level dependencies, given that not all manifest dependencies may be loaded by the top-level dependencies on the given system. +!!! note + This method is called automatically after any Pkg action that changes the manifest. + Any packages that have previously errored during precompilation won't be retried in auto mode + until they have changed. To disable automatic precompilation set `ENV["JULIA_PKG_PRECOMPILE_AUTO"]=0` + !!! compat "Julia 1.3" This function requires at least Julia 1.3. On earlier versions you can use `Pkg.API.precompile()` or the `precompile` Pkg REPL command. From 62e375adc045ddaaf1c4d4f2d50b50ddce3e7457 Mon Sep 17 00:00:00 2001 From: Ian Date: Sun, 11 Oct 2020 09:59:12 -0400 Subject: [PATCH 36/43] add tip back --- src/API.jl | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/API.jl b/src/API.jl index 4a491aa39e..ce4732e33a 100644 --- a/src/API.jl +++ b/src/API.jl @@ -920,6 +920,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) # when manually called, unsuspend all packages that were suspended due to precomp errors !internal_call && Operations.precomp_unsuspend!() + action_help = internal_call ? " (tip: to disable auto set ENV[\"JULIA_PKG_PRECOMPILE_AUTO\"]=0)" : "" direct_deps = [ Base.PkgId(uuid, name) @@ -987,7 +988,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) wait(first_started) isempty(pkg_queue) && return fancy_print && lock(print_lock) do - printpkgstyle(io, :Precompiling, "project...") + printpkgstyle(io, :Precompiling, "project...$action_help") end t = Timer(0; interval=1/10) anim_chars = ["◐","◓","◑","◒"] From f016b8ca6fda329b4dc89660d711d90ca04f5d0a Mon Sep 17 00:00:00 2001 From: Ian Date: Sun, 11 Oct 2020 10:00:33 -0400 Subject: [PATCH 37/43] remove TOMLCache usage --- src/API.jl | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/src/API.jl b/src/API.jl index ce4732e33a..4c1c975a64 100644 --- a/src/API.jl +++ b/src/API.jl @@ -898,9 +898,9 @@ function build(ctx::Context, pkgs::Vector{PackageSpec}; verbose=false, kwargs... Operations.build(ctx, pkgs, verbose) end -function _is_stale(paths::Vector{String}, sourcepath::String, toml_c::Base.TOMLCache) +function _is_stale(paths::Vector{String}, sourcepath::String) for path_to_try in paths - staledeps = Base.stale_cachefile(sourcepath, path_to_try, toml_c) + staledeps = Base.stale_cachefile(sourcepath, path_to_try) staledeps === true ? continue : return false end return true @@ -1048,10 +1048,9 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) println(io, str, "\n") end end - toml_c = Base.TOMLCache() @sync for (pkg, deps) in depsmap paths = Base.find_all_in_cache_path(pkg) - sourcepath = Base.locate_package(pkg, toml_c) + sourcepath = Base.locate_package(pkg) sourcepath === nothing && continue # Heuristic for when precompilation is disabled if occursin(r"\b__precompile__\(\s*false\s*\)", read(sourcepath, String)) @@ -1067,7 +1066,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) # skip stale checking and force compilation if any dep was recompiled in this session any_dep_recompiled = any(map(dep->was_recompiled[dep], deps)) if !Operations.precomp_suspended(pkg) - if (any_dep_recompiled || _is_stale(paths, sourcepath, toml_c)) + if (any_dep_recompiled || _is_stale(paths, sourcepath)) Base.acquire(parallel_limiter) is_direct_dep = pkg in direct_deps try @@ -1078,7 +1077,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) started[pkg] = true fancy_print && notify(first_started) Logging.with_logger(Logging.NullLogger()) do - Base.compilecache(pkg, sourcepath, toml_c, false) # don't print errors from indirect deps + Base.compilecache(pkg, sourcepath, false) # don't print errors from indirect deps end !fancy_print && lock(print_lock) do str = string(pkg.name, color_string(" ✓", :green)) From af28fb12e8f9fff5aa96024b36a6a651734d9070 Mon Sep 17 00:00:00 2001 From: KristofferC Date: Mon, 12 Oct 2020 00:16:44 +0200 Subject: [PATCH 38/43] fix test after `bytes` field in `SHA1` changed into a tuple --- test/artifacts.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/artifacts.jl b/test/artifacts.jl index 2a8c9203d1..caf727b5ab 100644 --- a/test/artifacts.jl +++ b/test/artifacts.jl @@ -102,7 +102,7 @@ end hash = create_artifact_chmod(creator) # Ensure it hashes to the correct gitsha: - @test hash.bytes == hex2bytes(known_hash) + @test all(hash.bytes .== hex2bytes(known_hash)) # Test that we can look it up and that it sits in the right place @test basename(dirname(artifact_path(hash))) == "artifacts" From cd136cdde458dda77d01a29f93e394e8a2516508 Mon Sep 17 00:00:00 2001 From: Ian Date: Sun, 11 Oct 2020 18:41:21 -0400 Subject: [PATCH 39/43] handle interrupts gracefully --- src/API.jl | 147 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 82 insertions(+), 65 deletions(-) diff --git a/src/API.jl b/src/API.jl index 4c1c975a64..6d052a2e84 100644 --- a/src/API.jl +++ b/src/API.jl @@ -983,69 +983,76 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) ansi_moveup(n::Int) = string("\e[", n, "A") ansi_movecol1 = "\e[1G" ansi_cleartoend = "\e[0J" - + show_report = true + t_print = @async begin - wait(first_started) - isempty(pkg_queue) && return - fancy_print && lock(print_lock) do - printpkgstyle(io, :Precompiling, "project...$action_help") - end - t = Timer(0; interval=1/10) - anim_chars = ["◐","◓","◑","◒"] - i = 1 - last_length = 0 - while !should_exit - lock(print_lock) do - term_size = Base.displaysize(stdout)::Tuple{Int,Int} - num_deps_show = term_size[1] - 2 - pkg_queue_show = if !finished && length(pkg_queue) > num_deps_show - last(pkg_queue, num_deps_show) - else - pkg_queue - end - str = "" - if i > 1 - str *= string(ansi_moveup(last_length), ansi_movecol1, ansi_cleartoend) - end - for dep in pkg_queue_show - finished && was_recompiled[dep] && continue - name = dep in direct_deps ? " $(dep.name)" : string(" ", color_string(dep.name, :light_black)) - if dep in failed_deps - str *= string(name, " ", color_string("✗", Base.error_color()), "\n") - elseif was_recompiled[dep] - str *= string(name, " ", color_string("✓", :green), "\n") - @async begin # keep successful deps visible for short period - sleep(1); - filter!(!isequal(dep), pkg_queue) - end - elseif started[dep] - anim_char = anim_chars[i % length(anim_chars) + 1] - anim_char_colored = dep in direct_deps ? anim_char : color_string(anim_char, :light_black) - str *= string(name, " $anim_char_colored\n") + try + wait(first_started) + isempty(pkg_queue) && return + fancy_print && lock(print_lock) do + printpkgstyle(io, :Precompiling, "project...$action_help") + end + t = Timer(0; interval=1/10) + anim_chars = ["◐","◓","◑","◒"] + i = 1 + last_length = 0 + while !should_exit + lock(print_lock) do + term_size = Base.displaysize(stdout)::Tuple{Int,Int} + num_deps_show = term_size[1] - 2 + pkg_queue_show = if !finished && length(pkg_queue) > num_deps_show + last(pkg_queue, num_deps_show) else - str *= name * "\n" + pkg_queue + end + str = "" + if i > 1 + str *= string(ansi_moveup(last_length), ansi_movecol1, ansi_cleartoend) + end + for dep in pkg_queue_show + finished && was_recompiled[dep] && continue + name = dep in direct_deps ? " $(dep.name)" : string(" ", color_string(dep.name, :light_black)) + if dep in failed_deps + str *= string(name, " ", color_string("✗", Base.error_color()), "\n") + elseif was_recompiled[dep] + str *= string(name, " ", color_string("✓", :green), "\n") + @async begin # keep successful deps visible for short period + sleep(1); + filter!(!isequal(dep), pkg_queue) + end + elseif started[dep] + anim_char = anim_chars[i % length(anim_chars) + 1] + anim_char_colored = dep in direct_deps ? anim_char : color_string(anim_char, :light_black) + str *= string(name, " $anim_char_colored\n") + else + str *= name * "\n" + end end + last_length = length(pkg_queue_show) + print(io, str) end - last_length = length(pkg_queue_show) - print(io, str) + should_exit = finished + i += 1 + wait(t) + end + ndeps = count(values(was_recompiled)) + plural = ndeps == 1 ? "y" : "ies" + str = "$(ndeps) dependenc$(plural) successfully precompiled" + !isempty(failed_deps) && (str *= ", $(length(failed_deps)) errored") + n_already = length(depsmap) - ndeps - length(failed_deps) + if n_already > 0 || !isempty(skipped_deps) + str *= " (" + n_already > 0 && (str *= "$n_already already precompiled") + !isempty(skipped_deps) && (str *= ", $(length(skipped_deps)) skipped in auto mode due to previous errors") + str *= ")" + end + show_report && lock(print_lock) do + println(io, str, "\n") + end + catch err + if err isa InterruptException + should_exit = true end - should_exit = finished - i += 1 - wait(t) - end - ndeps = count(values(was_recompiled)) - plural = ndeps == 1 ? "y" : "ies" - str = "$(ndeps) dependenc$(plural) successfully precompiled" - !isempty(failed_deps) && (str *= ", $(length(failed_deps)) errored") - n_already = length(depsmap) - ndeps - length(failed_deps) - if n_already > 0 || !isempty(skipped_deps) - str *= " (" - n_already > 0 && (str *= "$n_already already precompiled") - !isempty(skipped_deps) && (str *= ", $(length(skipped_deps)) skipped in auto mode due to previous errors") - str *= ")" - end - lock(print_lock) do - println(io, str, "\n") end end @sync for (pkg, deps) in depsmap @@ -1070,12 +1077,16 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) Base.acquire(parallel_limiter) is_direct_dep = pkg in direct_deps try - !fancy_print && lock(print_lock) do - isempty(pkg_queue) && printpkgstyle(io, :Precompiling, "project...$action_help") + !fancy_print && isempty(pkg_queue) && lock(print_lock) do + printpkgstyle(io, :Precompiling, "project...$action_help") end push!(pkg_queue, pkg) started[pkg] = true fancy_print && notify(first_started) + if should_exit + notify(was_processed[pkg]) + return + end Logging.with_logger(Logging.NullLogger()) do Base.compilecache(pkg, sourcepath, false) # don't print errors from indirect deps end @@ -1085,12 +1096,18 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) end was_recompiled[pkg] = true catch err - !fancy_print && lock(print_lock) do - str = string(pkg.name, color_string(" ✗", Base.error_color())) - println(io, " ", is_direct_dep ? str : color_string(str, :light_black))s + if err isa InterruptException + should_exit = true + show_report = false + notify(was_processed[pkg]) + else + !fancy_print && lock(print_lock) do + str = string(pkg.name, color_string(" ✗", Base.error_color())) + println(io, " ", is_direct_dep ? str : color_string(str, :light_black)) + end + Operations.precomp_suspend!(pkg) + push!(failed_deps, pkg) end - Operations.precomp_suspend!(pkg) - push!(failed_deps, pkg) finally Base.release(parallel_limiter) end From e4471b14a1708758d60a09f1d723223dc1b7b87d Mon Sep 17 00:00:00 2001 From: Ian Date: Sun, 11 Oct 2020 20:09:40 -0400 Subject: [PATCH 40/43] try fix CI tests --- src/Pkg.jl | 2 +- test/api.jl | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Pkg.jl b/src/Pkg.jl index 9a2ccb5af6..8f5ce73239 100644 --- a/src/Pkg.jl +++ b/src/Pkg.jl @@ -134,7 +134,7 @@ Precompile all the dependencies of the project in parallel. !!! note This method is called automatically after any Pkg action that changes the manifest. Any packages that have previously errored during precompilation won't be retried in auto mode - until they have changed. To disable automatic precompilation set `ENV["JULIA_PKG_PRECOMPILE_AUTO"]=0` + until they have changed. To disable automatic precompilation set `ENV["JULIA_PKG_PRECOMPILE_AUTO"]="0"` !!! compat "Julia 1.3" This function requires at least Julia 1.3. On earlier versions diff --git a/test/api.jl b/test/api.jl index 83405d2694..be819f0ba6 100644 --- a/test/api.jl +++ b/test/api.jl @@ -139,11 +139,11 @@ end Pkg.precompile() iob = IOBuffer() - ENV["JULIA_PKG_PRECOMPILE_AUTO"]=1 + ENV["JULIA_PKG_PRECOMPILE_AUTO"]="1" Pkg.develop(Pkg.PackageSpec(path="packages/Dep4")) Pkg.precompile(io=iob) @test String(take!(iob)) == "" # test that the previous precompile was a no-op - ENV["JULIA_PKG_PRECOMPILE_AUTO"]=0 + ENV["JULIA_PKG_PRECOMPILE_AUTO"]="0" Pkg.develop(Pkg.PackageSpec(path="packages/Dep5")) Pkg.precompile(io=iob) @test String(take!(iob)) != "" # test that the previous precompile did some work From c66094ad4032272958d99dcc4e78434275449aea Mon Sep 17 00:00:00 2001 From: Ian Date: Sun, 11 Oct 2020 20:45:20 -0400 Subject: [PATCH 41/43] CI debugging --- src/API.jl | 4 ++-- src/Pkg.jl | 2 +- test/api.jl | 6 ++++-- 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/API.jl b/src/API.jl index 6d052a2e84..97e2b17289 100644 --- a/src/API.jl +++ b/src/API.jl @@ -985,7 +985,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) ansi_cleartoend = "\e[0J" show_report = true - t_print = @async begin + t_print = @async begin # fancy print loop try wait(first_started) isempty(pkg_queue) && return @@ -1055,7 +1055,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) end end end - @sync for (pkg, deps) in depsmap + @sync for (pkg, deps) in depsmap # precompilation loop paths = Base.find_all_in_cache_path(pkg) sourcepath = Base.locate_package(pkg) sourcepath === nothing && continue diff --git a/src/Pkg.jl b/src/Pkg.jl index 8f5ce73239..9a2ccb5af6 100644 --- a/src/Pkg.jl +++ b/src/Pkg.jl @@ -134,7 +134,7 @@ Precompile all the dependencies of the project in parallel. !!! note This method is called automatically after any Pkg action that changes the manifest. Any packages that have previously errored during precompilation won't be retried in auto mode - until they have changed. To disable automatic precompilation set `ENV["JULIA_PKG_PRECOMPILE_AUTO"]="0"` + until they have changed. To disable automatic precompilation set `ENV["JULIA_PKG_PRECOMPILE_AUTO"]=0` !!! compat "Julia 1.3" This function requires at least Julia 1.3. On earlier versions diff --git a/test/api.jl b/test/api.jl index be819f0ba6..43a9ff62ad 100644 --- a/test/api.jl +++ b/test/api.jl @@ -139,11 +139,13 @@ end Pkg.precompile() iob = IOBuffer() - ENV["JULIA_PKG_PRECOMPILE_AUTO"]="1" + ENV["JULIA_PKG_PRECOMPILE_AUTO"]=1 + println("Auto precompilation enabled") Pkg.develop(Pkg.PackageSpec(path="packages/Dep4")) Pkg.precompile(io=iob) @test String(take!(iob)) == "" # test that the previous precompile was a no-op - ENV["JULIA_PKG_PRECOMPILE_AUTO"]="0" + ENV["JULIA_PKG_PRECOMPILE_AUTO"]=0 + println("Auto precompilation disabled") Pkg.develop(Pkg.PackageSpec(path="packages/Dep5")) Pkg.precompile(io=iob) @test String(take!(iob)) != "" # test that the previous precompile did some work From 425b14f11a0e3d15eda00dfa447b62c0b7573e15 Mon Sep 17 00:00:00 2001 From: Ian Date: Sun, 11 Oct 2020 22:22:26 -0400 Subject: [PATCH 42/43] fixes --- src/API.jl | 23 +++++++++++++---------- test/runtests.jl | 2 +- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/API.jl b/src/API.jl index 97e2b17289..d9ede61171 100644 --- a/src/API.jl +++ b/src/API.jl @@ -920,7 +920,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) # when manually called, unsuspend all packages that were suspended due to precomp errors !internal_call && Operations.precomp_unsuspend!() - action_help = internal_call ? " (tip: to disable auto set ENV[\"JULIA_PKG_PRECOMPILE_AUTO\"]=0)" : "" + action_help = internal_call ? " (tip: to disable auto-precompilation set ENV[\"JULIA_PKG_PRECOMPILE_AUTO\"]=0)" : "" direct_deps = [ Base.PkgId(uuid, name) @@ -974,6 +974,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) first_started = Base.Event() finished = false should_exit = !fancy_print # exit print loop immediately if not fancy printing + interrupted = false function color_string(str::String, col::Symbol) enable_ansi = get(Base.text_colors, col, Base.text_colors[:default]) @@ -996,7 +997,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) anim_chars = ["◐","◓","◑","◒"] i = 1 last_length = 0 - while !should_exit + while !should_exit && !interrupted lock(print_lock) do term_size = Base.displaysize(stdout)::Tuple{Int,Int} num_deps_show = term_size[1] - 2 @@ -1010,21 +1011,23 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) str *= string(ansi_moveup(last_length), ansi_movecol1, ansi_cleartoend) end for dep in pkg_queue_show - finished && was_recompiled[dep] && continue name = dep in direct_deps ? " $(dep.name)" : string(" ", color_string(dep.name, :light_black)) if dep in failed_deps str *= string(name, " ", color_string("✗", Base.error_color()), "\n") elseif was_recompiled[dep] + finished && continue str *= string(name, " ", color_string("✓", :green), "\n") @async begin # keep successful deps visible for short period sleep(1); filter!(!isequal(dep), pkg_queue) end elseif started[dep] + finished && continue anim_char = anim_chars[i % length(anim_chars) + 1] anim_char_colored = dep in direct_deps ? anim_char : color_string(anim_char, :light_black) str *= string(name, " $anim_char_colored\n") else + finished && continue str *= name * "\n" end end @@ -1051,7 +1054,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) end catch err if err isa InterruptException - should_exit = true + interrupted = true end end end @@ -1072,22 +1075,22 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) # skip stale checking and force compilation if any dep was recompiled in this session any_dep_recompiled = any(map(dep->was_recompiled[dep], deps)) - if !Operations.precomp_suspended(pkg) + if !Operations.precomp_suspended(pkg) if (any_dep_recompiled || _is_stale(paths, sourcepath)) Base.acquire(parallel_limiter) is_direct_dep = pkg in direct_deps try - !fancy_print && isempty(pkg_queue) && lock(print_lock) do - printpkgstyle(io, :Precompiling, "project...$action_help") + !fancy_print && lock(print_lock) do + isempty(pkg_queue) && printpkgstyle(io, :Precompiling, "project...$action_help") end push!(pkg_queue, pkg) started[pkg] = true fancy_print && notify(first_started) - if should_exit + if interrupted notify(was_processed[pkg]) return end - Logging.with_logger(Logging.NullLogger()) do + Logging.with_logger(Logging.NullLogger()) do Base.compilecache(pkg, sourcepath, false) # don't print errors from indirect deps end !fancy_print && lock(print_lock) do @@ -1097,7 +1100,7 @@ function precompile(ctx::Context; internal_call::Bool=false, io::IO=stderr) was_recompiled[pkg] = true catch err if err isa InterruptException - should_exit = true + interrupted = true show_report = false notify(was_processed[pkg]) else diff --git a/test/runtests.jl b/test/runtests.jl index 449883fad3..92bba921fb 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -4,7 +4,7 @@ module PkgTests import Pkg -ENV["JULIA_PKG_PRECOMPILE_AUTO"] = "0" +ENV["JULIA_PKG_PRECOMPILE_AUTO"]=0 if (server = Pkg.pkg_server()) !== nothing && Sys.which("curl") !== nothing s = read(`curl -sLI $(server)`, String); From e68d43c7f95b763865b1655b959001ba2bb2a99e Mon Sep 17 00:00:00 2001 From: Ian Date: Sun, 11 Oct 2020 22:59:14 -0400 Subject: [PATCH 43/43] fix SHA1.bytes check in verify_artifact --- src/Artifacts.jl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Artifacts.jl b/src/Artifacts.jl index e8f05d2dee..d98262d4e8 100644 --- a/src/Artifacts.jl +++ b/src/Artifacts.jl @@ -120,7 +120,7 @@ function verify_artifact(hash::SHA1; honor_overrides::Bool=false) end # Otherwise actually run the verification - return hash.bytes == GitTools.tree_hash(artifact_path(hash)) + return all(hash.bytes .== GitTools.tree_hash(artifact_path(hash))) end """