I'm running my package through R CMD check
and the only (remaining) warning is the following:
W checking for unstated dependencies in 'tests' (4.4s)
'::' or ':::' import not declared from: 'devtools'
After getting confused for a long time about this seemingly nonsensical warning, I realized it's coming from my "test manager" script (see reason for its need below). This is file pkg/tests/testthat.R
, while the tests themselves are in 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)
If I comment out this entire file, the R CMD check
warning vanishes.
And then the weird part: if I replace devtools::test()
with just test()
, the R CMD check
warning vanishes.
However, the purpose of this "manager" script is to be to be called (via Rscript
) by a git pre-commit hook. This way, I can run all my tests to ensure the commit is stable. Due to this, I can't use test()
, since devtools
isn't loaded when the script is run via Rscript
.
I tried a few things to satisfy both R CMD check
and being called by Rscript
:
- Using
library(devtools)
doesn't work (throws apackage not found
error); - Moving
testthat.R
out of the/tests/
folder and into the top-level. This kills theR CMD check
warning, but it now instead throws a note:Non-standard file/directory found at top level: 'testthat.R'
, so not exactly satisfactory (especially since keeping it in the/tests/
directory seems more logically consistent); - Testing for a function which has been apparently loaded by
R CMD check
to determine behavior. Since using a nakedtest()
works, I assumeddevtools
was loaded, so prepended the following to the file (and usedrunTests
on the problematic line). The logic being, if we can findtest()
, use it. If we can't, then this probably isn'tR CMD check
, so we can use the full name.
if (length(find("test")) == 0) {
runTests <- devtools::test()
} else {
runTests <- test()
}
Unfortunately, this just made things worse: the warning remains and we also get an error on the if-else
block:
> 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
Why devtools::test()
throws an error here and just a warning on the problematic line is beyond me.
- Similarly, using
testthat::skip()
. Also doesn't work.
So, what can I do to satisfy both R CMD check
and being called by Rscript
? Is there a way to tell R CMD check
to ignore this file?
For the record, this is my git pre-commit hook, in case it can be reformulated to solve this problem some other way
#!/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