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

后端 未结 1 1667
渐次进展
渐次进展 2021-01-21 06:45

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

相关标签:
1条回答
  • 2021-01-21 07:19

    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)
    
    0 讨论(0)
提交回复
热议问题