usethis 1.5.0

  r-lib, usethis

  Jenny Bryan

We’re gratified to announce that usethis 1.5.0 is now available on CRAN. Learn more about usethis at https://usethis.r-lib.org. Detailed notes are always in the change log.

usethis is a package that facilitates interactive workflows for R project creation and development. It has broad coverage of package development tasks, but many of its functions are also applicable to non-package projects.

usethis is part of the package development toolkit whose main public face is the venerable devtools package. When devtools went through its conscious uncoupling, the functionality related to package/project setup landed in usethis.

Install the latest release of usethis like so:

install.packages("usethis")

devtools exposes all of usethis’s functions and most users should just use library(devtools) to make usethis available in the session.

library(devtools)

It is also, of course, possible to just attach usethis specifically.

library(usethis)

usethis::use_devtools() can help you put a code snippet in your .Rprofile to do this automatically at startup for interactive sessions.

Overview of recent developments

We last blogged about usethis in February 2018, at the release of v1.3.0, so there’s a lot to catch up on! We’ll cover cumulative developments in v1.4.0 and v1.5.0. The current release also marks the passing of the maintainership torch from Hadley Wickham to Jenny Bryan.

Main themes:

  • Improve support for the Git/GitHub aspects of project initiation and development.
  • Make it possible for others to extend usethis, i.e. to implement specialized workflows or organization-specific standards.
  • Implement what the tidyverse/r-lib team regards as best practices, often in functions that feature the word “tidy”. These are mostly for our use and are, honestly, occasionally aspirational, but others may find it interesting or useful.
  • Embrace the fs package internally for everything related to filepath management. We’re also gradually adding better tooling for programmatic management of specific files or for specific parts of a file, such as the badge section of README.Rmd.

Below we highlight specific changes or new features that are of special interest to users. Again, detailed notes are in the change log.

Options to set in .Rprofile

usethis consults certain options when it creates a new package and, if found, it favors this info over built-in defaults when populating the DESCRIPTION fields. devtools has long had this feature, but it’s a good time to open your .Rprofile (maybe via usethis::edit_r_profile()) and refresh your settings to look more like so:

options(
  usethis.full_name = "Jane Doe",
  usethis.description = list(
    `Authors@R` = 'person("Jane", "Doe", email = "jane@example.com", role = c("aut", "cre"), 
    comment = c(ORCID = "YOUR-ORCID-ID"))',
    License = "MIT + file LICENSE",
    Version = "0.0.0.9000"
  ),
  usethis.protocol  = "ssh"
)

Note the usethis.* name prefixes and that field-specific options like devtools.desc.author and devtools.desc.license have been replaced with a single named list, usethis.description. If you are firmly an “SSH person” or an “HTTPS person”, in terms of your preferred Git transport protocol, this is a great place to express that. It affects remote URLs created by usethis.

More setup tips can be found in the usethis setup article. For example, you will unlock a lot of usethis’s GitHub functionality by setting up a personal access token. usethis::browse_github_token() walks you through that process.

Git and GitHub

The git_sitrep() function gives a report on your current situation as a Git and GitHub user and specifics on the current repo’s remotes and branches. Here’s an example where Jane Doe is working in a local copy of OWNER’s package, maybe preparing to contribute a bug fix or new feature:

usethis::git_sitrep()
#> Git user
#> * Name: 'Jane Doe'
#> * Email: 'jane.doe@example.com'
#> * Vaccinated: TRUE
#> usethis + git2r
#> * Default usethis protocol: 'ssh'
#> * git2r supports SSH: TRUE
#> * Credentials: '<usethis + git2r default behaviour>'
#> GitHub
#> * Personal access token: '<found in env var>'
#> * User: 'janedoe'
#> * Name: 'Jane Doe'
#> Repo
#> * Path: '/Users/jane/tmp/REPO/.git'
#> * Local branch -> remote tracking branch: 'master' -> 'origin/master'
#> GitHub pull request readiness
#> * origin: janedoe/REPO, can push, forked from OWNER/REPO
#> * upstream: OWNER/REPO, read only

git_vaccinate() makes sure your global, i.e. user-level, gitignore file contains entries relevant to useRs. You are less likely to push confidential or unnecessary and semi-embarrassing information to GitHub if you gitignore files like .Rhistory and .Rdata.

Several other new functions are mostly for internal use but can also be used for troubleshooting and taking greater control of the Git side of usethis: git_remotes(), use_git_remote(), git_protocol(), use_git_protocol(), git_credentials(), use_git_credentials().

