From Julia v1.4, Pkg.installed() shows deprecation message.
Using Pkg.dependencies() is recommended instead of Pkg.installed() in this issue: https://github.com/JuliaLang/Pkg.jl/issues/1724
However, Pkg.dependencies return all packages, not top level packages like Pkg.installed.
How can I get same results using Pkg.dependencies instead of Pkg.installed?
However on a usability prospective it is terrible, it is a regression compared to the first line… I need to know what a UUID is, where to find it,…
Why Pkg.installed(PackageName) has been deprecated ? Shouldn’t be a higher-level function like it (or better Pkg.isavailable("PackageName"), returning directly a bool ) made available ?
The first one had the problem in that it only showed packages that were direct dependencies. It’s API was fundamentally incompatible with showing packages in the manifest since you can have multiple packages with the same name there and the key for installed was the package name. To have an API that gives information about all dependencies (including recursive) you pretty much must use the UUID as the key since that is what identifies the package.
But I am interested in just knowing if a package is already available for using or not.
If name collision is a (remote, i.e. not possible if you just use the standard repository) possibility one could have just a function that returns the number of available packages by name and then use it as:
if Pkg.availablecount("pkgName") == 0
Pkg.add("pkgName")
elseif Pkg.availablecount("pkgName") > 1
@error "More than one package is available with the given name. Please use UUID"
end
using pkgName
To add to this discussion:
when I start a program I’d like to enter a vector of packages
then, automatically/generically
-check if it’s installed
-install it if not
-using all packages in vector
Old way, gives deprec warning
pk = ["Knet","Colors","Images"]
using Pkg; for p in pk; haskey(Pkg.installed(),p) || Pkg.add(p); end
using Knet, Colors, Images
isinstalled(pkg::String) = any(x -> x.name == pkg && x.is_direct_dep, values(Pkg.dependencies()))
pk = ["Knet","Colors","Images", "StatsPlots"]
using Pkg; for p in pk; isinstalled(p) || Pkg.add(p); end
using Knet, Colors, Images
Also I’d like to replace using Knet, Colors, Images
with for p in pk; using(p); end
but it doesn’t work bc pk is a vector of strings
Adding the function isinstalled(pkg::String) each time is a bit of a pain …
So is there no one-liner like Pkg.installed() now? I ran the for loop and I got the answer but is there any simpler way of getting the installed libraries?
I’m not aware of any. On the other hand it is a one-liner if you don’t insist on getting exactly the same datastructure as the ancient installed(). Like you could just do:
[dep for dep in dependencies() if dep.is_direct_dep]
There is the Pkg.project() which contains a field named dependencies containing a dict with package names and UUID of direct dependencies. So keys(Pkg.project().dependencies) == keys(Pkg.installed()) if I’m not mistaken, and could for the purpose in this thread probably be used as a one line replacement.
This code of mine works wonderfully and hopefully solves almost all the issues raised here:
# Make sure all needed Pkg's are ready to go
neededPackages = [:Gtk4, :Cairo]
using Pkg;
for neededpackage in neededPackages
(String(neededpackage) in keys(Pkg.project().dependencies)) || Pkg.add(String(neededpackage))
@eval using $neededpackage
end