【问题标题】:Exclude R files for R folder with .Rbuildignore使用 .Rbuildignore 排除 R 文件夹的 R 文件
【发布时间】:2021-08-13 23:36:18
【问题描述】:

有些文件包含正在进行的工作,我想从整个构建过程中排除(检查、安装、甚至记录,如果可能的话),但不加载 (devtools::load_all())。

我总是将它们命名为dev-{feature}.R,所以我正要使用通配符,但碰巧我什至无法从构建中排除单个文件。

为了调试,我创建了一个 R 文件,名称为“R/dev-myfeature.R”,仅包含行 stop("TEST")。然后我运行usethis::use_build_ignore("R/dev-myfeature.R"),它在.Rbuildignore 文件中添加了^R/dev-myfeature\.R$

无论我运行devtools::load_all(".")devtools::check() 还是devtools::document(),我都会收到TEST 错误,所以.Rbuildignore 被忽略了。由于它适用于所有其他文件,我猜它在R 文件夹中没有任何功能。

有没有办法绕过这个限制?

否则,对于尚不应该成为构建一部分的正在进行中的文件,什么是好的工作流程?

【问题讨论】:

    标签: r build devtools


    【解决方案1】:

    我认为.Rbuildignore 文件对于打包您的包很有用,仅此而已。如果您希望 R/*.R 文件中的某些功能但仅在您的控制台上进行测试,那么您可以考虑使用包装 if 表达式来构建测试文件。

    例如,我将一个名为MYDEV 的变量的存在和真实性声明我要加载文件的内容。

    if (exists("MYDEV") && MYDEV) {
      stop("TEST")
    }
    

    在默认环境(MYDEV 未定义)中,load_allcheckdocument 看不到错误。使用exists(...) 有助于确保在您的计算机或其他地方的不同 R 实例中这不会出错 (object not found)。

    如果您设置MYDEV <- TRUE,那么所有devtools 函数都会看到stop 并相应地出错。我相信没有(合理的)方法可以获取来自load_allnotdocument 的代码。

    notdevtools::document 错误的一个问题是它在内部调用devtools::load_all,因为这样简单的测试不起作用。可以从https://stackoverflow.com/a/62747050/3358272 改编一个函数,使用:

    search_calling_pkg <- function(pkgs, funcs) {
      # <borrowed from="rlang::trace_back">
      frames <- sys.frames()
      idx <- rlang:::trace_find_bottom(NULL, frames)
      frames <- frames[idx]
      parents <- sys.parents()[idx]
      calls <- as.list(sys.calls()[idx])
      calls <- purrr::map(calls, rlang:::call_fix_car)
      #==# calls <- lapply(calls, rlang:::call_fix_car)
      calls <- rlang:::add_pipe_pointer(calls, frames)
      calls <- purrr::map2(calls, seq_along(calls), rlang:::maybe_add_namespace)
      #==# calls <- Map(rlang:::maybe_add_namespace, calls, seq_along(calls))
      # </borrowed>
      calls_chr <- vapply(calls, function(cl) as.character(cl)[1], character(1))
      ptn <- paste0("^(", paste(pkgs, collapse = "|"), ")::")
      pkgres <- any(grepl(ptn, calls_chr))
      funcres <- !missing(funcs) && length(calls_chr) &&
        any(mapply(grepl, paste0("(^|::)", funcs, "$"), list(calls_chr)))
      return(pkgres && funcres)
    }
    

    如果找到任何包/函数对,则此函数返回 true,并且此组合将“看到”(错误出现)stop("TEST")devtools::load_all 但不是 devtools::document

    if (search_calling_pkg("pkgload", "load_all") &&
          !search_calling_pkg("devtools", "document")) {
      stop("TEST")
    }
    

    是的,这意味着您需要在您的环境中某处使用search_calling_pkg,无论是否属于此软件包。回想一下,如果.Rbuildignore 文件包含R/dev-myfeature.R,那么包捆绑包和所有下游用户将永远不会看到此代码。如果你想更加防御,你可以使用

    if (exists("search_calling_pkg") &&
          search_calling_pkg("pkgload", "load_all") &&
          !search_calling_pkg("devtools", "document")) {
      stop("TEST")
    }
    

    【讨论】:

      猜你喜欢
      • 2017-10-12
      • 1970-01-01
      • 2019-02-16
      • 2018-10-01
      • 1970-01-01
      • 2013-12-07
      • 1970-01-01
      • 2021-12-30
      • 1970-01-01
      相关资源
      最近更新 更多