diff --git a/NEWS.md b/NEWS.md index 75460bd6bb..514ea3bf62 100644 --- a/NEWS.md +++ b/NEWS.md @@ -151,6 +151,8 @@ unit = "s") 8. Change of `c.POSIXct` method planned for R 4.1.0 impacted `foverlaps` function that could raise `'origin' must be supplied` error. Fix for planned change has been provided in [#4428](https://github.com/Rdatatable/data.table/pull/4428). +9. `data.table::update.dev.pkg()` now unloads the `data.table` namespace to alleviate a DLL lock issue on Windows, [#4403](https://github.com/Rdatatable/data.table/issues/4403). Thanks to @drag5 for reporting. + # data.table [v1.12.8](https://github.com/Rdatatable/data.table/milestone/15?closed=1) (09 Dec 2019) diff --git a/R/devel.R b/R/devel.R index 8db74e47ce..b0dfb71858 100644 --- a/R/devel.R +++ b/R/devel.R @@ -7,7 +7,7 @@ dcf.lib = function(pkg, field, lib.loc=NULL){ if (nzchar(dcf)) read.dcf(dcf, fields=field)[1L] else NA_character_ } -dcf.repo = function(pkg, repo, field, type){ +dcf.repo = function(pkg, repo, field, type) { # get DESCRIPTION metadata field from remote PACKAGES file stopifnot(is.character(pkg), is.character(field), length(pkg)==1L, length(field)==1L, is.character(repo), length(repo)==1L, field!="Package") idx = file(file.path(contrib.url(repo, type=type),"PACKAGES")) @@ -17,22 +17,33 @@ dcf.repo = function(pkg, repo, field, type){ dcf[dcf[,"Package"]==pkg, field][[1L]] } -update.dev.pkg = function(object="data.table", repo="https://Rdatatable.gitlab.io/data.table", field="Revision", type=getOption("pkgType"), lib=NULL, ...){ +update.dev.pkg = function(object="data.table", repo="https://Rdatatable.gitlab.io/data.table", field="Revision", type=getOption("pkgType"), lib=NULL, ...) { + # this works for any package, not just data.table pkg = object # perform package upgrade when new Revision present stopifnot(is.character(pkg), length(pkg)==1L, !is.na(pkg), is.character(repo), length(repo)==1L, !is.na(repo), is.character(field), length(field)==1L, !is.na(field), is.null(lib) || (is.character(lib) && length(lib)==1L && !is.na(lib))) + # get Revision field from remote repository PACKAGES file una = is.na(ups<-dcf.repo(pkg, repo, field, type)) - upg = una | !identical(ups, dcf.lib(pkg, field, lib.loc=lib)) - if (upg) utils::install.packages(pkg, repos=repo, type=type, lib=lib, ...) - if (una) cat(sprintf("No commit information found in DESCRIPTION file for %s package. Unsure '%s' is correct field name in PACKAGES file in your devel repository '%s'.\n", pkg, field, file.path(repo, "src","contrib","PACKAGES"))) - cat(sprintf("R %s package %s %s (%s)\n", - pkg, - c("is up-to-date at","has been updated to")[upg+1L], - dcf.lib(pkg, field, lib.loc=lib), - utils::packageVersion(pkg, lib.loc=lib))) + if (una) + cat(sprintf("No revision information found in DESCRIPTION file for %s package. Unsure '%s' is correct field in PACKAGES file in your package repository '%s'. Otherwise package will be re-installed every time, proceeding to installation.\n", + pkg, field, contrib.url(repo, type=type))) + # see if Revision is different then currently installed Revision, note that installed package will have Revision info only when it was installed from remote devel repo + upg = una || !identical(ups, dcf.lib(pkg, field, lib.loc=lib)) + # update.dev.pkg fails on windows R 4.0.0, we have to unload package namespace before installing new version #4403 + on.exit({ + if (upg) { + unloadNamespace(pkg) ## hopefully will release dll lock on Windows + utils::install.packages(pkg, repos=repo, type=type, lib=lib, ...) + } + cat(sprintf("R %s package %s %s (%s)\n", + pkg, + c("is up-to-date at","has been updated to")[upg+1L], + unname(read.dcf(system.file("DESCRIPTION", package=pkg, lib.loc=lib, mustWork=TRUE), fields=field)[, field]), + utils::packageVersion(pkg, lib.loc=lib))) + }) } # non-exported utility when using devel version #3272: data.table:::.git() diff --git a/man/update.dev.pkg.Rd b/man/update.dev.pkg.Rd index f4802641cc..96f87c296d 100644 --- a/man/update.dev.pkg.Rd +++ b/man/update.dev.pkg.Rd @@ -3,15 +3,9 @@ \alias{update.dev.pkg} \title{Perform update of development version of a package} \description{ - It will download and install package from devel repository only when new commit is - available there, otherwise only PACKAGES file is transferred. Defaults are set to update \code{data.table}, other - packages can be used. Their repository has to include git commit - information in PACKAGES file. + It will download and install package from devel repository only when new commit is available there, otherwise only PACKAGES file is transferred. Defaults are set to update \code{data.table}, other packages can be used as well. Their repository has to include git commit information in PACKAGES file. } - -\usage{\method{update}{dev.pkg}(object="data.table", -repo="https://Rdatatable.gitlab.io/data.table", field="Revision", -type=getOption("pkgType"), lib=NULL, \dots) + \usage{\method{update}{dev.pkg}(object="data.table", repo="https://Rdatatable.gitlab.io/data.table", field="Revision", type=getOption("pkgType"), lib=NULL, \dots) } \arguments{ \item{object}{ character scalar, package name. } @@ -25,9 +19,10 @@ type=getOption("pkgType"), lib=NULL, \dots) \item{\dots}{ passed to \code{\link[utils]{install.packages}}. } } \details{ - In case if devel repository does not provide package binaries user has - have development tools installed for package compilation to use - this function. + In case if a devel repository does not provide binaries user will need development tools installed for package compilation, like \emph{Rtools} on Windows, and eventually set \code{type="source"}. +} +\note{ + Package namespace is unloaded before attempting to install newer version. } \value{ NULL.