Determine version of a specific package - julia

How can I get the version number for a specific package?
The obvious way is to get the dictionary with all installed packages, and then filter for the one of interest:
pkgs = Pkg.installed();
pkgs["Datetime"]
Getting the list of all installed packages is very slow though, especially if there are many packages.

EDIT: For Julia version 1.1+
Use the Pkg REPL notation:
] status # Show every installed package version
] status pkgName # Show the specific version of the package
] status pkgName1 pkgName2 # Show the named packages. You can continue the list.
The ] enters the Pkg REPL, so you basically write status ...
So in your case, write after entering the Pkg REPL:
status DataFrame
Or use the object-oriented approach (NB: Here you don't enter the Pkg REPL, i.e. DON'T use ]:
Pkg.status("DataFrame")
EDIT: For Julia version 1.0
Pkg.installed seems to have "regressed" with the new package system. There are no arguments for Pkg.installed. So, the OP's original method seems to be about the best you can do at the moment.
pkgs = Pkg.installed();
pkgs["Datetime"]
EDIT: For Julia version upto 0.6.4
You can pass a string to Pkg.installed. For example:
pkgs = Pkg.installed("JuMP")
I often check available calling arguments with methods. For example:
julia> methods(Pkg.installed)
# 2 methods for generic function "installed":
installed() at pkg/pkg.jl:122
installed(pkg::AbstractString) at pkg/pkg.jl:129
or
julia> Pkg.installed |> methods
# 2 methods for generic function "installed":
installed() at pkg/pkg.jl:122
installed(pkg::AbstractString) at pkg/pkg.jl:129

I would try Pkg.status("PackageName")
This will print out a little blurb giving the package name.
Here is an example
julia> Pkg.status("QuantEcon")
- QuantEcon 0.0.1 master

In Julia 1.1 you can use
(v1.1) pkg> status "name_of_the_package"
to find the version of any package in a given environment.

