Are there existing tools for evaluating the reverse dependencies of a package? That is, for determining the packages that depend directly or indirectly on a particular package?
It occurred to me that, if not, this might be an occasion for me to learn a bit more about the Registries used with Pkg3. How would I begin exploring the TOML capabilities if I decided to try to parse a Registry?
This showed up in my Google search today. I donโt think the answers here still work, so I feel compelled to post, with apology, a kludge that does work. Perhaps someone will also post a more elegant solution which makes use of the dependency graph that I believe Pkg maintains in the first place.
import Pkg
ctx = Pkg.Types.Context()
latest_version(ctx, uuid) = maximum(keys(Pkg.Operations.load_versions(Pkg.Types.registered_paths(ctx.env, uuid)[])))
function latest_pkgspec(ctx, name)
uuid = Pkg.Types.registered_uuid(ctx.env, name)
Pkg.Types.PackageSpec(name, uuid, latest_version(ctx, uuid))
end
latest_deps(pkg_name) = Pkg.Operations.load_deps(ctx, latest_pkgspec(ctx, pkg_name))
latest_deps("Plots") # trigger populating of ctx.env
function reverse_deps(ctx, pkg_name_query)
all_names = map(
x->if length(x) == 1; x[]; else; nothing; end,
values(ctx.env.names))
all_names = filter(!isnothing, all_names)
[pkg_name for pkg_name in all_names if pkg_name_query in keys(latest_deps(pkg_name))]
end
reverse_deps(ctx, "BinDeps")
Updated to run w/ 1.5/1.6 below. I say to run because the output is wrong. Pkg.Operations.load_all_deps does not seem to be the correct function to get all dependencies for a package (assuming thatโs what Pkg.Operations.load_deps did - it no longer exists). Rather, I believe load_all_deps returns all installed packages in the current environment.
For anyone who found this topic through Google you can now (1.9) do
help?> Pkg.dependencies
Pkg.dependencies()::Dict{UUID, PackageInfo}
This feature is considered experimental.
Query the dependency graph of the active project. The result is a Dict that maps a package UUID to a PackageInfo struct representing the dependency (a package).
PackageInfo fields
โกโกโกโกโกโกโกโกโกโกโกโกโกโกโกโกโกโกโกโก
Field Description
โโโโโโโโโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโโ
name The name of the package
version The version of the package (this is Nothing for stdlibs)
tree_hash A file hash of the package directory tree
is_direct_dep The package is a direct dependency
is_pinned Whether a package is pinned
is_tracking_path Whether a package is tracking a path
is_tracking_repo Whether a package is tracking a repository
is_tracking_registry Whether a package is being tracked by registry i.e. not by path nor by repository
git_revision The git revision when tracking by repository
git_source The git source when tracking by repository
source The directory containing the source code for that package
dependencies The dependencies of that package as a vector of UUIDs
Wait, doesnโt this just give the dependencies of the currently active project? If I understood the question correctly, itโs about finding the packages that depend on a given package. So, e.g. finding all the packages that use Plots or something like that.