【问题标题】:"R CMD check" throws warning on use of 'devtools::test()', but allows 'test()', but need to use full function name“R CMD check”在使用“devtools::test()”时抛出警告,但允许“test()”,但需要使用完整的函数名
【发布时间】:2020-06-03 14:49:42
【问题描述】:

我正在通过R CMD check 运行我的包,唯一(剩余的)警告如下:

W  checking for unstated dependencies in 'tests' (4.4s)
   '::' or ':::' import not declared from: 'devtools'

在对这个看似荒谬的警告困惑了很长时间之后,我意识到它来自我的“测试管理器”脚本(请参阅下面的需要它的原因)。这是文件pkg/tests/testthat.R,而测试本身在pkg/tests/testthat/。

# testthat.R
sink(stderr(), type = "output")

x <- tryCatch(
  {
    x <- data.frame(devtools::test())  # here's the problem!

    as.numeric(sum(x$failed) > 0)
  },
  error = function(e) {
    1
  }
)

sink(NULL, type = "output")
cat(1)

如果我注释掉整个文件,R CMD check 警告就会消失。

然后是奇怪的部分:如果我只用 test() 替换 devtools::test(),R CMD check 警告就会消失。

然而,这个“管理器”脚本的目的是被一个 git pre-commit 钩子调用(通过Rscript)。这样,我可以运行所有测试以确保提交是稳定的。因此,我不能使用test(),因为通过Rscript 运行脚本时不会加载devtools。

我尝试了一些方法来满足R CMD check 和被Rscript 调用:

  • 使用library(devtools) 不起作用(引发package not found 错误);
  • 将testthat.R 移出/tests/ 文件夹并移至顶层。这会杀死 R CMD check 警告,但现在会抛出一个注释:Non-standard file/directory found at top level: 'testthat.R',因此并不完全令人满意(尤其是因为将其保存在 /tests/ 目录中似乎更符合逻辑);
  • 测试显然已由R CMD check 加载的函数以确定行为。由于使用裸test() 有效,我假设devtools 已加载,因此将以下内容添加到文件中(并在有问题的行上使用runTests)。逻辑是,如果我们能找到test(),就使用它。如果我们不能,那么这可能不是R CMD check,所以我们可以使用全名。
if (length(find("test")) == 0) {
  runTests <- devtools::test()
} else {
  runTests <- test()
}

不幸的是,这只会让事情变得更糟:警告仍然存在,我们还在if-else 块上收到错误:

> if (length(find("test")) == 0) {
+   runTests <- devtools::test()
+ } else {
+   runTests <- test()
+ }
Error in loadNamespace(name) : there is no package called 'devtools'
Calls: :: ... loadNamespace -> withRestarts -> withOneRestart -> doWithOneRestart

为什么devtools::test() 会在这里抛出错误,而我只是在有问题的行上发出警告。

  • 类似地,使用testthat::skip()。也不行。

那么,我该怎么做才能同时满足R CMD check 和被Rscript 调用?有没有办法告诉R CMD check 忽略这个文件?


作为记录,这是我的 git pre-commit 钩子,以防万一它可以重新制定以通过其他方式解决这个问题

#!/bin/sh

R_USER="D:/Users/wasabi/Documents"
export R_USER

# check that Rscript is accessible via PATH; fail otherwise
command -v Rscript >/dev/null || {
    echo "Rscript must be accessible via PATH. Commit aborted.";
    exit 1;
};

# check whether there are unstaged changes. If so, stash them.
# This allows the tests to run only on previously committed or
# indexed (added on this commit) changes.
hasChanges=$(git diff)
if [ -n "$hasChanges" ]; then
    git stash push --keep-index
fi

exitCode=$(Rscript tests/testthat.R)

# remember to unstash any unstaged changes
if [ -n "$hasChanges" ]; then
    git stash pop
fi

exit $exitCode

【问题讨论】:

    标签: r git


    【解决方案1】:

    解决方案是简单地将tests/testthat.R 添加到.Rbuildignore(以正则表达式的形式手动添加或使用usethis::use_build_ignore("tests/testthat.R"))。

    如果您实际运行R CMD check,警告仍然会出现(因为它在源文件上运行,因此会忽略 .Rbuildignore,除非您在二进制文件本身上运行它)。

    但是 RStudio 中的“检查包”命令依赖于 devtools::check(),它首先构建包然后检查二进制文件,因此不会出现错误。既然这就是我和我的团队实际运行检查的方式,这就足够了。

    受this question启发的解决方案。

    【讨论】:

      猜你喜欢
      • 2020-02-18
      • 2018-03-02
      • 2017-06-10
      • 2020-10-13
      • 2014-03-07
      • 2017-07-05
      • 1970-01-01
      • 2020-10-30
      • 1970-01-01
      相关资源
      最近更新 更多