Skip to contents

There are two ways to help. Anyone who uses the package can report a problem or ask for a feature, which needs no setup and is covered in the first section. The rest of this guide is for people comfortable with R packages who want to change the code or the documentation.

Everyone taking part is asked to follow the code of conduct.

Report a problem or ask for a feature

Colony managers see problems and needs that no test finds. All you need is a free GitHub account: open an Issue.

For a problem, please include:

  • What you did: the steps in the app (which tab, which buttons) or the shortest script that shows the problem.
  • What you expected, and what happened instead, with the exact wording of any error message.
  • Your package version and R setup. Run these in R and paste the output:
packageVersion("nprcgenekeepr")
sessionInfo()

Please show the problem with the package’s example data, such as nprcgenekeepr::examplePedigree, and do not post real colony records, because Issues are public. If a problem appears only with your own file, make a small made-up file with the same columns that shows it, or describe the columns and values involved.

For a feature, please say what you are trying to do, what decision it would help you make, and how you do it today.

Set up a copy of the package

You need R, git and a C/C++ compiler (Xcode Command Line Tools on a Mac, Rtools on Windows), because some packages may need building.

Fork the repository on GitHub, then clone your fork and open R in its folder:

git clone https://github.com/<your-account>/nprcgenekeepr.git
cd nprcgenekeepr
R

The project uses renv, which starts by itself when R opens in this folder and keeps what you install here apart from your other R libraries. Install the package versions the project records, then the development tools and your copy of the package, and answer yes when asked:

renv::restore()
renv::install(c("devtools", "lintr", "quarto", "roxygen2@8.0.0"))
devtools::install(upgrade = FALSE)

renv::restore() installs the versions recorded in renv.lock. The automatic checks on a pull request install current versions instead, so a package that has changed since can make a check fail there and not on your machine. roxygen2 is the version the package’s help pages were generated with, because another version rewrites many of them. The last command installs your copy of the package itself, which one of the tests needs.

Then restart R, because loading a package in the session that just replaced it can fail. To confirm it worked, load the package from your copy:

pkgload::load_all()

After that, every function in R/ is available, including ones not exported. runGeneKeepR() starts the Shiny app from your copy.

Where things live

Path What it holds
R/ The package’s functions, mostly one to a file, with their help written as roxygen comments.
R/appUI.R, R/appServer.R The Shiny app’s layout and server. Each tab is a module in its own file, such as R/modPedigree.R.
tests/testthat/ The tests. test_<name>.R files are ordinary tests; test-e2e-<name>.R files drive the app in a browser.
man/ Help pages generated from the roxygen comments. Do not edit these by hand.
vignettes/ The tutorial and manual that install with the package, such as vignettes/a2interactive.Rmd.
vignettes/articles/ Articles for the website only, such as vignettes/articles/colony-manager-guide.qmd.
inst/extdata/ Example files, and in inst/extdata/ui_guidance/ the help pages the app shows.
data/, data-raw/ Example datasets, and the scripts that build them.
NEWS.Rmd The release notes. NEWS.md is generated from it.
_pkgdown.yml The website’s menus and its function reference.

The other top-level files and folders hold working notes and release records. A pull request does not need to touch them.

Run the tests

To run one test file, which is what you will do most often:

Sys.setenv(NOT_CRAN = "true")
pkgload::load_all()
testthat::test_file("tests/testthat/test_kinship.R")

Setting NOT_CRAN matters: without it, a file that skips itself on CRAN does so silently and looks as if it passed.

Before opening a pull request, run the whole suite and the package check:

devtools::test()
devtools::check()

The browser tests are skipped unless you ask for them, because they need Chrome and take much longer. They test the installed package rather than the loaded one, so install your copy first. If you change something a tab shows, run the file for that tab:

devtools::install(upgrade = FALSE)
Sys.setenv(NOT_CRAN = "true", NPRC_RUN_E2E = "true")
testthat::test_file("tests/testthat/test-e2e-pedigree-module.R")

If the spelling test flags a word that is spelled correctly, add it to inst/WORDLIST. Some other tests read the documentation itself, and a failure there is telling you which page has fallen out of step.

Write tests with your change

A pull request that changes what the package does includes tests for that change. Cover the normal case, bad input, and the edge cases that matter for pedigrees, such as an empty input, a single animal, or missing parents and dates. Aim to cover more than 80% of the new code. Put the tests in tests/testthat/test_<name>.R, using the file for the function you changed if there is one:

test_that("findOffspring gives 0 for an animal with no offspring", {
  ped <- data.frame(
    id = c("sire1", "dam1", "kid1"),
    sire = c(NA, NA, "sire1"),
    dam = c(NA, NA, "dam1")
  )
  counts <- findOffspring(c("sire1", "kid1"), ped)
  expect_identical(counts[["sire1"]], 1L)
  expect_identical(counts[["kid1"]], 0L)
})

To test a Shiny tab, use shiny::testServer() as the test_mod<name>.R files do.

We recommend writing the failing test first: run it, see it fail for the reason you expect, write the smallest change that makes it pass, and then tidy up. This is how most of the package was built, and it often finds a misunderstanding before any code is written. It is not required of a pull request, as long as the tests are there and they pass.

A new test file also runs during CRAN’s check, which has a time limit. If yours takes more than half a second, add its name to tests/testthat/slowTestFiles.txt.

Check style with lint

pkgload::load_all()
lintr::lint_package()

This should report nothing. The rules are in .lintr, among them a limit of 80 characters per line; tests/ and vignettes/ are not linted.

Update the documentation

Most changes need one or more of these:

  • A function’s help. Edit the roxygen comments in R/, then run devtools::document(), which regenerates man/ and NAMESPACE. Check git status afterwards and commit only what belongs to your change.
  • A new exported function. Add it to a reference group in _pkgdown.yml. A test fails until it is listed.
  • Anything a user would notice. Add one plain line to NEWS.Rmd, under the section for the app tab it affects, then regenerate NEWS.md:
rmarkdown::render("NEWS.Rmd", quiet = TRUE)
  • A change to what a tab shows or does. Update that tab’s part of vignettes/articles/colony-manager-guide.qmd, and its help page in inst/extdata/ui_guidance/ if it has one.

Propose a change

  1. For anything larger than a small fix, open an Issue first, so we can agree on the approach before you spend time on it.
  2. Make your change on a new branch from master, keeping one change to a pull request.
  3. Run the tests, the package check and lint, as above.
  4. Open a pull request against master. Say what changed and why, and link the Issue if there is one.

Opening a pull request runs the package check, lint, test coverage and a website build automatically, and the results appear on the pull request. The browser tests run nightly on master, not on pull requests, so please run any that your change affects yourself. The maintainer then reviews the pull request.