In order to look of a version of an indirectly included package (e.g. top-level project includes Module A which depends on Module B, where you need to know info about Module B), you have to pull the info either from the Manifest.toml directly, or you have to bring in the Context object in from Pkg.
Below is done with Julia 1.3.1 ... there may be changes to Pkg's internals since then.
using Pkg
ctx = Pkg.Operations.Context()
# Get the version of CSV.jl
version = ctx.env.manifest[UUID("336ed68f-0bac-5ca0-87d4-7b16caf5d00b")].version
if version <= v"0.5.24"
# handle some uniqueness about the specific version of CSV.jl here
end
UPDATE: Or without a UUID and just the package name (thanks #HHFox):
using Pkg
pkg_name = "Observables"
m = Pkg.Operations.Context().env.manifest
v = m[findfirst(v->v.name == pkg_name, m)].version
or to do the same with the Manifest.toml
using Pkg
# given the path to the Manifest.toml file...
manifest_dict = Pkg.TOML.parsefile(manifest_path)
# look for a named package like `CSV`
package_dict = manifest_dict[package_name][1]
#show package_dict

Well this didn't print well in the comment section...
Here is a version that matches the name rather than the UUID
using Pkg
m = Pkg.Operations.Context().env.manifest
v = m[findfirst(v -> v.name == "CSV", m)].version

For packages which are dependencies of the specified packages in the project file one can use status -m <packageName> or shorter st -m <packageName> in package mode (After ]`).
For a full list, just use st -m.
This is an extension to https://stackoverflow.com/a/25641957.

Related

How to add dependencies to my Julia package?

I have created a package (let's call it package_name) in Julia; the file structure is already generated along with the Project.toml and Manifest.toml files and I have already added some dependencies when I created the package.
I forgot to add a dependency and I would like to get the REPL to show:
(package_name) pkg >
so that I may type
add dependency_name
How do I get the REPL to show this? I think I need to go to the package folder and (re) activate the package but I am unable to navigate to it with cd.
Showing the exact commands I should type in the REPL would be helpful.
In order to get the package REPL mode, you should type a closing bracket ] when your cursor is at the beginning of the line. Likewise, when in package REPL mode, you need to type BackSpc right after the prompt in order to get back to standard REPL mode:
julia> # type ] here to enter the Pkg REPL
# We're now in the Pkg REPL, but the default environment is active
# Let's activate the environment we want
# (replace the path below with "." to activate the environment defined in the current working directory)
(#v1.5) pkg> activate /path/to/package
# Now we see that the correct environment is active
# This is where new dependencies will be added
(package_name) pkg> add DepName
(package_name) pkg> # type BackSpace here to get back to the standard REPL
julia>
Additionally, you could achieve the same thing without entering the Pkg REPL mode, by using the pkg"..." string macro defined in the Pkg library:
julia> using Pkg
julia> pkg"activate /path/to/package"
julia> pkg"add DepName"
You can also add deps manually to your project.toml file like
name = "MyPackage"
uuid = "e91191c6-8984-4a4d-b031-ef6fb65a77ca"
authors = ["Shep Bryan IV and contributors"]
version = "0.1.0"
[deps]
HDF5 = "f67ccb44-e63f-5c2f-98bd-6dc0ccc4ba2f"
SparseArrays = "2f01184e-e22b-5df5-ae63-d93ebab69eaf"
This requires that you be able to find the corresponding uuid codes for each package you use. Currently there is no simple function to do this, but if you really want to do it manually you can find a complete list of uuids for registered packages here.
Alternatively you can use this crude script to get the uuids from within Julia:
using Downloads
function get_uuid_from_registry(modulename)
# Download the registry to temporary file
tempfile = Downloads.download("https://github.com/JuliaRegistries/General/blob/master/Registry.toml")
# Open the tempfile
f = open(tempfile, "r")
# Loop through the lines in the file
for line in readlines(f)
if occursin(">$(modulename)<", line)
# Cut out uuid from HTML file
uuid = split(split(line, "<span class=\"pl-smi\">")[2], "</span>")[1]
return uuid
end
end
println("No module found")
return
end
uuid = get_uuid_from_registry("HDF5")

How can I switch virtualenv from reticulate in R?

In R package reticulate there is a function use_virtualenv but it does not look like I can call it twice with different virtualenvs, second call is always ignored.
Is there a way to deactivate first virtualenv so I can call use_virtualenv("venv2") with the expected behavior?
#initialize
require(reticulate)
virtualenv_create("venv1")
virtualenv_create("venv2")
#call first virtualenv
use_virtualenv("venv1")
py_config() #show venv1 specs
#call second vrtualenv
use_virtualenv("venv2")
py_config() # still show venv1 specs, I want venv2 here
I think unloadNamespace("reticulate") could work but in my case first call is made by another package...
In short: By restarting the R session! You can't switch virtualenv in reticulate once chosen!
I tried it (but chose "venv2" first).
> use_python("venv1", T)
Error in use_python("venv1", T) :
Specified version of python 'venv1' does not exist.
> use_python("~/.virtualenvs/venv1", T)
ERROR: The requested version of Python ('~/.virtualenvs/venv1') cannot
be used, as another version of Python
('/home/josephus/.virtualenvs/venv2/bin/python') has already been
initialized. Please restart the R session if you need to attach
reticulate to a different version of Python.
Error in use_python("~/.virtualenvs/venv1", T) :
failed to initialize requested version of Python
So reticulate messages, that one has to start a new session to choose new virtual environment.
This must apply to use_virtualenv(<xxx>, T) too, though it is not as verbose as use_python(<xxx>, T).

list packages available for download/install in Julia version 1.0

In version 0.4 there was Pkg.available() which I used to look at what packages were available for download/install. How do you do this in v1.0?
Yes, I have read the documentation and searched extensively.
Assuming you are keeping your package repository in a standard location you can use
using Pkg
Pkg.update()
reg = "~/.julia/registries/General/Registry.toml"
regdict = Pkg.TOML.parsefile(reg)
pkg_list = getindex.(values(regdict["packages"]), "name")
If you use a non-standard location of the Registry.toml file then you can see it e.g. when you run Pkg.update() command or get it using Pkg.Types.registries() (the directory where this file lies should be the first entry in the list).
Finally you can fetch Registry.toml from https://github.com/JuliaRegistries/General GitHub repository.
EDIT:
Using standard functions you could do it as follows
using Pkg
reg = joinpath(Pkg.Types.registries()[1], "Registry.toml")
regdict = Pkg.Types.read_registry(reg)
pkg_list = getindex.(values(regdict["packages"]), "name")
You can just use tab-completion in the Pkg REPL mode.
For example:
(v1.0) pkg> add JS[TAB]
JSON JSONWebTokens JSON2 JSExpr JSONSchema
(Where [TAB] represents a key-press, not literal characters)

How to quickly replicate/update local library under $R_LIBS_USER?

Suppose that
the version of R I have installed is 3.3.1;
my environment variable $R_LIBS_USER is set to $HOME/my/R_lib/%V; and
I have a directory $HOME/my/R_lib/3.3.1 containing a large number of packages I've installed over time.
Now I want to upgrade my version of R, to 3.4.1, say.
I'm looking for a convenient way to install a new collection of packages under the new directory $HOME/my/R_lib/3.4.1 that is the "version-3.4.1-equivalent" of the library I currently have under $HOME/my/R_lib/3.3.1.
(IOW, I'm looking for a functionality similar to what one can do with Python's pip installer's "freeze" option, which, essentially, produces the input one would have to give the installer in the future to reproduce the current installation.)
You can use function installed.packages for that purpose. Namely:
installed.packages(lib.loc = "$HOME/my/R_lib/3.3.1")
The returned object contains a lot of informations (most fields from each package DESCRIPTION file) but the names of the packages are in the first column. So something like the following should do the trick:
inst <- installed.packages(lib.loc = "$HOME/my/R_lib/3.3.1")
install.packages(inst[,1], lib="$HOME/my/R_lib/3.4.1", dependencies=FALSE)
To answer the additional question in the comments:
If your old library contained packages from other sources than CRAN, you will have to do some gymnastic based on the content of the DESCRIPTION files, and thus will depend on how well the package author documented it.
Argument field in installed.packages allows you to select some additional fields from those files. Fields of interest to determine the source of a package are fields Repository, URL and Maintainer. Here are some ideas on how to split them apart:
CRAN vs non-CRAN:
inst <- installed.packages(lib.loc = "$HOME/my/R_lib/3.3.1",
fields=c("URL","Repository","Maintainer"))
inst <- as.data.frame(inst, row.names=NA, stringsAsFactors=FALSE)
cran <- inst[inst$Repository%in%"CRAN",]
non_cran <- inst[!inst$Repository%in%"CRAN" & !inst$Priority%in%"base",]
Bioconductor packages:
bioc <- inst[grepl("Bioconductor",inst$Maintainer),]
source("https://bioconductor.org/biocLite.R")
biocLite(pkgs=bioc$Packages)
Github packages:
git <- non_cran[grepl("github", non_cran$URL),]
install.packages("devtools")
library(devtools)
for(i in seq(nrow(git))){
install_github(repo=gsub("http://github.com/","",git$URL[i]))
}

Installing all CRAN packages that are not already installed?

The following R commands will install all CRAN packages:
availablePackages <- available.packages()[,1]
install.packages(availablePackages)
And the following command will list all installed packages:
installedPackages <- .packages(all.available = TRUE)
My question is: How do I instruct R to install all CRAN packages that are not already installed?
Frankly, I think it's painstaking job... it would last for days, even weeks (depending on resources), but here's the code (I just enjoy doing trivial things):
# get names of installed packages
packs <- installed.packages()
exc <- names(packs[,'Package'])
# get available package names
av <- names(available.packages()[,1])
# create loooong string
ins <- av[!av %in% exc]
install.packages(ins)
I still don't get why you're doing this, but, hey... some things are just not meant to be....
What wonders me the most is the fact that you've already answered your own question! You got what you needed, and it's just up to you to put things together...
Are we missing the point? Did you have something else in mind?!?
1) Why would you want to do that? There are over 3500 (as of Feb 2012) of them?
2) Did you look at CRAN Task Views and the ctv package that allows you to install packages from a given task?
3) You bold-face question is a simple indexing query you can do by hand (and besides that, also see help(sets))
R> available <- LETTERS # a simple set
R> installed <- LETTERS[c(1:10, 15:26)] # a simple subset
R> available[ ! available %in% installed ]
[1] "K" "L" "M" "N"
R>
Edit: in response to your follow-up:
a) If a package does not pass 'R CMD check' on Linux and Windows, it does not get uploaded to CRAN. So that job is done.
b) Getting all depends at your end is work too as you will see. We did it for cran2deb which is at http://debian.cran.r-project.org (which does full-blown Debian package building which is more than just installing). We get about 2050 out of 2150 packages built. There are a few we refuse to build because of license, a few we cannot because of missing headers or libs and a few we cannot build because they need e.g. BioConductor packages.
type this command and then all packages will be installed automatically:
install.packages(available.packages()[,1])
Better if you use:
check.and.install.Package<-function(package_name){
if(!package_name%in%installed.packages()){
install.packages(package_name)
}
}
call the function and check if required package is installed:
check.and.install.Package("pkgName")
I've tested this and it works
availablePackages=available.packages()
availablePackages<-as.vector(availablePackages[,1])
installedPackages=.packages(all.available = TRUE)
missedPackages<-setdiff(availablePackages, installedPackages)
for (i in 1:length(missedPackages))
{
pkgName <- missedPackages[i]
install.packages(pkgName)
}
print("END")
Regards
From my experience, it is not wise to install all the R packages at once! Even if you do not call upon (using library function) all those packages, by just sitting in the home directory, they can slow down your R studio. At least that's what happened in my case.

Resources