Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I automatically add/update Depends/Imports/Suggests versions in DESCRIPTION?

I like to keep my R packages up to date, and in developing my own package, I want to stick to @Hadley's advice:

Generally, it’s always better to specify the version and to be conservative about which version to require. Unless you know otherwise, always require a version greater than or equal to the version you’re currently using.

So, I'll need some of those here in DESCRIPTION:

Imports:
 knitr (>= 1.13),
 rmarkdown (>= 1.0)

Is there an existing tool to programmatically update the versions of dependencies based on the packages I currently have installed?

I know this is a small thing and I can do this manually, but I just know this is the kind of thing that is easily forgotten.

Using the locally installed version of a package as a minimum dependency also seems to make sense because I tested / build with those dependencies.

Is there a reason why I shouldn't do this?

like image 498
maxheld Avatar asked Aug 03 '16 08:08

maxheld


People also ask

How do I update a specific package in R?

If you only want to update a single package, the best way to do it is using install. packages() again. In RStudio, you can also manage packages using Tools -> Install Packages.

What is R CMD check?

R CMD check automatically checks your code for common problems. It's essential if you're planning on submitting to CRAN, but it's useful even if you're not because it automatically detects many common problems that you'd otherwise discover the hard way.

What are r dependencies?

A dependency is a code that your package needs to run. Dependencies are managed by two files. The DESCRIPTION manages dependencies at the package level; i.e. what packages needs to be installed for your package to work. R has a rich set of ways to describe different types of dependencies.


1 Answers

This shld do what you ask (well, you still need to cut/paste the output into DESCRIPTION :-)

#' Add curent version string to package dependencies
#'
#' Will \code{cat} out a cut/paste-able set of fields for a
#' \code{DESCRIPTION} file with minimum required versions for
#' each package based upon currently available package vesions
#' in CRAN.
#'
#' @param pkg package description, can be path or package name
#' @param fields fields to get & report dependencies for
#' @note R and the R version is NOT added to \code{Depends}
#' @examples
#' add_pkg_versions("qmethod")
#' add_pkg_versions("MASS")
#' \dontrun { # assumes you're in a pkg devel dir
#' add_pkg_versions()
#' }
add_pkg_versions <- function(pkg=".",
                             fields=c("Depends", "Imports", "LinkingTo", "Suggests")) {

  require(purrr)
  walk(c("dplyr", "tools", "stringi", "devtools"), require, character.only=TRUE)

  stopifnot(is_scalar_character(pkg), pkg != "")
  fields <- match.arg(fields, c("Depends", "Imports", "LinkingTo", "Suggests"),
                      several.ok=TRUE)

  avail <- as_data_frame(available.packages())

  if (pkg == ".") {
    pkg_deps <- unclass(as_data_frame(read.dcf(file.path(package_file(), "DESCRIPTION"))))
    pkg <- pkg_deps$Package
    map(fields, ~stri_split_lines(pkg_deps[[.]])) %>%
      map(function(x) {
        if (length(x) > 0) {
          unlist(x) %>%
            stri_replace_all_regex(" \\(.*$|,", "") %>%
            discard(`%in%`, c("", "R"))
        } else { x }
      }) -> pkg_deps
    names(pkg_deps) <- fields
  } else {
    pkg_deps <- map(fields, ~flatten_chr((package_dependencies(pkg,  which=.))))
    names(pkg_deps) <- fields
  }

  pkg_deps <- discard(pkg_deps, function(x) {length(x)==0})

  map(pkg_deps, function(x) {

    non_base <- filter(avail, Package %in% x)
    base <- setdiff(x, non_base$Package)

    non_base %>%
      mutate(pv=sprintf("%s (>= %s)", Package, Version)) %>%
      select(pv) %>%
      flatten_chr() -> pkg_plus_version

    sort(c(pkg_plus_version, base))

  }) -> pkg_deps

  cat("Package: ", pkg, "\n", sep="")
  walk(names(pkg_deps), function(x) {

    cat(x, ":\n", sep="")
    sprintf("    %s", pkg_deps[[x]]) %>%
      paste0(collapse=",\n") %>%
      cat()
    cat("\n")

  })

}

One of your packages:

add_pkg_versions("qmethod")

Package: qmethod
Imports:
    digest (>= 0.6.10),
    GPArotation (>= 2014.11-1),
    knitr (>= 1.13),
    methods,
    psych (>= 1.6.6),
    tools,
    xtable (>= 1.8-2)

Just to show edge cases are handled:

add_pkg_versions("MASS")

Package: MASS
Depends:
    graphics,
    grDevices,
    stats,
    utils
Imports:
    methods
Suggests:
    lattice (>= 0.20-33),
    nlme (>= 3.1-128),
    nnet (>= 7.3-12),
    survival (>= 2.39-5)
like image 161
hrbrmstr Avatar answered Oct 08 '22 05:10

hrbrmstr