Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ Pkg v1.13 Release Notes

- Project.toml environments now support a `readonly` field to mark environments as read-only, preventing modifications.
([#4284])
- `Pkg.status` now displays a `○` indicator for packages that are not yet precompiled, helping users identify which
packages will require precompilation on first load. ([#xxxx])
- `Pkg.build` now supports an `allow_reresolve` keyword argument to control whether the build process can re-resolve
package versions, similar to the existing option for `Pkg.test`. ([#3329])
- Packages are now automatically added to `[sources]` when they are added by url or devved. ([#4225])
Expand Down
20 changes: 18 additions & 2 deletions src/Operations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2911,6 +2911,7 @@ struct PackageStatusData
downloaded::Bool
upgradable::Bool
heldback::Bool
precompiled::Bool
compat_data::Union{Nothing, Tuple{Vector{String}, VersionNumber, VersionNumber}}
changed::Bool
extinfo::Union{Nothing, Vector{ExtInfo}}
Expand All @@ -2924,6 +2925,7 @@ function print_status(
not_installed_indicator = sprint((io, args) -> printstyled(io, args...; color = Base.error_color()), "→", context = io)
upgradable_indicator = sprint((io, args) -> printstyled(io, args...; color = :green), "⌃", context = io)
heldback_indicator = sprint((io, args) -> printstyled(io, args...; color = Base.warn_color()), "⌅", context = io)
not_precompiled_indicator = sprint((io, args) -> printstyled(io, args...; color = :light_black), "○", context = io)
filter = !isempty(uuids) || !isempty(names)
# setup
xs = diff_array(old_env, env; manifest, workspace)
Expand Down Expand Up @@ -2968,6 +2970,7 @@ function print_status(
no_packages_upgradable = true
no_visible_packages_heldback = true
no_packages_heldback = true
all_packages_precompiled = true
lpadding = 2

package_statuses = PackageStatusData[]
Expand Down Expand Up @@ -3011,16 +3014,24 @@ function print_status(
pkg_upgradable = new_ver_avail && cinfo !== nothing && isempty(cinfo[1])
pkg_heldback = new_ver_avail && cinfo !== nothing && !isempty(cinfo[1])

if !pkg_downloaded && (pkg_upgradable || pkg_heldback)
# Check precompilation status
pkg_precompiled = false
if pkg_downloaded && !isnothing(new)
pkgid = Base.PkgId(uuid, new.name)
pkg_precompiled = Base.isprecompiled(pkgid)
end

if (!pkg_downloaded || (pkg_downloaded && !pkg_precompiled)) && (pkg_upgradable || pkg_heldback)
# allow space in the gutter for two icons on a single line
lpadding = 3
end
all_packages_downloaded &= (!changed || pkg_downloaded)
no_packages_upgradable &= (!changed || !pkg_upgradable)
no_visible_packages_heldback &= (!changed || !pkg_heldback)
no_packages_heldback &= !pkg_heldback
all_packages_precompiled &= (!changed || pkg_precompiled)

push!(package_statuses, PackageStatusData(uuid, old, new, pkg_downloaded, pkg_upgradable, pkg_heldback, cinfo, changed, ext_info))
push!(package_statuses, PackageStatusData(uuid, old, new, pkg_downloaded, pkg_upgradable, pkg_heldback, pkg_precompiled, cinfo, changed, ext_info))
end

for pkg in package_statuses
Expand All @@ -3029,6 +3040,8 @@ function print_status(

if !pkg.downloaded
print_padding(not_installed_indicator)
elseif pkg.downloaded && !pkg.precompiled
print_padding(not_precompiled_indicator)
elseif lpadding > 2
print_padding(" ")
end
Expand Down Expand Up @@ -3115,6 +3128,9 @@ function print_status(
if !no_changes && !all_packages_downloaded
printpkgstyle(io, :Info, "Packages marked with $not_installed_indicator are not downloaded, use `instantiate` to download", color = Base.info_color(), ignore_indent)
end
if !no_changes && !all_packages_precompiled
printpkgstyle(io, :Info, "Packages marked with $not_precompiled_indicator are not precompiled.", color = Base.info_color(), ignore_indent)
end
if !outdated && (mode != PKGMODE_COMBINED || (manifest == true))
tipend = manifest ? " -m" : ""
tip = show_usagetips ? " To see why use `status --outdated$tipend`" : ""
Expand Down
1 change: 1 addition & 0 deletions src/Pkg.jl
Original file line number Diff line number Diff line change
Expand Up @@ -625,6 +625,7 @@ Print out the status of the project/manifest.
Packages marked with `⌃` have new versions that can be installed, e.g. via [`Pkg.update`](@ref).
Those marked with `⌅` have new versions available, but cannot be installed due to compatibility conflicts with other packages. To see why, set the
keyword argument `outdated=true`.
Packages marked with `○` are not precompiled yet.
Packages marked with `[yanked]` are yanked versions that should be updated or replaced as they may contain bugs or security vulnerabilities.

Setting `outdated=true` will only show packages that are not on the latest version,
Expand Down
1 change: 1 addition & 0 deletions src/REPLMode/command_declarations.jl
Original file line number Diff line number Diff line change
Expand Up @@ -454,6 +454,7 @@ compound_declarations = [
new versions available, but cannot be installed due to compatibility
constraints. To see why use `pkg> status --outdated` which shows any packages
that are not at their latest version and if any packages are holding them back.
Packages marked with `○` are not precompiled yet and can be precompiled via `pkg> precompile`.
Packages marked with `[yanked]` have been yanked from the registry and should be
updated or removed.

Expand Down
19 changes: 11 additions & 8 deletions test/new.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2904,23 +2904,26 @@ end
io = PipeBuffer()
Pkg.status(; io = io)
@test occursin(r"Status `.+Project.toml`", readline(io))
@test occursin(r"^→⌃ \[7876af07\] Example\s*v\d\.\d\.\d", readline(io))
@test occursin(r"^ \[d6f4376e\] Markdown", readline(io))
@test occursin(r"^→⌃ \[7876af07\] Example\s*v\d\.\d\.\d", readline(io))
@test occursin(r"^ \[d6f4376e\] Markdown", readline(io))
@test "Info Packages marked with → are not downloaded, use `instantiate` to download" == strip(readline(io))
@test "Info Packages marked with ○ are not precompiled." == strip(readline(io))
@test "Info Packages marked with ⌃ have new versions available and may be upgradable." == strip(readline(io))
Pkg.status(; io = io, mode = Pkg.PKGMODE_MANIFEST)
@test occursin(r"Status `.+Manifest.toml`", readline(io))
@test occursin(r"^→⌃ \[7876af07\] Example\s*v\d\.\d\.\d", readline(io))
@test occursin(r"^ \[2a0f44e3\] Base64", readline(io))
@test occursin(r"^ \[d6f4376e\] Markdown", readline(io))
@test occursin(r"^→⌃ \[7876af07\] Example\s*v\d\.\d\.\d", readline(io))
@test occursin(r"^ \[2a0f44e3\] Base64", readline(io))
@test occursin(r"^ \[d6f4376e\] Markdown", readline(io))
@test "Info Packages marked with → are not downloaded, use `instantiate` to download" == strip(readline(io))
@test "Info Packages marked with ○ are not precompiled." == strip(readline(io))
@test "Info Packages marked with ⌃ have new versions available and may be upgradable." == strip(readline(io))
Pkg.instantiate(; io = devnull) # download Example
Pkg.status(; io = io, mode = Pkg.PKGMODE_MANIFEST)
@test occursin(r"Status `.+Manifest.toml`", readline(io))
@test occursin(r"^⌃ \[7876af07\] Example\s*v\d\.\d\.\d", readline(io))
@test occursin(r"^ \[2a0f44e3\] Base64", readline(io))
@test occursin(r"^ \[d6f4376e\] Markdown", readline(io))
@test occursin(r"○^⌃ \[7876af07\] Example\s*v\d\.\d\.\d", readline(io))
@test occursin(r"○^ \[2a0f44e3\] Base64", readline(io))
@test occursin(r"○^ \[d6f4376e\] Markdown", readline(io))
@test "Info Packages marked with ○ are not precompiled." == strip(readline(io))
@test "Info Packages marked with ⌃ have new versions available and may be upgradable." == strip(readline(io))
end
# Manifest Status API
Expand Down
Loading