I found an inconsistency with the documentation here:
"""
installed(pkg) -> Void | VersionNumber
If `pkg` is installed, return the installed version number, otherwise return `nothing`.
"""
installed(pkg::AbstractString) = cd(Entry.installed,pkg)
Currently it raises an error instead if there is not such a package:
julia> Pkg.installed("Foo")
ERROR: Base.Pkg.PkgError("Foo is not a package (not registered or installed)")
[inlined code] from .\pkg.jl:13
in installed(::String) at .\pkg\entry.jl:123
[inlined code] from .\promotion.jl:248
in (::Base.Pkg.Dir.##2#3{Array{Any,1},Base.Pkg.Entry.#installed,Tuple{String}})() at .\pkg\dir.jl:31
in cd(::Base.Pkg.Dir.##2#3{Array{Any,1},Base.Pkg.Entry.#installed,Tuple{String}}, ::String) at .\file.jl:58
in #cd#1(::Array{Any,1}, ::Function, ::Function, ::String, ::Vararg{String,N}) at .\pkg\dir.jl:31
[inlined code] from .\pkg\dir.jl:25
in installed(::String) at .\pkg.jl:112
in eval(::Module, ::Any) at .\boot.jl:230
I think nothing
is more useful, since can be used in conditionals, see:
Ok I see what's the problem, if the package is in METADATA but not installed, it returns nothing. If the package is not in METADATA it raises an error, and that is not documented a simple:
julia> is_installed(pkg) = Pkg.installed(pkg) === nothing ? false : true
is_installed (generic function with 1 method)
julia> is_installed("Conda")
true
julia> is_installed("Gadfly")
false
Does not work, a try catch is needed to test for non registered packages.
I agree with @Ismael-VC that the behavior of sometimes throwing an error and other times returning nothing for when there is a lack of a package is confusing. For example, to use this function to conditionally change behavior whether or not a package is installed, you can make it a boolean by using something like: (credits to @Ismael-VC )
function is_installed(pkg)
try
return(Pkg.installed(pkg) === nothing ? false: true)
catch
return(false)
end
end
but that feels like a hacky solution. If it always returned nothing even when not in METADATA, this would be greatly simplified.
I think it never should raise error.
And what should it return for an installed but not registered package? There are no meaningful version numbers in that case.
@tkelman that already works, since even if it's unregistered, when installed it's added to your own copy of METADATA and then it can return the version number correctly:
julia> Pkg.installed("LispREPL")
ERROR!
julia> Pkg.clone("https://github.com/swadey/LispREPL.jl.git")
julia> Pkg.installed("LispREPL")
v"0.0.0-"
So I edited the last comment, I didn't know LispSyntax was already registered, in my example, changed it to LispREPL, in this case it returns the zero version string, but it all depends on how the unregistered package handles it's releases.
In the case it's not registered it could return nothing
if not installed, just like registered packages. But it also could Warn
the same message (not registered or installed)
instead of Error
?
This issue is really depends on how do you look at top level Pkg
module command. If they are final UI implementation (I'd like to think so) then all exceptions should be caught and reported in a user friendly manner. If Pkg
is the API then current behaviour is the proper one.
Was this implemented? On Travis looks like it returns nothing
, but my local installation throws an error.
From what I figured out:
nothing
if not installedv"0.0.0-"
.I'm cleaning my left over PRs and reported issues. @StefanKarpinski is this issue still relevant when we take into account Pkg3? If this is or is going to be addressed by Pkg3, we could close this issue, else keep it open, just we don't forget.
The question of asking whether or not a particular package is installed or not becomes considerably more subtle in Pkg3. Which version? The one you have in your manifest? Or just any version? So I think this requires more consideration in the new Pkg3 universe. But in any case, this issue does seem no longer relevant.
Most helpful comment
From what I figured out:
nothing
if not installedv"0.0.0-"
.