Development guidelines
The following points are here for the developers to make sure they are following consistent standards.
Development workflow
- Create a feature or bugfix branch (see branching)
- Development (see details in function writing)
- Write function-specific unit tests(
devtools::use_test('test_name')
- Document the changes (
devtools::document()
or Ctrl+Shift+D)
- Check all unit tests pass in the package (
devtools::test()
)
- Check if there are any other issues in the package by running a R CMD check (
devtools::check()
)
- Make sure the lock file for {renv} is up to date if you added any new packages/dependencies.
- Push and create a pull request (PR) from your feature branch in to the develop branch
- If there are any merge conflicts, merge the develop branch in to your feature branch and solve the conflicts in the feature branch (see Resolving git conflicts
Branching
We will have a main
branch, and a develop
branch. When tackling an issue which has a corresponding issue/ticket, create a branchticketY
from develop
, where Y
is the ticket number/ID (can optionally extend the branch name with a succinct description of the work required e.g. ticketY-fix-bug-x
). Once the work is complete and tested, create a pull request for the branch ticketY
in to develop
.
When we are ready to make a new release, we will merge develop
in to main
.
Package building
- We use
devtools
, usethis
, testthat
and renv
packages for package development.
- We namespace calls to functions from other packages, e.g.
dplyr::filter()
, and specify a dependency on that package in the DESCRIPTION file (usethis::use_package('package_name')
)
- If a function is used very often in a package (e.g. the magrtittr pipe), we can use a central script with roxygen’s
@importFrom
to simplify things.
See R packages by Hadley Wickham for reference.
Function Writing
- Create a new .R script in
/R
: `usethis::use_r(‘script_name’)
- Add the roxygen skeletion: Ctrl+Alt+Shift+R.
- Update the title.
- Always document the argument type, as well as its description e.g.
@param x {numeric} a number of iterations
.
- Define the expected output using
@return
, e.g. @return A numeric vector of length 1
.
- Export all the functions relevant to package users using the @export (can be skipped for internal/utils functions).
- Where possible, provide examples (in
@examples
).
- You can interactively test your code by mocking attaching the package with
devtools::load_all()
.
Dependency Management with {renv}
- Reference renv vignette
- Ensure you’re working with the correct version of R itself: You can look up the version in the
renv.lock
file which you can open in regualr editor or RStudio. You can change the version of R in the topright corner of RStudio Server.
renv::init()
: Initializes the current working directory as a renv project. Run it when starting a new R Project.
renv::snapshot()
: Save the current state of your library. Run after installing a new package.
renv::restore()
: Restore the library state saved in the most recent snapshot. Run after pulling a branch when you want to restore the latest library state.
Merge review workflow
- Pull the branch to be reviewed (in Shell:
git checkout origin/branch_to_review
).
- Understand the scope of the feature and expected outputs.
- Try to break the developed functions by running it through different examples, unexpected/wrong inputs etc.
- Check if the function descriptions are clear and concise.
- Check if the newly developed functions have corresponding unit tests.
- Update the package documentation (
devtools::document()
)
- Check all unit tests pass (
devtools::test()
)
- Check if there are any other issues in the package (
devtools::check()
)
- If there are any major issues, request changes to the PR.
- When all the points have passed, approve the PR and delete the feature branch.
Release workflow (to be expanded to include CRAN steps)
- Pull latest
develop
branch
- Make sure documentation, tests and R CMD check all look good.
- Bump up package version in DESCRIPTION.
- Write achievements in NEWS.md
- Merge
develop
branch in to main
.
Git
Resolving git conflicts
- Make sure all your branches are up-to-date (by running
git fetch --all
and git pull
: the latter needs to be run for each of the branches of interest).
- Navigate to the branch you want to work on (e.g.
git checkout feature-branch-name
).
- Make a merge (e.g.
git merge develop
).
- If there are any conflicts, those will be listed in the Terminal/Shell and additionally marked orange in RStudio’s git screen. a) If you want to cancel the merge, run
git merge --abort
. b) If you’re happy to continue the merge, read on.
- Navigate to the conflicted files and edit them so that they contain the desired code version.
- Once finished, stage the changed files (
git add .
or git add file-name1 file-name2
).
- Confirm that all relevant files have been staged (
git status
- all staged files will appear green).
- Commit the changes (
git commit -m 'commit message'
).
- Your merge has been completed. To view the commit history (with commit numbers) run
git log
(press q
to return to the command line screen).
Undoing the changes
- If you want to move HEAD of the branch to one of the previous commits (e.g. undoing the merge) run
git reset --hard <commit-hash-to-move-to>
. This change will remove any changes/commits that were added after the specified commit.
- If you want to remove the merge while keeping the merge commit in the commit history, run
git revert -m 1 <merge commit hash>
.