Skip to content

Commit

Permalink
Use the Pkg.Registry API
Browse files Browse the repository at this point in the history
As of Julia 1.7, Pkg.Registry provides some of the same capability
implemented in this package. When `VERSION` is at least v1.7, we use
`Pkg.Registry.reachable_registries`, `Pkg.Registry.RegistryInstance`,
and `Pkg.Registry.PkgEntry` instead of the custom versions implemented
in this package. For lower version numbers, we use the custom versions
implemented in this package.

The largest change when using the new capabilities in Pkg.Registry is
that this package's version of `RegistryInstance` stored a dictionary
mapping package names to `PkgEntry`s, but Pkg.Registry's version has a
dictionary mapping `UUID`s to `PkgEntry`s.

A benefit of using the `Pkg.Registry` API is that it already supports
both uncompressed registries as well as registries stored in
compressed tarballs. Thus, this fixes #37.
  • Loading branch information
danielmatz committed Jun 23, 2022
1 parent a568954 commit 59473f4
Show file tree
Hide file tree
Showing 3 changed files with 67 additions and 36 deletions.
55 changes: 36 additions & 19 deletions src/PkgDeps.jl
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,13 @@ export NoUUIDMatch, PackageNotInRegistry
export users, reachable_registries
export direct_dependencies, dependencies

include("pkg_entry.jl")
include("registry_instance.jl")
@static if VERSION >= v"1.7"
using Pkg.Registry: RegistryInstance, PkgEntry
else
include("pkg_entry.jl")
include("registry_instance.jl")
end

include("exceptions.jl")
include("utilities.jl")

Expand Down Expand Up @@ -45,27 +50,39 @@ function reachable_registries(
depots::Union{String, Vector{String}}=Base.DEPOT_PATH,
kwargs...
)
registries = RegistryInstance[]
@static if VERSION >= v"1.7"
all_registries = Pkg.Registry.reachable_registries(; depots)

if depots isa String
depots = [depots]
end
registries = if isempty(registry_names)
all_registries
else
[r for r in all_registries if r.name in registry_names]
end

for d in depots
isdir(d) || continue
reg_dir = joinpath(d, "registries")
isdir(reg_dir) || continue
return registries
else
registries = RegistryInstance[]

for name in readdir(reg_dir)
if isempty(registry_names) || name in registry_names
file = joinpath(reg_dir, name, "Registry.toml")
isfile(file) || continue
push!(registries, RegistryInstance(joinpath(reg_dir, name)))
if depots isa String
depots = [depots]
end

for d in depots
isdir(d) || continue
reg_dir = joinpath(d, "registries")
isdir(reg_dir) || continue

for name in readdir(reg_dir)
if isempty(registry_names) || name in registry_names
file = joinpath(reg_dir, name, "Registry.toml")
isfile(file) || continue
push!(registries, RegistryInstance(joinpath(reg_dir, name)))
end
end
end
end

return registries
return registries
end
end
reachable_registries(registry_name::String; depots::Union{String, Vector{String}}=Base.DEPOT_PATH, kwargs...) = reachable_registries([registry_name]; depots=depots, kwargs...)
reachable_registries(; depots::Union{String, Vector{String}}=Base.DEPOT_PATH, kwargs...) = reachable_registries([]; depots=depots, kwargs...)
Expand Down Expand Up @@ -97,10 +114,10 @@ function users(
downstream_dependencies = String[]

for rego in registries
for (pkg, pkg_entry) in rego.pkgs
for pkg_entry in values(rego.pkgs)
deps = direct_dependencies(pkg_entry)
if any(isequal(uuid), values(deps))
push!(downstream_dependencies, pkg)
push!(downstream_dependencies, pkg_entry.name)
end
end
end
Expand Down
32 changes: 17 additions & 15 deletions src/utilities.jl
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,9 @@ function _find_latest_pkg_entry(pkg_name::Union{AbstractString, Missing}, pkg_uu
entries = PkgEntry[]

for rego in registries
for (name, entry) in rego.pkgs
for entry in values(rego.pkgs)
if !ismissing(pkg_name)
pkg_name == name || continue
pkg_name == entry.name || continue
end
if !ismissing(pkg_uuid)
pkg_uuid == entry.uuid || continue
Expand Down Expand Up @@ -74,9 +74,9 @@ Get the package name from a UUID
"""
function _get_pkg_name(uuid::UUID, registries)
for rego in registries
for (pkg_name, pkg_entry) in rego.pkgs
if pkg_entry.uuid == uuid
return pkg_name
for entry in values(rego.pkgs)
if entry.uuid == uuid
return entry.name
end
end
end
Expand All @@ -103,18 +103,20 @@ function _get_pkg_uuid(
end

function _get_pkg_uuid(pkg_name::String, registry::RegistryInstance)
if haskey(registry.pkgs, pkg_name)
return registry.pkgs[pkg_name].uuid
else
alt_packages = _find_alternative_packages(pkg_name, collect(keys(registry.pkgs)))
for entry in values(registry.pkgs)
if entry.name == pkg_name
return entry.uuid
end
end

warning = "The package $(pkg_name) was not found in the $(registry.name) registry."
alt_packages = _find_alternative_packages(pkg_name, [entry.name for entry in values(registry.pkgs)])

if !isempty(alt_packages)
warning *= "\nPerhaps you meant: $(string(alt_packages))"
end
warning = "The package $(pkg_name) was not found in the $(registry.name) registry."

warning *= "\nOr you can search in another registry using `users(\"$(pkg_name)\", \"OtherRegistry\")`"
throw(PackageNotInRegistry(warning))
if !isempty(alt_packages)
warning *= "\nPerhaps you meant: $(string(alt_packages))"
end

warning *= "\nOr you can search in another registry using `users(\"$(pkg_name)\", \"OtherRegistry\")`"
throw(PackageNotInRegistry(warning))
end
16 changes: 14 additions & 2 deletions test/runtests.jl
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using PkgDeps
using Test
using UUIDs
using Pkg

const DEPOT = joinpath(@__DIR__, "resources")
const GENERAL_REGISTRY = only(reachable_registries("General"; depots=DEPOT))
Expand Down Expand Up @@ -67,12 +68,23 @@ all_registries = reachable_registries(; depots=DEPOT)
entry = PkgDeps._find_latest_pkg_entry("ClashPkg"; registries=all_registries)
# General has a later version of `ClashPkg`
@test entry.uuid == clashpkg_general_uuid
@test entry.repo == "https://path.to.repo/"

@static if VERSION >= v"1.7"
Pkg.Registry.init_package_info!(entry)
@test entry.info.repo == "https://path.to.repo/"
else
@test entry.repo == "https://path.to.repo/"
end

# No conflict here, so it should just find the right one
entry = PkgDeps._find_latest_pkg_entry("Case4"; registries=all_registries)
@test entry.uuid == UUID("172f9e6e-38ba-42e1-abf1-05c2c32c0454")
@test entry.repo == "https://path.to.repo/"
@static if VERSION >= v"1.7"
Pkg.Registry.init_package_info!(entry)
@test entry.info.repo == "https://path.to.repo/"
else
@test entry.repo == "https://path.to.repo/"
end

entry = PkgDeps._find_latest_pkg_entry(missing, UUID("172f9e6e-38ba-42e1-abf1-05c2c32c0454"); registries=all_registries)
@test entry.name == "Case4"
Expand Down

0 comments on commit 59473f4

Please sign in to comment.