Skip to content

Commit a0c774c

Browse files
committed
allow for a deprecated table in a Package.toml in a registry
these packages will not tab complete to and will show up as deprecated in pkg status Fixes #2194
1 parent a1818b9 commit a0c774c

File tree

4 files changed

+98
-3
lines changed

4 files changed

+98
-3
lines changed

ext/REPLExt/completions.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ function complete_remote_package!(comps, partial; hint::Bool)
7979
name in cmp && continue
8080
if startswith(regpkg.name, partial)
8181
pkg = Registry.registry_info(regpkg)
82+
Registry.isdeprecated(pkg) && continue
8283
compat_info = Registry.compat_info(pkg)
8384
# Filter versions
8485
for (v, uncompressed_compat) in compat_info

src/Operations.jl

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +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
55+
for reg in registries
56+
reg_pkg = get(reg, pkg.uuid, nothing)
57+
if reg_pkg !== nothing
58+
info = Registry.registry_info(reg_pkg)
59+
Registry.isdeprecated(info) && return true
60+
end
61+
end
62+
return false
63+
end
64+
5365
function default_preserve()
5466
return if Base.get_bool_env("JULIA_PKG_PRESERVE_TIERED_INSTALLED", false)
5567
PRESERVE_TIERED_INSTALLED
@@ -3054,6 +3066,11 @@ function print_status(
30543066
printstyled(io, " [yanked]"; color = :yellow)
30553067
end
30563068

3069+
# show if package is deprecated
3070+
if is_pkg_deprecated(pkg_spec, registries)
3071+
printstyled(io, " [deprecated]"; color = :yellow)
3072+
end
3073+
30573074
if outdated && !diff && pkg.compat_data !== nothing
30583075
packages_holding_back, max_version, max_version_compat = pkg.compat_data
30593076
if pkg.new.version !== max_version_compat && max_version_compat != max_version

src/Registry/registry_instance.jl

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,9 @@ struct PkgInfo
4848
repo::Union{String, Nothing}
4949
subdir::Union{String, Nothing}
5050

51+
# Package.toml [deprecated]:
52+
deprecated::Union{Dict{String, Any}, Nothing}
53+
5154
# Versions.toml:
5255
version_info::Dict{VersionNumber, VersionInfo}
5356

@@ -68,6 +71,7 @@ end
6871

6972
isyanked(pkg::PkgInfo, v::VersionNumber) = pkg.version_info[v].yanked
7073
treehash(pkg::PkgInfo, v::VersionNumber) = pkg.version_info[v].git_tree_sha1
74+
isdeprecated(pkg::PkgInfo) = pkg.deprecated !== nothing
7175

7276
function uncompress(compressed::Dict{VersionRange, Dict{String, T}}, vsorted::Vector{VersionNumber}) where {T}
7377
@assert issorted(vsorted)
@@ -201,6 +205,10 @@ function init_package_info!(pkg::PkgEntry)
201205
repo = get(d_p, "repo", nothing)::Union{Nothing, String}
202206
subdir = get(d_p, "subdir", nothing)::Union{Nothing, String}
203207

208+
# The presence of a [deprecated] table indicates the package is deprecated
209+
# We store the raw table to allow other tools to use the metadata
210+
deprecated = get(d_p, "deprecated", nothing)::Union{Nothing, Dict{String, Any}}
211+
204212
# Versions.toml
205213
d_v = custom_isfile(pkg.in_memory_registry, pkg.registry_path, joinpath(pkg.path, "Versions.toml")) ?
206214
parsefile(pkg.in_memory_registry, pkg.registry_path, joinpath(pkg.path, "Versions.toml")) : Dict{String, Any}()
@@ -256,7 +264,7 @@ function init_package_info!(pkg::PkgEntry)
256264
end
257265

258266
@assert !isdefined(pkg, :info)
259-
pkg.info = PkgInfo(repo, subdir, version_info, compat, deps, weak_compat, weak_deps, pkg.info_lock)
267+
pkg.info = PkgInfo(repo, subdir, deprecated, version_info, compat, deps, weak_compat, weak_deps, pkg.info_lock)
260268

261269
return pkg.info
262270
end

test/registry.jl

Lines changed: 71 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,8 +41,6 @@ function setup_test_registries(dir = pwd())
4141
)
4242
write(
4343
joinpath(regpath, "Example", "Deps.toml"), """
44-
["0.5"]
45-
julia = "0.6-1.0"
4644
"""
4745
)
4846
write(
@@ -343,6 +341,77 @@ end
343341
end
344342
end
345343

344+
@testset "deprecated package" begin
345+
temp_pkg_dir() do depot
346+
# Set up test registries with an extra deprecated package
347+
regdir = mktempdir()
348+
setup_test_registries(regdir)
349+
350+
# Add a deprecated package to the first registry
351+
regpath = joinpath(regdir, "RegistryFoo1")
352+
mkpath(joinpath(regpath, "DeprecatedExample"))
353+
354+
# Add the deprecated package to Registry.toml
355+
registry_toml = read(joinpath(regpath, "Registry.toml"), String)
356+
registry_toml = replace(
357+
registry_toml,
358+
"[packages]" =>
359+
"[packages]\n11111111-1111-1111-1111-111111111111 = { name = \"DeprecatedExample\", path = \"DeprecatedExample\" }"
360+
)
361+
write(joinpath(regpath, "Registry.toml"), registry_toml)
362+
363+
# Create deprecated package with [deprecated] table
364+
write(
365+
joinpath(regpath, "DeprecatedExample", "Package.toml"), """
366+
name = "DeprecatedExample"
367+
uuid = "11111111-1111-1111-1111-111111111111"
368+
repo = "https://github.com/test/DeprecatedExample.jl.git"
369+
370+
[deprecated]
371+
reason = "This package is no longer maintained"
372+
alternative = "Example"
373+
"""
374+
)
375+
376+
write(
377+
joinpath(regpath, "DeprecatedExample", "Versions.toml"), """
378+
["1.0.0"]
379+
git-tree-sha1 = "1234567890abcdef1234567890abcdef12345678"
380+
"""
381+
)
382+
383+
git_init_and_commit(regpath)
384+
385+
# Add the test registry
386+
Pkg.Registry.add(url = regpath)
387+
388+
# Test that the package is marked as deprecated
389+
registries = Pkg.Registry.reachable_registries()
390+
reg_idx = findfirst(r -> r.name == "RegistryFoo", registries)
391+
@test reg_idx !== nothing
392+
393+
reg = registries[reg_idx]
394+
pkg_uuid = UUID("11111111-1111-1111-1111-111111111111")
395+
@test haskey(reg, pkg_uuid)
396+
397+
pkg_entry = reg[pkg_uuid]
398+
pkg_info = Pkg.Registry.registry_info(pkg_entry)
399+
400+
# Test that deprecated info is loaded correctly
401+
@test Pkg.Registry.isdeprecated(pkg_info)
402+
@test pkg_info.deprecated !== nothing
403+
@test pkg_info.deprecated["reason"] == "This package is no longer maintained"
404+
@test pkg_info.deprecated["alternative"] == "Example"
405+
406+
# Test that non-deprecated package is not marked as deprecated
407+
example1_uuid = UUID("c5f1542f-b8aa-45da-ab42-05303d706c66")
408+
example1_entry = reg[example1_uuid]
409+
example1_info = Pkg.Registry.registry_info(example1_entry)
410+
@test !Pkg.Registry.isdeprecated(example1_info)
411+
@test example1_info.deprecated === nothing
412+
end
413+
end
414+
346415
@testset "yanking" begin
347416
uuid = Base.UUID("7876af07-990d-54b4-ab0e-23690620f79a") # Example
348417
# Tests that [email protected] does not get installed

0 commit comments

Comments
 (0)