From 253336e833ca12b2fcccc8451db01f4683b12b42 Mon Sep 17 00:00:00 2001 From: Daniel Matz Date: Tue, 20 Dec 2022 14:34:49 -0600 Subject: [PATCH] Use the RegistryInstances package The Pkg API often changes with each Julia release. Some of the capability of Pkg had been duplicated in this package, but it lacked some of the new capabilities of Pkg. With this change, we now leverage RegistryInstances, which makes it easier for us to support multiple versions of Julia. There are a few differences between the old implementation that was in this package and the implementation provided by RegistryInstances: - The old `RegistryInstance` had a `pkgs` field containing a dictionary mapping package names to `PkgEntry`s. The RegistryInstances version of `RegistryInstance` has a `pkgs` field, too, but it is a dictionary mapping `UUID`s to `PkgEntry`s. - The old `PkgEntry` had a `repo` field. The RegistryInstances version does not. Instead, it has a lazily initialized `info` field, which should be accessed using `RegistryInstances.registry_info`. Another benefit of using RegistryInstances is that it supports both uncompressed registries as well as registries stored in compressed tarballs. Thus, this fixes #37. --- Project.toml | 2 ++ src/PkgDeps.jl | 31 +++++++++---------------------- src/pkg_entry.jl | 7 ------- src/registry_instance.jl | 36 ------------------------------------ src/utilities.jl | 30 ++++++++++++++++-------------- test/runtests.jl | 5 +++-- 6 files changed, 30 insertions(+), 81 deletions(-) delete mode 100644 src/pkg_entry.jl delete mode 100644 src/registry_instance.jl diff --git a/Project.toml b/Project.toml index 7575450..a75f82f 100644 --- a/Project.toml +++ b/Project.toml @@ -7,6 +7,7 @@ version = "0.6.2" Compat = "34da2185-b29b-5c13-b0c7-acf172513d20" Pkg = "44cfe95a-1eb2-52ea-b672-e2afdf69b78f" REPL = "3fa0cd96-eef1-5676-8a61-b3b8758bbffb" +RegistryInstances = "2792f1a3-b283-48e8-9a74-f99dce5104f3" TOML = "fa267f1f-6049-4f14-aa54-33bafae1ed76" UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" @@ -14,6 +15,7 @@ UUIDs = "cf7118a7-6976-5b1a-9a39-7adc72f591a4" Compat = "3.26.0" TOML = "1.0" julia = "1.5" +RegistryInstances = "0.1" [extras] Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40" diff --git a/src/PkgDeps.jl b/src/PkgDeps.jl index aa7fed7..aa9eee6 100644 --- a/src/PkgDeps.jl +++ b/src/PkgDeps.jl @@ -6,14 +6,13 @@ using REPL using TOML: parsefile using UUIDs using Compat +using RegistryInstances: RegistryInstances, PkgEntry, RegistryInstance export PkgEntry, RegistryInstance export NoUUIDMatch, PackageNotInRegistry export users, reachable_registries export direct_dependencies, dependencies -include("pkg_entry.jl") -include("registry_instance.jl") include("exceptions.jl") include("utilities.jl") @@ -45,27 +44,15 @@ function reachable_registries( depots::Union{String, Vector{String}}=Base.DEPOT_PATH, kwargs... ) - registries = RegistryInstance[] + registries = RegistryInstances.reachable_registries(; depots) - 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 + if isempty(registry_names) + registries + else + filter(registries) do r + r.name in registry_names end end - - return registries 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...) @@ -97,10 +84,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 diff --git a/src/pkg_entry.jl b/src/pkg_entry.jl deleted file mode 100644 index 6b92a92..0000000 --- a/src/pkg_entry.jl +++ /dev/null @@ -1,7 +0,0 @@ -struct PkgEntry - path::String - registry_path::String - name::String - uuid::UUID - repo::String -end diff --git a/src/registry_instance.jl b/src/registry_instance.jl deleted file mode 100644 index 1ff145a..0000000 --- a/src/registry_instance.jl +++ /dev/null @@ -1,36 +0,0 @@ -struct RegistryInstance - path::String - name::String - uuid::UUID - url::Union{String, Nothing} - repo::Union{String, Nothing} - description::Union{String, Nothing} - pkgs::Dict{AbstractString, PkgEntry} -end - -function RegistryInstance(path::AbstractString) - d = parsefile(joinpath(path, "Registry.toml")) - pkgs = Dict{AbstractString, PkgEntry}() - - for (uuid, info) in d["packages"] - uuid = UUID(uuid) - name = info["name"] - pkgpath = info["path"] - - p = parsefile(joinpath(path, pkgpath, "Package.toml")) - p_repo = p["repo"] - - pkg = PkgEntry(pkgpath, path, name, uuid, p_repo) - pkgs[name] = pkg - end - - return RegistryInstance( - path, - d["name"], - UUID(d["uuid"]), - get(d, "url", nothing), - get(d, "repo", nothing), - get(d, "description", nothing), - pkgs - ) -end diff --git a/src/utilities.jl b/src/utilities.jl index fed4aad..b63be3f 100644 --- a/src/utilities.jl +++ b/src/utilities.jl @@ -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 @@ -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 + for pkg_entry in values(rego.pkgs) if pkg_entry.uuid == uuid - return pkg_name + return pkg_entry.name end end end @@ -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 pkg_entry in values(registry.pkgs) + if pkg_entry.name == pkg_name + return pkg_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 diff --git a/test/runtests.jl b/test/runtests.jl index d317002..56b1f0e 100644 --- a/test/runtests.jl +++ b/test/runtests.jl @@ -1,6 +1,7 @@ using PkgDeps using Test using UUIDs +using RegistryInstances: registry_info const DEPOT = joinpath(@__DIR__, "resources") const GENERAL_REGISTRY = only(reachable_registries("General"; depots=DEPOT)) @@ -67,12 +68,12 @@ 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/" + @test registry_info(entry).repo == "https://path.to.repo/" # 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/" + @test registry_info(entry).repo == "https://path.to.repo/" entry = PkgDeps._find_latest_pkg_entry(missing, UUID("172f9e6e-38ba-42e1-abf1-05c2c32c0454"); registries=all_registries) @test entry.name == "Case4"