Repo corresponding to package in environment

Is there some way to go from the name of a package in the current environment, to the GitHub repo that it ultimately came from? I mean in the case of a package that is currently coming from a registry, not one that is explicitly specified as a repo in an add or dev.

Clearly Pkg at some point works this out when you do an add or update, and I wonder if it’s possible to hook into whatever it’s doing. If the API already has something for this I’ve missed it somehow.

The motivation is that I’d like to explore making some tooling to extract useful info from a given package’s repo, without priori knowing what that repo is.

Pkg doesn’t have a public API for this and I wouldn’t recommend depending on the internals since they tend to be a moving target. Instead you can use GitHub - GunnarFarneback/RegistryInstances.jl: Access the information in installed Julia registries., which basically is a snapshot of the registry functionality of Pkg. It’s no better documented than Pkg so you need to figure out some things yourself.

Some pointers along the way:

  • Base.active_project can give you the path to the current environment.
  • Use the TOML stdlib to read Project.toml / Manifest.toml.
  • RegistryInstances.reachable_registries() loads your currently installed registries into memory.
  • RegistryInstances.registry_info(pkg) extracts information about a package, including its repository.
2 Likes

Thanks! That’s very helpful:

using RegistryInstances
function package_repo(pkgname)
    rr = reachable_registries()
    for reg_instance in rr
        for pkg in reg_instance.pkgs
            if pkg.second.name == pkgname
                found = true
                ri = registry_info(pkg.second)
                return ri.repo
            end
        end
    end
    throw(ErrorException("Could not find package $pkgname"))
end
julia> package_repo("RegistryInstances")
"https://github.com/GunnarFarneback/RegistryInstances.jl.git"

If you want to be thorough you should take the possibility of multiple packages with the same name into account. Then you need to look up the UUID from your environment and use that as key to the registry instances. Potentially you could also find the same package in multiple registries, possibly with different repo URLs.

If you don’t have a need to cover those possibilities, your function is fine.

Yep, makes sense. Also, in the meantime I stumbled on this which looks like it already has what I need: GitHub - JuliaEcosystem/PackageAnalyzer.jl

There is also the pkg_site function from the PkgOnlineHelp package.

1 Like