Skip to content

Commit 8e984a1

Browse files
use_claude_code() (#594)
1 parent e134d37 commit 8e984a1

File tree

5 files changed

+264
-0
lines changed

5 files changed

+264
-0
lines changed

.Rbuildignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,3 +20,4 @@ contributors.md
2020
^data-raw$
2121
^[\.]?air\.toml$
2222
^\.vscode$
23+
^\.claude$

.claude/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
settings.local.json

.claude/CLAUDE.md

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
## R package development
2+
3+
### Key commands
4+
5+
```
6+
# To run code
7+
Rscript -e "devtools::load_all(); code"
8+
9+
# To run all tests
10+
Rscript -e "devtools::test()"
11+
12+
# To run all tests for files starting with {name}
13+
Rscript -e "devtools::test(filter = '^{name}')"
14+
15+
# To run all tests for R/{name}.R
16+
Rscript -e "devtools::test_active_file('R/{name}.R')"
17+
18+
# To run a single test "blah" for R/{name}.R
19+
Rscript -e "devtools::test_active_file('R/{name}.R', desc = 'blah')"
20+
21+
# To document the package
22+
Rscript -e "devtools::document()"
23+
24+
# To check pkgdown documentation
25+
Rscript -e "pkgdown::check_pkgdown()"
26+
27+
# To format code
28+
air format .
29+
```
30+
31+
### Coding
32+
33+
* Always run `air format .` after generating code
34+
* Use the base pipe operator (`|>`) not the magrittr pipe (`%>%`)
35+
* Don't use `_$x` or `_$[["x"]]` since dbplyr must work on R 4.1.
36+
* Use `\() ...` for single-line anonymous functions. For all other cases, use `function() {...}`
37+
38+
### Testing
39+
40+
- Tests for `R/{name}.R` go in `tests/testthat/test-{name}.R`.
41+
- All new code should have an accompanying test.
42+
- If there are existing tests, place new tests next to similar existing tests.
43+
- Strive to keep your tests minimal with few comments.
44+
45+
### Documentation
46+
47+
- Every user-facing function should be exported and have roxygen2 documentation.
48+
- Wrap roxygen comments at 80 characters.
49+
- Internal functions should not have roxygen documentation.
50+
- Whenever you add a new (non-internal) documentation topic, also add the topic to `_pkgdown.yml`.
51+
- Use `pkgdown::check_pkgdown()` to check that all topics are included in the reference index.
52+
53+
### `NEWS.md`
54+
55+
- Every user-facing change should be given a bullet in `NEWS.md`. Do not add bullets for small documentation changes or internal refactorings.
56+
- Each bullet should briefly describes the change to the end user, and mention the related issue in parentheses.
57+
- A bullet can consist of multiple sentences but should not contain any new lines (i.e. don't wrap the bullet).
58+
- If the change is related to a function, put the name of the function early in the bullet.
59+
- Order bullets alphabetically by function name. Put all bullets that don't mention function names at the beginning.
60+
61+
### Writing
62+
63+
- Use sentence case for headings.
64+
- Use US English.
65+
66+
### Proofreading
67+
68+
If the user asks you to proofread a file, act as an expert proofreader and editor with a deep understanding of clear, engaging, and well-structured writing.
69+
70+
Work paragraph by paragraph, always starting by making a TODO list that includes individual items for each top-level heading.
71+
72+
Fix spelling, grammar, and other minor problems without asking the user. Label any unclear, confusing, or ambiguous sentences with a FIXME comment.
73+
74+
Only report what you have changed.

.claude/settings.json

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
{
2+
3+
"permissions": {
4+
"$schema": "https://json.schemastore.org/claude-code-settings.json",
5+
"defaultMode": "acceptEdits",
6+
"allow": [
7+
"Bash(air:*)",
8+
"Bash(cat:*)",
9+
"Bash(find:*)",
10+
"Bash(gh issue list:*)",
11+
"Bash(gh issue view:*)",
12+
"Bash(gh pr diff:*)",
13+
"Bash(gh pr view:*)",
14+
"Bash(git checkout:*)",
15+
"Bash(git grep:*)",
16+
"Bash(grep:*)",
17+
"Bash(ls:*)",
18+
"Bash(R:*)",
19+
"Bash(rm:*)",
20+
"Bash(Rscript:*)",
21+
"Bash(sed:*)",
22+
"Skill(*)",
23+
"WebFetch(domain:cran.r-project.org)",
24+
"WebFetch(domain:github.com)",
25+
"WebFetch(domain:raw.githubusercontent.com)"
26+
],
27+
"deny": [
28+
"Read(.Renviron)",
29+
"Read(.env)"
30+
]
31+
}
32+
}
Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
---
2+
name: tidy-deprecate-function
3+
description: Guide for deprecating R functions/arguments. Use when a user asks to deprecate a function or parameter, including adding lifecycle warnings, updating documentation, adding NEWS entries, and updating tests.
4+
---
5+
6+
# Deprecate functions and function arguments
7+
8+
Use this skill when deprecating functions or function parameters in dbplyr.
9+
10+
## Overview
11+
12+
This skill guides you through the complete process of deprecating a function or parameter, ensuring all necessary changes are made consistently:
13+
14+
1. Add deprecation warning using `lifecycle::deprecate_warn()`.
15+
2. Silence deprecation warnings in existing tests.
16+
3. Add lifecycle badge to documentation.
17+
4. Add bullet point to NEWS.md.
18+
5. Create test for deprecation warning.
19+
20+
## Workflow
21+
22+
### Step 1: Determine deprecation version
23+
24+
Read the current version from DESCRIPTION and calculate the deprecation version:
25+
26+
- Current version format: `MAJOR.MINOR.PATCH.9000` (development).
27+
- Deprecation version: Next minor release `MAJOR.(MINOR+1).0`.
28+
- Example: If current version is `2.5.1.9000`, deprecation version is `2.6.0`.
29+
30+
### Step 2: Add `lifecycle::deprecate_warn()` call
31+
32+
Add the deprecation warning to the function:
33+
34+
```r
35+
# For a deprecated function:
36+
function_name <- function(...) {
37+
lifecycle::deprecate_warn("X.Y.0", "function_name()", "replacement_function()")
38+
# rest of function
39+
}
40+
41+
# For a deprecated parameter:
42+
function_name <- function(param1, deprecated_param = deprecated()) {
43+
if (lifecycle::is_present(deprecated_param)) {
44+
lifecycle::deprecate_warn("X.Y.0", "function_name(deprecated_param)")
45+
}
46+
# rest of function
47+
}
48+
```
49+
50+
Key points:
51+
52+
- First argument is the deprecation version string (e.g., "2.6.0").
53+
- Second argument describes what is deprecated (e.g., "function_name(param)").
54+
- Optional third argument suggests replacement.
55+
- Use `lifecycle::is_present()` to check if a deprecated parameter was supplied.
56+
57+
### Step 3: Update tests
58+
59+
Find all existing tests that use the deprecated function or parameter and silence lifecycle warnings. Add at the beginning of test blocks that use the deprecated feature:
60+
61+
```r
62+
test_that("existing test with deprecated feature", {
63+
withr::local_options(lifecycle_verbosity = "quiet")
64+
65+
# existing test code
66+
})
67+
```
68+
69+
Then add a new test to verify the deprecation message in the appropriate test file (usually `tests/testthat/test-{name}.R`):
70+
71+
```r
72+
test_that("function_name(deprecated_param) is deprecated", {
73+
expect_snapshot(. <- function_name(deprecated_param = value))
74+
})
75+
```
76+
77+
You'll need to supply any additional arguments to create a valid call.
78+
79+
Then run the tests and verify they pass.
80+
81+
### Step 4: Update documentation
82+
83+
For function deprecation, add to the description section:
84+
85+
```r
86+
#' @description
87+
#' `r lifecycle::badge("deprecated")`
88+
#'
89+
#' This function is deprecated. Please use [replacement_function()] instead.
90+
```
91+
92+
If the documentation does not already contain `@description`, you will need to add it.
93+
94+
For argument deprecation, add to the appropriate `@param` tag:
95+
96+
```r
97+
#' @param deprecated_param `r lifecycle::badge("deprecated")`
98+
```
99+
100+
When deprecating a function or parameter in favor of a replacement, add old/new examples to the `@examples` section to help users migrate. These should relace all existing examples.
101+
102+
```r
103+
#' @examples
104+
#' # Old:
105+
#' old_function(arg1, arg2)
106+
#' # New:
107+
#' replacement_function(arg1, arg2)
108+
#'
109+
#' # Old:
110+
#' x <- "value"
111+
#' old_function("prefix", x, "suffix")
112+
#' # New:
113+
#' replacement_function("prefix {x} suffix")
114+
```
115+
116+
Key points:
117+
118+
- Use "# Old:" and "# New:" comments to clearly show the transition.
119+
- Include 2-3 practical examples covering common use cases.
120+
- Make examples runnable and self-contained.
121+
- Show how the new syntax differs from the old.
122+
123+
Then re-document the package.
124+
125+
### Step 5: Add NEWS entry
126+
127+
Add a bullet point to the top of the "# dbplyr (development version)" section in NEWS.md:
128+
129+
```markdown
130+
# dbplyr (development version)
131+
132+
* `function_name(parameter)` is deprecated and will be removed in a future
133+
version.
134+
* `function_name()` is deprecated. Use `replacement_function()` instead.
135+
```
136+
137+
Place the entry:
138+
139+
- In the lifecycle subsection if it exists, otherwise at the top level under development version.
140+
- Include the replacement if known.
141+
- Keep entries concise and actionable.
142+
143+
## Implementation checklist
144+
145+
When deprecating a function or parameter, ensure you:
146+
147+
- [ ] Read DESCRIPTION to determine deprecation version.
148+
- [ ] Add `lifecycle::deprecate_warn()` call in the function.
149+
- [ ] Add `withr::local_options(lifecycle_verbosity = "quiet")` to existing tests.
150+
- [ ] Create new test for deprecation warning using `expect_snapshot()`.
151+
- [ ] Run tests to verify everything works.
152+
- [ ] Add lifecycle badge to roxygen documentation.
153+
- [ ] Add migration examples to `@examples` section (for function deprecation).
154+
- [ ] Run `devtools::document()` to update documentation.
155+
- [ ] Add bullet point to NEWS.md.
156+
- [ ] Run `air format .` to format code.

0 commit comments

Comments
 (0)