|
| 1 | +# NA |
| 2 | + |
| 3 | +## This package |
| 4 | + |
| 5 | +## Package development |
| 6 | + |
| 7 | +### Key commands |
| 8 | + |
| 9 | +``` r |
| 10 | + |
| 11 | +# To run code |
| 12 | +devtools::load_all() |
| 13 | +code |
| 14 | + |
| 15 | +# To run all tests |
| 16 | +devtools::test() |
| 17 | + |
| 18 | +# To run all tests for files starting with {name} |
| 19 | +devtools::test(filter = '^{name}') |
| 20 | + |
| 21 | +# To run all tests for R/{name}.R |
| 22 | +devtools::test_active_file('R/{name}.R') |
| 23 | + |
| 24 | +# To run a single test with exact description "blah" (no regexp) |
| 25 | +devtools::test_active_file('R/{name}.R', desc = 'blah') |
| 26 | + |
| 27 | +# To redocument the package |
| 28 | +devtools::document() |
| 29 | + |
| 30 | +# To check pkgdown documentation |
| 31 | +pkgdown::check_pkgdown() |
| 32 | + |
| 33 | +# To check the package with R CMD check |
| 34 | +devtools::check() |
| 35 | +``` |
| 36 | + |
| 37 | +There are three possible ways to run code, listed in rough order of |
| 38 | +desirability: |
| 39 | + |
| 40 | +- If you’re running inside Posit Assistant or otherwise have an |
| 41 | + `executeCode()` tool available, use it to run code in a session that |
| 42 | + the user can also interact with. |
| 43 | + |
| 44 | +- Otherwise, if an R REPL (e.g. `mcp__r__repl` or `btw::run_r`) is |
| 45 | + available, use that. Note that `mcp__r__repl` uses a sandbox that |
| 46 | + blocks network requests and reads/writes outside of the current |
| 47 | + directory. |
| 48 | + |
| 49 | +- Otherwise, use `Rscript -e "code"`. |
| 50 | + |
| 51 | +### Coding |
| 52 | + |
| 53 | +- Always run `air format .` after generating code. |
| 54 | +- Use the base pipe operator (`|>`), not the magrittr pipe (`%>%`). |
| 55 | +- Use `\() ...` for single-line anonymous functions. For all other |
| 56 | + cases, use `function() {...}`. |
| 57 | + |
| 58 | +### Testing |
| 59 | + |
| 60 | +- Tests for `R/{name}.R` go in `tests/testthat/test-{name}.R`. |
| 61 | +- All new code should have an accompanying test. |
| 62 | +- If there are existing tests, place new tests next to similar existing |
| 63 | + tests. |
| 64 | +- Strive to keep your tests minimal with few comments. |
| 65 | +- Never put code in a `test-{name}.R` file outside of a `test_that()` |
| 66 | + block. Instead, use `tests/testthat/helper.R` or |
| 67 | + `tests/testthat/helper-{name}.R`. |
| 68 | +- Avoid `expect_true()` and `expect_false()` in favor of a specific |
| 69 | + expectation with a better failure message. A few expectations in newer |
| 70 | + releases that you might not know about are `expect_all_true()`, |
| 71 | + `expect_all_equal()`, and `expect_r6_class()`. |
| 72 | +- When testing errors and warnings, don’t use `expect_error()` or |
| 73 | + `expect_warning()`. Instead, use `expect_snapshot(error = TRUE)` for |
| 74 | + errors and `expect_snapshot()` for warnings because these allow the |
| 75 | + user to review the full text of the output. |
| 76 | +- Avoid the `.package` argument to `local_mocked_bindings()`; this |
| 77 | + modifies the namespace of another package, which is not good practice. |
| 78 | + Instead create a mockable version of the function in the current |
| 79 | + package. See `?local_mocked_bindings` for more details. |
| 80 | + |
| 81 | +### Documentation |
| 82 | + |
| 83 | +- Every user-facing function should be exported and have roxygen2 |
| 84 | + documentation. |
| 85 | +- Internal functions should not have roxygen documentation. |
| 86 | +- Wrap roxygen2 comments to 80 characters. |
| 87 | +- Whenever you add a new (non-internal) documentation topic, also add |
| 88 | + the topic to `_pkgdown.yml`. |
| 89 | +- Always re-document the package after changing a roxygen2 comment. |
| 90 | +- Use |
| 91 | + [`pkgdown::check_pkgdown()`](https://pkgdown.r-lib.org/reference/check_pkgdown.html) |
| 92 | + to check that all topics are included in the reference index. |
| 93 | + |
| 94 | +### `NEWS.md` |
| 95 | + |
| 96 | +- Every user-facing change should be given a bullet in `NEWS.md`. |
| 97 | +- Changes that shouldn’t get a bullet: |
| 98 | + - Small documentation changes. |
| 99 | + - Internal refactorings. |
| 100 | + - Fixes to bugs introduced in the current dev version. |
| 101 | +- Each bullet should briefly describe the change to the end user and |
| 102 | + mention the related issue in parentheses. |
| 103 | +- A bullet can consist of multiple sentences but should not contain any |
| 104 | + newlines (i.e. DO NOT line wrap). |
| 105 | +- If the change is related to a function, put the name of the function |
| 106 | + early in the bullet. |
| 107 | +- Order bullets alphabetically by function name. Put all bullets that |
| 108 | + don’t mention function names at the beginning. |
| 109 | + |
| 110 | +## Specialized skills |
| 111 | + |
| 112 | +- Do you need to deprecate a function or argument? Read the output of |
| 113 | + `usethis::learn_tidy_skill("deprecate")`. |
| 114 | +- Are you adding input checking to an existing function or writing a new |
| 115 | + exported function? Read the output of |
| 116 | + `usethis::learn_tidy_skill("arg-checking")`. |
| 117 | + |
| 118 | +## Writing |
| 119 | + |
| 120 | +- Use sentence case for headings. |
| 121 | +- Use US English. |
| 122 | + |
| 123 | +### Proofreading |
| 124 | + |
| 125 | +If the user asks you to proofread a file, act as an expert proofreader |
| 126 | +and editor with a deep understanding of clear, engaging, and |
| 127 | +well-structured writing. |
| 128 | + |
| 129 | +Work paragraph by paragraph, always starting by making a TODO list that |
| 130 | +includes individual items for each top-level section. |
| 131 | + |
| 132 | +Fix spelling, grammar, and other minor problems without asking the user. |
| 133 | +Label any unclear, confusing, or ambiguous sentences with a FIXME |
| 134 | +comment. |
| 135 | + |
| 136 | +Only report what you have changed. |
0 commit comments