The question is pretty simple. First:
Is it possible to include a non-CRAN (or bioconductor, or omega hat) package in a CRAN package and actually use tools from that package in examples.
If yes how does one set up the DESCRIPTION file etc. to make it legit and pass CRAN checks?
Specifically I'm asking about openNLPmodels.en that used to be a CRAN package. It's pretty useful and want to include functionality from it. I could do a work around and not actual use openNLPmodels.en in the examples or create unit tests for it, and have it install when a function gets use (similar to how the gender package installs the data sets it needs) but I'd prefer an approach that allows me to run checks, texts, examples.
This is how one downloads and installs openNLPmodels.en
install.packages(
"http://datacube.wu.ac.at/src/contrib/openNLPmodels.en_1.5-1.tar.gz",
repos=NULL,
type="source"
)
Existing answer is good but doesn't explain the whole process fully in details so posting this one.
Is it possible to include a non-CRAN (or bioconductor, or omega hat) package in a CRAN package and actually use tools from that package in examples.
Yes, it is possible. Any use (package code, examples, tests, vignettes) of such non-CRAN has to be escaped as any other package in Suggests, ideally using
if (requireNamespace("non.cran.pkg", quietly=TRUE)) {
non.cran.pkg::fun()
} else {
cat("skipping functionality due to missing Suggested dependency")
}
If yes how does one set up the DESCRIPTION file etc. to make it legit and pass CRAN checks?
You need to use Additional_repositories field in DESCRIPTION file. Location provided in that field has to contain expect directory structure, PACKAGES file in appropriate directory, and PACKAGES file has to have non-CRAN package listed.
Now going to your particular example of openNLPmodels.en package.
According to the way how you download and install this package it will not be possible to use it as dependency and pass on CRAN. openNLPmodels.en has to be published in a structure expected from R repository. Otherwise you don't have a valid location to put into Additional_repositories field.
What you can do is to download non-CRAN package and publish it in your R repository yourself, and then use that location in Additional_repositories field in your CRAN package.
Here is an example of how to do it:
dir.create("src/contrib", recursive=TRUE)
download.file("http://datacube.wu.ac.at/src/contrib/openNLPmodels.en_1.5-1.tar.gz", "src/contrib/openNLPmodels.en_1.5-1.tar.gz")
tools::write_PACKAGES("src/contrib")
We just put package sources in expected directory src/contrib and the rest is nicely handled by write_PACKAGES function. To ensure that repository is properly created you can list packages that are available in that repository:
available.packages(repos=file.path("file:/",getwd()))
It should list your non-CRAN package there.
Then having non-CRAN package published in R repository you should location of the repository into Additional_repositories field of your CRAN package. In this case location will be location returned by file.path("file:/",getwd()) expression.
Note that it uses location on your local machine, you will probably want to put it online, so that url can accessed by any machine checking your CRAN package, including checks on CRAN itself. For that just move your src directory to a public directory that is going to be hosted somewhere online and use the location of that server.
Now looking at your non-CRAN package again, we can see it has src/contrib in its url, thus we can assume that proper R repository already exists for it and we don't have to create and publish new one.
Therefore your installation instruction could look like
install.packages(
"openNLPmodels.en",
repos="http://datacube.wu.ac.at",
type="source"
)
And then all you need for your CRAN package is to use existing repository where it is available
Additional_repositories http://datacube.wu.ac.at
Its possible, but! ...
There is a field in the DESCRIPTION file that that you can use:
Additional_repositories: http://ghrr.github.io/drat
BUT!
Everything that depends on the functionality from the package from the additional repository has to be absolutely optional.
So packages from this repo should be placed under Suggests.
Example
I am not 100% sure whether or not BioConductor and OmegaHat are considered mainstream or not.
The usethis::use_dev_package function has solved this problem.
As an example, running this line:
usethis::use_dev_package(package = "h3", type = "Imports", remote = "crazycapivara/h3-r")
will automatically write the following lines to your DESCRIPTION file:
Imports:
h3 (>= 3.7.1)
Remotes:
crazycapivara/h3-r
Note that because github is the most commonly-used unofficial package distribution in R, it is the default. As such, make sure there is no github:: prefix to the entry in the Remotes section of the DESCRIPTION file.
Related
I want to use the R package BOLTSSIRR available on GitHub in my R package, which I want to upload to CRAN.
I listed BOLTSSIRR under Suggests: in the DESCRIPTION file and made the link to GitHub available using Additional_repositories: https://github.com/daviddaigithub/BOLTSSIRR.
However, running R CMD check --as-cran I get:
Suggests or Enhances not in mainstream repositories:
BOLTSSIRR
Availability using Additional_repositories specification:
BOLTSSIRR no ?
? ? https://github.com/daviddaigithub/BOLTSSIRR
Additional repositories with no packages:
https://github.com/daviddaigithub/BOLTSSIRR
So the GitHub link does not seem to get recognized in the check. Might I have to change something here?
As you found, you can't use Remotes in a CRAN package. What you need to do is to make sure the .tar.gz file for the package you are depending on is available somewhere. Github doesn't do that automatically, because https://github.com/daviddaigithub/BOLTSSIRR isn't set up as a package repository.
The solution is to create your own small repository, and keep copies of non-CRAN packages there. The drat package (available here: https://github.com/eddelbuettel/drat) makes this easy as long as you have a Github account: follow the instructions here: https://github.com/drat-base/drat. In summary:
Fork https://github.com/drat-base/drat into your account, and clone it to your own computer.
Enable Github Pages with the docs/ folder in the main branch.
Install the drat package into R using remotes::install_github("eddelbuettel/drat"). (I assume this version will make it to CRAN eventually; if you use the current CRAN version instructions are slightly more complicated.)
Build the package you want to insert. You need the source version; you might want binaries too, if those are hard for your users to build.
Run options(dratBranch="docs"); drat::insertPackage(...) to insert those files into your repository.
Commit the changes, and push them to Github.
In the package that needs to use this non-CRAN package, add
Additional_repositories: https://yourname.github.io/drat
to the DESCRIPTION.
You will be responsible for updating your repository if BOLTSSIRR is updated. This is good because the updates might break yours: after all, it's still in development mode. It's also bad because your users won't automatically get bug fixes.
That's it, if I haven't missed anything!
I was trying to use actions in a package I wrote. The issue is that the package actions uses remotes in its setup to install CRAN only packages.
Since the package I am working on depends on a non CRAN package that is present on GitHub, both coverage and R CMD checks fail. I tried to avoid this by naively downgrading to an earlier version of the package in depends but some functions are not exported. I am wondering if someone knows a workaround that might help(I cannot open an issue at actions since their support.md file discourages this).
If your package depends on a non-CRAN package, you must include under Remotes: rather than just Imports: in your DESCRIPTION file. Here you would have:
Imports:
actions
Remotes:
r-lib/actions
This will pass checks, but there is no work around for publishing to CRAN if any of your dependencies are not on CRAN, thus you'll get a warning if any packages are present in the Remotes field.
The alternative using Travis is adding r_github_packages: r-lib/actions to your .travis.yml.
After some time, I have found a workaround that for now is good enough if you want to test for the development version(like I wanted). You should include an install_github command in the check.yaml file. Here's an example:
- name: Install dependencies
run: |
install.packages(c("remotes","testthat"),dependencies=TRUE)
remotes::install_github("tidyverse/dplyr")
remotes::install_cran("covr")
shell: Rscript {0}
The above snippet fixed my issue because I wanted to depend on a future dplyr version. You can view the full yaml file here.
Packages on the Comprehensive R Archive Network (CRAN) can obviously directly import other packages that are on CRAN.
Can packages on CRAN also import packages that are not on CRAN? - if not, I guess the options are:
get the other package onto CRAN, or
abstract out the necessary parts to include directly (rather than import the entire package)
other methods?
I'm interested because sometimes a contribution makes more sense sitting in a separate package, especially if the contribution is likely to be used in its own right, or in other packages.
I don't think so.
Writing R Extensions specifies that you can include an Additional_repositories field in the DESCRIPTION file.
However, the CRAN Repository Policy says:
Packages on which a CRAN package depends should be available from a mainstream repository: if any mentioned in ‘Suggests’ or ‘Enhances’ fields are not from such a repository, where to obtain them at a repository should be specified in an ‘Additional_repositories’ field of the DESCRIPTION file (as a comma-separated list of repository URLs) or for other means of access, described in the ‘Description’ field.
"mainstream" here presumably means CRAN (and maybe? Bioconductor) (this bioc-devel thread from 2015 suggests that both CRAN and Bioconductor are "mainstream")
"depends" here means Imports/LinkingTo/Depends
I can't think of any solutions beyond the ones you suggest (get the package on CRAN or incorporate the necessary code in your package).
I'm developing an R package that works as a wrapper for functions from the parallel and Rhpc packages called ctools. I know that if I want my package to require these packages I need to include them in the Imports section of the DESCRIPTION file. When installing my package, these packages will be installed from CRAN. Similarly I can put them in the Suggests section if they aren't required, but useful. These won't be installed with my package.
But, I've forked the Rhpc package and added a function that I use in my ctools package. How do I get my package to Suggest/Import this package from my GitHub repo so of instead of installing the Rhpc package, it executes devtools::install_github("bamonroe/Rhpc")?
From the manual (and quoting source here):
#c DESCRIPTION field Additional_repositories
The #samp{Additional_repositories} field is a comma-separated list of
repository URLs where the packages named in the other fields may be
found. It is currently used by #command{R CMD check} to check that the
packages can be found, at least as source packages (which can be
installed on any platform).
You can add the package to Suggests: and point to additional repositories -- possibly created using drat. There used to a package doing that, and IIRC there is another one doing it now but its name escaped me now.
Edit: Found it! See here in the source DESCRIPTION file of RNeXML -- and note how the line disappears in the posted DESCRIPTION on CRAN. Better still, note how two of the packages in Suggests: are not listed a hyperlinks on CRAN. I thinks those come from the additional repos. And yes, rOpenSci uses drat to manage that.
Edit 2: And just to close the loop, you (easily) use drat to host such an additional repo on GitHub -- the prime use case for drat.
Edit 3: RNeXML has dropped the additional repository, but the github history still has it.
Edit 4: Currently (i.e. on 2020-03-13), the CRAN packages EMC, bcmaps, blkbox, broom.mixed, epikit, grattan, gtsummary, hurricaneexposure, memoise, multinomialeq, noaastormevents, pointblank, provSummarize, provViz, spData, swephR, tashu, taxadb, waveformbildar all list a field Additional_repositories containing a URL pointing to a drat repo.
I want to set up a local CRAN repository . I want to put just one package in this repository ( let's call it MyPackage ). The reason I'm doing this is that I want to share this package with people at my company. By the way - we all use Ubuntu Linux.
I have already done this:
I have a web server ( BOA web server ) and made a web folder called R. Made folder src and contrib.
In the contrib folder I put my package MyPackage ( tar.gz) plus the PACKAGES file.
However, when I do this:
install.packages("MyPackage", repos = "127.0.0.1/R" )
it does not work ;
Warning: unable to access index for repository [ ]
Warning message:
In getDependencies(pkgs, dependencies, available, lib) :
package ‘MyPackage’ is not available (for R version 2.13.1)
Can you guys guide me a bit and tell me what is the correct folder structure ?
Thanks.
See "Section 6.6 Setting up a package repository" of the R Admin manual.
Edit some three+ years later: We now have the drat package which automates creating a repository, and can use GitHub in a clever way to host it for you.
You might just need to specify the URL properly; http://127.0.0.1/R.
Also, make sure you can access that URL in your browser.
The miniCRAN works good for me. There are few advantages to using miniCRAN to create the repository:
Security: Many R users are accustomed to downloading and installing new R packages at will, from CRAN or one of its mirror sites.
Easier offline installation: To install package to an offline server requires that you also download all package dependencies, Using miniCRAN makes it easier to get all dependencies in the correct format.
Improved version management: In a multiuser environment, there are good reasons to avoid unrestricted installation of multiple package versions on the server.
Use other R Package Indexes: You may wish to make packages available from public repositories other than CRAN, e.g. BioConductor, r-forge, OmegaHat, etc.
Prepare own R repo: You may wish to add custom in-house packages to your repository.
See intro:
Using miniCRAN to create a local CRAN repository
Create a local package repository using miniCRAN
I think the problem is revealed in this statement:
"In the contrib folder I put ... the PACKAGES file."
The PACKAGES file is an index for the repository. You need to create that file after your package files are placed in the repository directory. Don't copy and paste the PACKAGES file from another repository.
If I were you, here's what I would do. First, add the following code to your .Rprofile for a local repository:
utils::setRepositories(ind = 0, addURLs = c(WORK = "127.0.0.1/R"))
Restart R after changing your .Rprofile.
ind = 0 will indicate that you only want the local repository. Additional repositories can be included in the addURLs = option and are comma separated within the character vector.
Then, create the repository index:
tools::write_PACKAGES("127.0.0.1/R/src/contrib", verbose = TRUE)
After you do that, you should be able to generate a data frame that has a list of all the packages. For example, my_packages <- available.packages().
If you see packages in your repository data frame, then install using the following code:
install.packages("MyPackage")
For more information, please see here.