How to test if package is installed

question

#1

What’s the recommended API for testing if a package (which may not be registed) is installed? I have seen two versions floating around:

"somepackage" ∈ keys(Pkg.installed())

and

isdir(Pkg.dir("somepackage"))

The second one feels hackish. First I thought checking Pkg.installed("somepackage") but that can return an error for unregistered, uninstalled packages.

(This is for use in .juliarc.jl, when running different versions.)


#2

The second one is very similar to how Pkg itself does it, so I would not say it’s hackish (unless you believe the approach of Pkg itself to be hackish). If you want to match exactly how Pkg determines if a package is installed, use

isinstalled(pkg::AbstractString) =
    pkg != "METADATA" && pkg != "REQUIRE" && pkg[1] != '.' && Pkg.cd(isdir, pkg)

#3

Pkg doesn’t have the most useful conception of what “installed” means at the moment. What are you trying to accomplish? Modules can be used from anywhere on LOAD_PATH without Pkg knowing anything about them.


#4

basically, something like this in .juliarc:

if (SomePackage is installed) && (VERSION >= v"0.6-")
   eval(quote
           import SomePackage
           SomePackage.dostuff(...)
        end)
end

ie using a package but not causing an error if it is not available.


#5

Can’t you just use a try catch?


#6

With Julia v0.7.0 and v1.0.0 releases, I want to revive this topic. The reason is that Pkg.installed does not exist anymore in these new releases. Moreover, executing, say, Pkg.dir("OhMyREPL) gives us the following warning on v0.7.0:

WARNING: Base.Pkg is deprecated, run `using Pkg` instead
  likely near /Users/xxx/.julia/config/startup.jl:1
┌ Warning: `Pkg.dir(pkgname, paths...)` is deprecated; instead, do `import OhMyREPL; joinpath(dirname(pathof(OhMyREPL)), "..", paths...)`.
└ @ Pkg.API /Users/osx/buildbot/slave/package_osx64/build/usr/share/julia/stdlib/v0.7/Pkg/src/API.jl:454

This system suggestion is not good since we want to do isdir(Pkg.dir("OhMyREPL")) and if OhMyREPL.jl is not installed, import OhMyREPL in the suggested solution generates error of course.
So what would be a good solution for v0.7.0 and v1.0.0?
Thanks!


#7

So I’m inferring that your use case is that you want to check whether OhMyREPL is installed in your startup.jl, perhaps so that you can use it if it’s installed. I used to do this because I was changing JULIA_PKGDIR to get separate package environments, and OhMyREPL might not be installed in all of them. If you were doing the same thing, I can recommend simply installing OhMyREPL to your default package environment. If you do that, then running julia --project in some other directory will still result in OhMyREPL being on the LOAD_PATH, so it’s available regardless of your active project and you don’t need to check.

But maybe I’m wrong and you have a different use case.


#8

Thanks a lot! However, if I put using OhMyREPL directly in my ~/.julia/config/startup.jl (v0.7/v1.0 replacement of ~/.juliarc.jl), then for normal Julia sessions, I don’t have any problem, but when I try to build Conda.jl, it somehow says that it cannot find OhMyREPL package and suggests that I should run Pkg.add("OhMyREPL") although I already added it.
But then, I found an excellent solution posted by @Simon_Bolland:


After putting this one in startup.jl, I haven’t got any error when building Conda.


#9

Yeah, this is a known bug (https://github.com/JuliaLang/Pkg.jl/issues/609) which will be adressed in Julia 1.0.1.


#10

Thanks a lot! Good to know that it would be addressed in Julia 1.0.1!


#11

I don’t think try catch is a good idea, I mean, I’ll avoid using it if there is any other way to know if a package is intalled,


#12

There is a recent issue

but, with Pkg(3), I am no longer sure that this functionality should be used by other packages, except in exceptional circumstances.

If a package is needed, one can just specify it as a dependency in Project.toml, and let Pkg take care of the details. If functionality is conditional on a package being installed, we have

What I originally wanted to accomplish when I asked this question is solved by the latter.