Skip to content

Commit adb19f3

Browse files
committed
show more deprecated info in status
1 parent 595ffee commit adb19f3

File tree

5 files changed

+79
-18
lines changed

5 files changed

+79
-18
lines changed

docs/src/registries.md

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,11 @@ One use of the `[metadata]` table is to mark packages as deprecated using `[meta
114114
- Be excluded from tab-completion suggestions
115115
- Still be installable and usable
116116

117-
The `[metadata.deprecated]` table can contain arbitrary metadata fields. Common fields include:
117+
The `[metadata.deprecated]` table can contain arbitrary metadata fields. Two special fields are recognized by Pkg and displayed when using `pkg> status --deprecated`:
118+
- `reason`: A string explaining why the package is deprecated
119+
- `alternative`: A string suggesting a replacement package
120+
121+
Example:
118122

119123
```toml
120124
name = "MyPackage"
@@ -126,7 +130,7 @@ reason = "This package is no longer maintained"
126130
alternative = "ReplacementPackage"
127131
```
128132

129-
The specific fields within `[metadata.deprecated]` are not currently used by Pkg itself, but are stored to allow other tools and registries to utilize this metadata.
133+
Other fields can be added to `[metadata.deprecated]` for use by registries or other tools.
130134

131135
### Registry Compat.toml
132136

src/API.jl

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1314,14 +1314,15 @@ end
13141314

13151315
@deprecate status(mode::PackageMode) status(mode = mode)
13161316

1317-
function status(ctx::Context, pkgs::Vector{PackageSpec}; diff::Bool = false, mode = PKGMODE_PROJECT, workspace::Bool = false, outdated::Bool = false, compat::Bool = false, extensions::Bool = false, io::IO = stdout_f())
1317+
function status(ctx::Context, pkgs::Vector{PackageSpec}; diff::Bool = false, mode = PKGMODE_PROJECT, workspace::Bool = false, outdated::Bool = false, deprecated::Bool = false, compat::Bool = false, extensions::Bool = false, io::IO = stdout_f())
13181318
if compat
13191319
diff && pkgerror("Compat status has no `diff` mode")
13201320
outdated && pkgerror("Compat status has no `outdated` mode")
1321+
deprecated && pkgerror("Compat status has no `deprecated` mode")
13211322
extensions && pkgerror("Compat status has no `extensions` mode")
13221323
Operations.print_compat(ctx, pkgs; io)
13231324
else
1324-
Operations.status(ctx.env, ctx.registries, pkgs; mode, git_diff = diff, io, outdated, extensions, workspace)
1325+
Operations.status(ctx.env, ctx.registries, pkgs; mode, git_diff = diff, io, outdated, deprecated, extensions, workspace)
13251326
end
13261327
return nothing
13271328
end

src/Operations.jl

Lines changed: 49 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,16 +50,18 @@ function is_pkgversion_yanked(entry::PackageEntry, registries::Vector{Registry.R
5050
return is_pkgversion_yanked(entry.uuid, entry.version, registries)
5151
end
5252

53-
function is_pkg_deprecated(pkg::Union{PackageSpec, PackageEntry}, registries::Vector{Registry.RegistryInstance} = Registry.reachable_registries())
54-
pkg.uuid === nothing && return false
53+
function get_pkg_deprecation_info(pkg::Union{PackageSpec, PackageEntry}, registries::Vector{Registry.RegistryInstance} = Registry.reachable_registries())
54+
pkg.uuid === nothing && return nothing
5555
for reg in registries
5656
reg_pkg = get(reg, pkg.uuid, nothing)
5757
if reg_pkg !== nothing
5858
info = Registry.registry_info(reg_pkg)
59-
Registry.isdeprecated(info) && return true
59+
if Registry.isdeprecated(info)
60+
return info.deprecated
61+
end
6062
end
6163
end
62-
return false
64+
return nothing
6365
end
6466

6567
function default_preserve()
@@ -2927,11 +2929,12 @@ struct PackageStatusData
29272929
compat_data::Union{Nothing, Tuple{Vector{String}, VersionNumber, VersionNumber}}
29282930
changed::Bool
29292931
extinfo::Union{Nothing, Vector{ExtInfo}}
2932+
deprecation_info::Union{Nothing, Dict{String, Any}}
29302933
end
29312934

29322935
function print_status(
29332936
env::EnvCache, old_env::Union{Nothing, EnvCache}, registries::Vector{Registry.RegistryInstance}, header::Symbol,
2934-
uuids::Vector, names::Vector; manifest = true, diff = false, ignore_indent::Bool, workspace::Bool, outdated::Bool, extensions::Bool, io::IO,
2937+
uuids::Vector, names::Vector; manifest = true, diff = false, ignore_indent::Bool, workspace::Bool, outdated::Bool, deprecated::Bool, extensions::Bool, io::IO,
29352938
mode::PackageMode, hidden_upgrades_info::Bool, show_usagetips::Bool = true
29362939
)
29372940
not_installed_indicator = sprint((io, args) -> printstyled(io, args...; color = Base.error_color()), "", context = io)
@@ -3015,6 +3018,19 @@ function print_status(
30153018
continue
30163019
end
30173020

3021+
# Deprecated info
3022+
deprecation_info = nothing
3023+
pkg_deprecated = false
3024+
if !isnothing(new)
3025+
pkg_spec = something(new, old)
3026+
deprecation_info = get_pkg_deprecation_info(pkg_spec, registries)
3027+
pkg_deprecated = deprecation_info !== nothing
3028+
end
3029+
3030+
# if we are running with deprecated, only show packages that are deprecated
3031+
if deprecated && !pkg_deprecated
3032+
continue
3033+
end
30183034

30193035
# TODO: Show extension deps for project as well?
30203036

@@ -3033,7 +3049,7 @@ function print_status(
30333049
no_visible_packages_heldback &= (!changed || !pkg_heldback)
30343050
no_packages_heldback &= !pkg_heldback
30353051

3036-
push!(package_statuses, PackageStatusData(uuid, old, new, pkg_downloaded, pkg_upgradable, pkg_heldback, cinfo, changed, ext_info))
3052+
push!(package_statuses, PackageStatusData(uuid, old, new, pkg_downloaded, pkg_upgradable, pkg_heldback, cinfo, changed, ext_info, deprecation_info))
30373053
end
30383054

30393055
for pkg in package_statuses
@@ -3067,10 +3083,22 @@ function print_status(
30673083
end
30683084

30693085
# show if package is deprecated
3070-
if is_pkg_deprecated(pkg_spec, registries)
3086+
if pkg.deprecation_info !== nothing
30713087
printstyled(io, " [deprecated]"; color = :yellow)
30723088
end
30733089

3090+
# show deprecation details when using --deprecated flag
3091+
if deprecated && !diff && pkg.deprecation_info !== nothing
3092+
reason = get(pkg.deprecation_info, "reason", nothing)
3093+
alternative = get(pkg.deprecation_info, "alternative", nothing)
3094+
if reason !== nothing
3095+
printstyled(io, " (reason: ", reason, ")"; color = :yellow)
3096+
end
3097+
if alternative !== nothing
3098+
printstyled(io, " (alternative: ", alternative, ")"; color = :yellow)
3099+
end
3100+
end
3101+
30743102
if outdated && !diff && pkg.compat_data !== nothing
30753103
packages_holding_back, max_version, max_version_compat = pkg.compat_data
30763104
if pkg.new.version !== max_version_compat && max_version_compat != max_version
@@ -3161,6 +3189,17 @@ function print_status(
31613189
It is recommended to update them to resolve a valid version.""", color = Base.warn_color(), ignore_indent)
31623190
end
31633191

3192+
# Check if any packages are deprecated for info message
3193+
any_deprecated_packages = any(pkg -> pkg.deprecation_info !== nothing, package_statuses)
3194+
3195+
# Add info for deprecated packages (only if not already in deprecated mode)
3196+
if !deprecated && any_deprecated_packages
3197+
deprecated_str = sprint((io, args) -> printstyled(io, args...; color = :yellow), "[deprecated]", context = io)
3198+
tipend = manifest ? " -m" : ""
3199+
tip = show_usagetips ? " Use `status --deprecated$tipend` to see more information." : ""
3200+
printpkgstyle(io, :Info, """Packages marked with $deprecated_str are no longer maintained.$tip""", color = Base.info_color(), ignore_indent)
3201+
end
3202+
31643203
return nothing
31653204
end
31663205

@@ -3192,7 +3231,7 @@ end
31923231
function status(
31933232
env::EnvCache, registries::Vector{Registry.RegistryInstance}, pkgs::Vector{PackageSpec} = PackageSpec[];
31943233
header = nothing, mode::PackageMode = PKGMODE_PROJECT, git_diff::Bool = false, env_diff = nothing, ignore_indent = true,
3195-
io::IO, workspace::Bool = false, outdated::Bool = false, extensions::Bool = false, hidden_upgrades_info::Bool = false, show_usagetips::Bool = true
3234+
io::IO, workspace::Bool = false, outdated::Bool = false, deprecated::Bool = false, extensions::Bool = false, hidden_upgrades_info::Bool = false, show_usagetips::Bool = true
31963235
)
31973236
io == Base.devnull && return
31983237
# if a package, print header
@@ -3223,10 +3262,10 @@ function status(
32233262
diff = old_env !== nothing
32243263
header = something(header, diff ? :Diff : :Status)
32253264
if mode == PKGMODE_PROJECT || mode == PKGMODE_COMBINED
3226-
print_status(env, old_env, registries, header, filter_uuids, filter_names; manifest = false, diff, ignore_indent, io, workspace, outdated, extensions, mode, hidden_upgrades_info, show_usagetips)
3265+
print_status(env, old_env, registries, header, filter_uuids, filter_names; manifest = false, diff, ignore_indent, io, workspace, outdated, deprecated, extensions, mode, hidden_upgrades_info, show_usagetips)
32273266
end
32283267
if mode == PKGMODE_MANIFEST || mode == PKGMODE_COMBINED
3229-
print_status(env, old_env, registries, header, filter_uuids, filter_names; diff, ignore_indent, io, workspace, outdated, extensions, mode, hidden_upgrades_info, show_usagetips)
3268+
print_status(env, old_env, registries, header, filter_uuids, filter_names; diff, ignore_indent, io, workspace, outdated, deprecated, extensions, mode, hidden_upgrades_info, show_usagetips)
32303269
end
32313270
return if is_manifest_current(env) === false
32323271
tip = if show_usagetips

src/REPLMode/command_declarations.jl

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -435,16 +435,17 @@ compound_declarations = [
435435
PSA[:name => "manifest", :short_name => "m", :api => :mode => PKGMODE_MANIFEST],
436436
PSA[:name => "diff", :short_name => "d", :api => :diff => true],
437437
PSA[:name => "outdated", :short_name => "o", :api => :outdated => true],
438+
PSA[:name => "deprecated", :api => :deprecated => true],
438439
PSA[:name => "compat", :short_name => "c", :api => :compat => true],
439440
PSA[:name => "extensions", :short_name => "e", :api => :extensions => true],
440441
PSA[:name => "workspace", :api => :workspace => true],
441442
],
442443
:completions => :complete_installed_packages,
443444
:description => "summarize contents of and changes to environment",
444445
:help => md"""
445-
[st|status] [-d|--diff] [--workspace] [-o|--outdated] [pkgs...]
446-
[st|status] [-d|--diff] [--workspace] [-o|--outdated] [-p|--project] [pkgs...]
447-
[st|status] [-d|--diff] [--workspace] [-o|--outdated] [-m|--manifest] [pkgs...]
446+
[st|status] [-d|--diff] [--workspace] [-o|--outdated] [--deprecated] [pkgs...]
447+
[st|status] [-d|--diff] [--workspace] [-o|--outdated] [--deprecated] [-p|--project] [pkgs...]
448+
[st|status] [-d|--diff] [--workspace] [-o|--outdated] [--deprecated] [-m|--manifest] [pkgs...]
448449
[st|status] [-d|--diff] [--workspace] [-e|--extensions] [-p|--project] [pkgs...]
449450
[st|status] [-d|--diff] [--workspace] [-e|--extensions] [-m|--manifest] [pkgs...]
450451
[st|status] [-c|--compat] [pkgs...]
@@ -455,7 +456,10 @@ compound_declarations = [
455456
constraints. To see why use `pkg> status --outdated` which shows any packages
456457
that are not at their latest version and if any packages are holding them back.
457458
Packages marked with `[yanked]` have been yanked from the registry and should be
458-
updated or removed.
459+
updated or removed. Packages marked with `[deprecated]` are no longer maintained.
460+
461+
Use `pkg> status --deprecated` to show only deprecated packages along with deprecation
462+
information such as the reason and alternative packages (if provided by the registry).
459463
460464
Use `pkg> status --extensions` to show dependencies with extensions and what extension dependencies
461465
of those that are currently loaded.

test/registry.jl

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -409,6 +409,19 @@ end
409409
example1_info = Pkg.Registry.registry_info(example1_entry)
410410
@test !Pkg.Registry.isdeprecated(example1_info)
411411
@test example1_info.deprecated === nothing
412+
413+
# Test get_pkg_deprecation_info function
414+
using Pkg.Operations: get_pkg_deprecation_info
415+
deprecated_pkg_spec = Pkg.Types.PackageSpec(name = "DeprecatedExample", uuid = pkg_uuid)
416+
normal_pkg_spec = Pkg.Types.PackageSpec(name = "Example1", uuid = example1_uuid)
417+
418+
dep_info = get_pkg_deprecation_info(deprecated_pkg_spec, registries)
419+
@test dep_info !== nothing
420+
@test dep_info["reason"] == "This package is no longer maintained"
421+
@test dep_info["alternative"] == "Example"
422+
423+
normal_info = get_pkg_deprecation_info(normal_pkg_spec, registries)
424+
@test normal_info === nothing
412425
end
413426
end
414427

0 commit comments

Comments
 (0)