Table of Contents generated with DocToc
- Contributing to wehoop
Thank you for your interest in contributing to wehoop! This guide will help you get started.
Development Setup
- Fork and clone the repository
-
Install dependencies: Open the project in RStudio and run
devtools::install_deps(dependencies = TRUE) -
Create a feature branch from
main:git checkout -b feat/your-feature main
Workflow
Making Changes
- Edit source code in
R/ - Regenerate docs:
devtools::document() - Run tests:
devtools::test() - Check the package:
devtools::check()
Adding a New WNBA Stats API Endpoint
-
Create the function in the appropriate
R/wnba_stats_*.Rfile following the existing pattern:- Use
wnba_endpoint()+request_with_proxy()for HTTP - Parse response with
purrr::pluck()->data.frame()->janitor::clean_names()->make_wehoop_data() - Use
%||%(rlang) for null safety on every extracted field
- Use
-
Add roxygen docs with
@export,@family,@return(including column markdown tables), and@detailsexample -
Create a test in
tests/testthat/withskip_on_cran()andskip_on_ci()guards - Update NEWS.md with a description of the new function
- Run
devtools::document()to update NAMESPACE
Naming Conventions
Function Names
| Data Source | Prefix | Example |
|---|---|---|
| WNBA Stats API | wnba_ |
wnba_leagueleaders(), wnba_boxscoretraditionalv3()
|
| ESPN WNBA | espn_wnba_ |
espn_wnba_pbp(), espn_wnba_teams()
|
| ESPN WBB | espn_wbb_ |
espn_wbb_pbp(), espn_wbb_teams()
|
| NCAA WBB | ncaa_wbb_ |
ncaa_wbb_teams() |
| Data loaders |
load_wnba_ / load_wbb_
|
load_wnba_pbp(), load_wbb_team_box()
|
General Naming Rules
- snake_case for all function names, variables, and parameters
-
Internal helpers (not exported) are prefixed with
.(e.g.,.players_on_court_v3_wnba()) -
Parameter names use
snake_casein R, mapped toPascalCasefor the WNBA Stats API (e.g.,game_id->GameID) -
Game IDs must always be passed through
pad_id()before API calls (zero-pads to 10 digits) -
File names follow the pattern
R/wnba_stats_*.R,R/espn_*.R,R/ncaa_wbb_*.R
V2 vs V3 API Patterns
-
V2 endpoints (e.g.,
boxscoretraditionalv2): ReturnresultSets[].headers[] + rowSet[][]. Parsed viawnba_stats_map_result_sets(). -
V3 endpoints (e.g.,
boxscoretraditionalv3): Return nested JSON. Parsed viapurrr::pluck()->data.frame()-> pipeline.
Data Processing Pipeline
All returned data frames must pass through:
raw_data %>%
data.frame(stringsAsFactors = FALSE) %>%
dplyr::as_tibble() %>%
janitor::clean_names() %>%
make_wehoop_data("Description from WNBA.com", Sys.time())Roxygen Documentation
Every exported function needs:
-
@nameand@rdnametags withNULLobject preceding the function -
@titlewith bold markdown description -
@authortag -
@paramfor every parameter (including...) -
@returnwith markdown tables documenting column names and types -
@importFromfor specific function imports @export-
@familyfor grouping in pkgdown (e.g.,"WNBA PBP Functions","WNBA Boxscore V3 Functions") -
@detailswith a runnable example code block
Code Style
- Follow tidyverse style:
snake_case, 2-space indentation - Internal helpers start with
.(e.g.,.players_on_court_v3_wnba()) - Game IDs must be passed through
pad_id()before API calls - Use
%||%(rlang) for null-safe defaults when parsing API responses
Commit Messages
Use Conventional Commits:
feat: add wnba_playbyplayv3() endpoint wrapper
fix: correct WNBA time calculations for 10-min quarters
docs: update roxygen for wnba_pbp() version param
test: add column validation for V3 boxscore endpoints
refactor: extract clock parsing into helper
chore: update .Rbuildignore
ci: update GitHub Actions workflow versions
Optional scope is encouraged for clarity (e.g., feat(pbp): ..., docs(instructions): ...). Use type!: or a BREAKING CHANGE: footer for breaking changes. Split unrelated work into separate commits for reviewability.
Important: Never include AI agents or assistants (e.g., Claude, Copilot) as co-authors on commits. Omit all Co-Authored-By trailers referencing AI tools.
Pull Requests
- Target the
mainbranch - Include a clear description of what changed and why
- Ensure
devtools::check()passes with no errors or warnings - Add tests for new functions
- Update NEWS.md for user-facing changes
Testing
Test Pattern
When writing tests for WNBA Stats API endpoints, follow this pattern:
test_that("WNBA Endpoint Name", {
skip_on_cran()
skip_on_ci()
x <- wnba_function(game_id = "1022200034")
cols_x1 <- c("col1", "col2", ...)
expect_in(sort(cols_x1), sort(colnames(x[[1]])))
expect_s3_class(x[[1]], "data.frame")
Sys.sleep(3) # Rate limiting
})For intermittent or empty responses:
if (length(x) == 0 || is.null(x[[1]]) || nrow(x[[1]]) == 0) {
skip("No rows returned from endpoint at test time")
}Note: All API tests are skipped on CRAN (skip_on_cran()) and CI (skip_on_ci()) by default. They require network access and valid API responses.
CI / GitHub Actions
The repository uses GitHub Actions for R CMD check and pkgdown site deployment. The following secrets should be configured:
| Secret | Used By | Description |
|---|---|---|
GITHUB_TOKEN |
All workflows | Auto-provided by GitHub |
Reporting Issues
When filing a bug report, please include:
- A minimal reprex (reproducible example) using
reprex::reprex() - The game ID or parameters used
- Your
sessionInfo()output - The specific error message or unexpected output
Use the bug report template when opening a new issue.
License
By contributing, you agree that your contributions will be licensed under the MIT License.
