usethis 1.6.0

  devtools, usethis

  Hadley Wickham

We’re happy to announce that usethis 1.6.0 is now available on CRAN. usethis is a package that facilitates interactive workflows for R project creation and development. It’s mostly focussed on easing day-to-day package development, but many of its functions are also useful for non-package projects. Install usethis with:

install.packages("usethis")

This blog post discusses three sets of improvements to usethis:

  • New helpers for using GitHub Actions for continuous integration. If you’re an R package developer who uses GitHub, we recommend moving away from Travis and AppVeyor in favour of GitHub Actions.

  • We’ve made a number of small tweaks to create_package() in order to reduce inessential friction in the initial startup phase of a package.

  • We’ve continued to polish our tools for contributing to other people’s packages through GitHub pull requests.

This release also includes a handful of new functions (my favourite is rename_file()), many bug fixes, and lots of small improvements. We’re slowly grinding down the rough edges, so usethis just works in more cases, and when it fails, it’s more likely to give you error messages that help you quickly figure out the problem. As usual, you can find detailed notes about all these changes in the change log.

GitHub Actions

GitHub Actions is a continuous integration service that allows you to automatically run code whenever you push to GitHub. If you’re developing a package this allows you to automate tasks like:

  • Run R CMD check on multiple platforms (Linux, Windows, and Mac) and different versions of R (e.g., devel, release, oldrel).
  • Record the code coverage of your unit tests.
  • Re-build your pkgdown website.

Outside of a package, you can also use GitHub Actions to rebuild blogdown and bookdown sites, or regularly re-knit .Rmd files.

Each GitHub Actions workflow is described in a yaml file stored in the .github/workflows directory of your repository. usethis v1.6.0 introduces new helper functions to create these files:

You can see examples of other workflows at https://github.com/r-lib/actions/tree/master/examples. The files in this directory are templates that you can easily copy into your package by running use_github_action("name"). We encourage you to look at the .yaml files that these functions create and customise them to meet your needs.

Compared to Travis-CI, GitHub Actions:

  • Provides more resources, i.e. 6 hour build times and 20 concurrent builds instead of 50 minute build times and ~5 concurrent builds.

  • Has more complete support for building on Windows and macOS and a more natural way of using Docker containers.

  • Doesn’t require any extra authentication because all code is run on GitHub.

  • Is considerably easier to customise to provide workflows that we haven’t made easy.

You can learn more by reading Github Actions with R, by Chris Brown, Murray Cadzow, Paula A Martinez, Rhydwyn McGuire, David Neuzerling, David Wilkinson, and Saras Windecker, or watching Jim Hester’s rstudio::conf(2020) presentation.

Creating packages

Based on our experience teaching package development, we’ve made a few changes to how create_package() sets up a new package. The biggest difference is that we now assume that you’re going to use roxygen21 (although you can opt out with roxygen = FALSE), reducing some inconsistencies in development behaviours before and after your first run of devtools::document():

  • We automatically add a RoxygenNote field to the DESCRIPTION. This is a subtle change that ensures devtools::check() re-documents your package even when you haven’t yet run devtools::document().

  • The default NAMESPACE no longer exports anything. This means that you must always use @export if you want functions to be available to the end-user.

We made a couple of small changes to ease other minor frustrations:

  • use_rstudio() now sets the LineEndingConversion to Posix so that packages edited with RStudio always use LF line endings, regardless of platform. This reduces spurious changes when multiple people collaborate on the same package.

  • The usethis.description option now lets you set Authors@R = person() directly. That is, you can make an actual call to person() as opposed to writing a string that, when evaluated as code, returns a person(). This makes it less aggravating to detect and correct any mistakes. For example, in my .Rprofile I used to have:

    options(usethis.description = list(
      `Authors@R` = 'person("Hadley", "Wickham", , "hadley@rstudio.com", role = c("aut", "cre"))'
    ))
    

    And now I have:

    options(usethis.description = list(
      `Authors@R` = utils::person(
        "Hadley", "Wickham", , "hadley@rstudio.com",
        role = c("aut", "cre")
      )
    ))
    

    As you can see from the syntax highlighting, it’s now much easier to see if you’ve got all the quotes and commas in the right place. When you do this in .Rprofile, note that you must call it as utils::person().

Contributing to packages via GitHub pull requests

Based on our experiences at tidyverse developer day, we’ve tweaked the behaviour of usethis to ensure that new files have the same line ending as the rest of the project. We’ve also continued to polish our family of pull request helpers to work in more real-world situations. And, thanks to Mine Cetinkaya-Rundel, we now have an article that explains the overall workflow.

Thank you!

A big thanks to all 103 contributors who helped make this release happen via their contributions on GitHub. @aaronpeikert, @adelmofilho, @Ahobert, @alandipert, @andrie, @angela-li, @antoine-sachet, @aosmith16, @atusy, @avalcarcel9, @barryrowlingson, @batpigandme, @boshek, @cderv, @Cervangirard, @chsafouane, @coatless, @ColinFay, @CorradoLanera, @csgillespie, @cstepper, @davechilders, @davidchall, @DavisVaughan, @dchiu911, @dragosmg, @edgararuiz, @erindb, @espinielli, @fabian-s, @fermumen, @florianm, @fmichonneau, @friep, @gaborcsardi, @GegznaV, @GregorDeCillia, @hadley, @igordot, @ijlyttle, @IndrajeetPatil, @irenetlv, @isteves, @jdblischak, @jennybc, @jimhester, @jimmyg3g, @jmgirard, @JohnCoene, @jplecavalier, @jpritikin, @jrosen48, @jules32, @jzadra, @karawoo, @kevinushey, @kiernann, @krlmlr, @lettucehead, @leungi, @lionel-, @llrs, @lorenzwalthert, @maelle, @MagdyLaban, @malcolmbarrett, @Maschette, @matthijsvanderloos, @maurolepore, @maxheld83, @MichaelChirico, @mikmart, @MilesMcBain, @mine-cetinkaya-rundel, @mitchelloharawild, @muschellij2, @nandriychuk, @njtierney, @noamross, @okhoma, @overdodactyl, @pachamaltese, @pat-s, @perezp44, @petrbouchal, @phargarten2, @pieterjanvc, @ramiromagno, @riccardoporreca, @rich-iannone, @Robinlovelace, @romainfrancois, @rossellhayes, @rundel, @ryapric, @slyrus, @smingerson, @smwindecker, @strboul, @timtrice, @TylerGrantSmith, @VincentGuyader, and @wch.


  1. This seems like a reasonable assumption given that ~80% of new CRAN packages use roxygen2. ↩︎