Two existing functions keep improving and deserve a mention:

  • create_from_github("OWNER/REPO) creates a local project from a GitHub repository. It’s pretty smart about when it should clone vs fork-and-clone (or you can specify this) and, when it forks, it sets up the origin and upstream remotes correctly.

    usethis::create_from_github("OWNER/REPO", protocol = "ssh")
    #> ✔ Creating '/Users/jane/rrr/REPO/'
    #> ✔ Forking 'OWNER/REPO'
    #> ✔ Cloning repo from 'git@github.com:janedoe/REPO.git' into '/Users/jane/rrr/REPO'
    #> ✔ Setting active project to '/Users/jane/rrr/REPO'
    #> ✔ Adding 'upstream' remote: 'git@github.com:OWNER/REPO.git'
    #> ✔ Pulling changes from GitHub source repo 'upstream/master'
    
  • use_github() connects an existing local repo to GitHub post hoc. It is more robust and, when it fails, it does so early and with actionable messages about what you can fix.

A new experimental family of pr_*() functions makes GitHub pull requests (PR) easier, both for maintainers and contributors. We’re quite excited about these, as we handle an extraordinary number of pull requests across the tidyverse, r-lib, and tidymodels organizations. For maintainers, pr_fetch(<PR_NUMBER>) allows you to check out a PR locally, explore it, check/test it, or even fix or extend it. pr_push() pushes back into the actual PR, where it can now be merged or receive more work from the original author. For contributors, pr_init() and pr_push() help to initiate a PR. In all cases, pr_finish() does the necessary local clean up when the PR is no longer in play.

Extending usethis

We’ve made usethis easier for others to wrap and extend:

  • usethis is very chatty and this is now under the control of the option usethis.quiet. This makes it easier for a wrapper to muffle usethis’s messaging or to temporarily toggle it with functions like withr::with_options() or withr::local_options().
  • Project-related helpers proj_path(), with_project(), local_project(), and proj_activate() are exported.
  • File editing helpers edit_file(), write_over(), and write_union() are exported.
  • use_template() can use a template file stored in any package, not just usethis.

We’ve also exported the ui_*() functions that implement usethis’s messaging, conditions, and interactive menus. This is in response to repeated community requests. These functions benefit greatly from the glue and crayon packages to provide nifty features like string interpolation and formatting.

There are inline styles (ui_field(), ui_value(), ui_path(), ui_code()), which can be used within the block styles (ui_line(), ui_done(), ui_todo(), ui_oops(), ui_info()). Some example usage (flanking newlines added for readability):

ui_stop() and ui_warn() raise the associated condition, but with the same features for the message:

Finally, ui_yeah() and ui_nope() facilitate control flow based on user input:

These functions may ultimately move to a more appropriate home, so we can use them to create a more consistent UI across a broad set of tidyverse, r-lib, and tidymodels packages.

Acknowledgements

We give a tremendous thanks to the 108 useRs who contributed to the v1.4.0 and v1.5.0 releases, especially those who joined us at the inaugural Tidyverse Developer Day following rstudio::conf 2019:

@Aariq, @adam-gruer, @akgold, @alandipert, @alexpghayes, @andrie, @angela-li, @apreshill, @atheriel, @batpigandme, @beanumber, @behrman, @benmarwick, @bestdan, @bfgray3, @boshek, @cboettig, @cderv, @chris-billingham, @Chris-Engelhardt, @chris-prener, @coatless, @colearendt, @cwickham, @dirkschumacher, @dpprdan, @dragosmg, @duckmayr, @echasnovski, @EmilHvitfeldt, @erictleung, @etiennebr, @Fazendaaa, @friendly, @gaborcsardi, @gadenbuie, @GregorDeCillia, @GShotwell, @gvelasq, @hadley, @hafen, @HanjoStudy, @haozhu233, @heavywatal, @ijlyttle, @IndrajeetPatil, @jackwasey, @Jadamso, @jayhesselberth, @JBGruber, @jdblischak, @jennybc, @jimhester, @jjchern, @jmgirard, @jonocarroll, @jonthegeek, @jooyoungseo, @jsta, @jtr13, @karawoo, @kevinushey, @khailper, @kiwiroy, @krlmlr, @lbusett, @leonawicz, @lionel-, @llrs, @lorenzwalthert, @lwjohnst86, @maelle, @maislind, @markdly, @martinjhnhadley, @MatthieuStigler, @maurolepore, @maxheld83, @mdlincoln, @mine-cetinkaya-rundel, @MishaCivey, @mkearney, @move[bot], @muschellij2, @nbrgraphs, @nijibabulu, @njtierney, @noamross, @overmar, @pat-s, @petermeissner, @romainfrancois, @rorynolan, @ryapric, @sriharitn, @statquant, @statwonk, @strboul, @stufield, @tgerke, @thomasp85, @topepo, @trestletech, @VerenaHeld, @VincentGuyader, @vnijs, @webbedfeet, and @wlandau