Add graph_downloads() function - #518
d-morrison wants to merge 63 commits into
Conversation
Plots new and cumulative downloads from CRAN, with optional GitHub release download tracking (off by default). Exported with keywords internal. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Adds a new internal-but-exported function graph_downloads() that fetches CRAN download stats (via cranlogs) and optionally GitHub release download stats (via gh), then renders a faceted ggplot of new and cumulative downloads.
Changes:
- New
R/graph_downloads.Rimplementinggraph_downloads(github = FALSE)with CRAN-only or CRAN+GitHub 2x2 facet output. - New
.positai/settings.jsonwith editor/tooling permission settings.
Reviewed changes
Copilot reviewed 4 out of 4 changed files in this pull request and generated 7 comments.
| File | Description |
|---|---|
| R/graph_downloads.R | Implements the new plotting helper, exported with @keywords internal; depends on cranlogs and gh. |
| .positai/settings.json | Adds local Positai permission configuration. |
Codecov Report✅ All modified and coverable lines are covered by tests. |
…ptions Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- Add cranlogs and gh to Suggests in DESCRIPTION - Pin purrr >= 1.0.0 - Add .positai/ to .Rbuildignore - Use .data$ prefix for all column references (avoids R CMD check NOTEs) - Fix first GitHub release downloads being dropped (was hard-coded to 0) - Run devtools::document() to generate NAMESPACE export and man page Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Rename 'source' column to 'provider' to avoid undesirable_function_linter flagging it as the source() function. Wrap long lines to stay under 80 chars. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract .check_suggests(), .fetch_cran_downloads(), .fetch_github_downloads(), .aggregate_by_unit(), .prepare_download_data(), and .plot_downloads() to keep all functions under 100 lines. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
packageRank::cranDownloads() provides daily data 2with cumulative counts already computed, replacing our manual cranlogs fetch and cumsum calculation. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
is.null(start) inside filter() produced a length-0 logical via the | operator. Use an if-guard instead. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
@claude review |
|
Claude finished @d-morrison's task in 2m 29s —— View job Code ReviewTasks:
Overall this PR is well-structured — the split into single-responsibility helper files is clean, the Bugs / Correctness1. Stale
# graph_downloads.R line 2 — should be:
#' Fetches download data from CRAN (via `packageRank`) and optionally GitHub2. Empty GitHub releases → error in In if (nrow(github_releases) == 0L) {
return(tibble::tibble(date = Date(), provider = character(),
new = integer(), cumulative = integer()))
}3.
Design Issues (previously flagged by Copilot — still unaddressed)4. Hard-coded package name, GitHub owner, and start date
5. Missing
6. This is a local editor configuration file. It's correctly excluded from the package build via Minor Notes7. GitHub "new downloads" semantics The 8. Facet layout direction When 9. No tests for any new code (0% coverage) The Copilot review noted this. The pure data-shaping helpers — |
Tests cover .aggregate_by_unit(), .prepare_download_data(), .plot_downloads(), .check_suggests(), and input validation. Uses mock data fixtures and vdiffr for visual regression. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Historical CRAN download counts are stable, making them reliable fixtures. GitHub data is still synthetic since real data has zero downloads (no release assets). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Added to copilot-instructions.md and new CLAUDE.md. Prefer pipes (|>) over nesting in all R code including tests. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Extract into named variables instead. Updated both CLAUDE.md and copilot-instructions.md. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Apply no-function-calls-as-arguments rule: extract Sys.Date(), as.Date(), min(), names(), seq(), and tidyr::replace_na() calls into intermediate variables. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ownloads() Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
- paste() calls into msg before cli::cli_abort() - ggplot2::aes() into mapping before ggplot() - scales::label_comma() into comma_labels - dplyr::all_of() into metric_cols - factor() piped from .data$metric Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
graph_downloads() and .fetch_cran_downloads() now accept ... for additional cranDownloads() arguments. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
|
Committed. Here's a summary of what was done: Changes in this commit (
What's already in place from the prior commit (
Note: The 7 stub files can't be fully deleted in this automated context (file deletion requires interactive approval). A follow-up — posted by @claude post-step from workflow run |
This comment has been minimized.
This comment has been minimized.
gdl::graph_downloads() does not accept a 'github' argument; it determines GitHub inclusion from whether 'github_repo' is non-NULL. Passing 'github' leaked through ... into packageRank::cranDownloads(), causing an 'unused argument' error. Translate the 'github' flag into 'github_repo' (NULL when FALSE) and match.arg(unit) so a single unit is passed.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
The gdl-delegated graph_downloads() test failed in R CMD check because gdl resolves CRAN downloads via packageRank, an optional gdl dependency that is not installed transitively. Re-add packageRank to Suggests so it is available, and guard the test with skip_if_not_installed()/ skip_if_offline() for robustness. Point codecov's network-wrapper ignore list at R/graph_downloads.R (the prior entries were moved to gdl) and add 'packageRank' to WORDLIST.
This comment has been minimized.
This comment has been minimized.
|
Working on this — paws off until I'm done. Generated by Claude Code |
…t artifacts - .positai/settings.json was committed before .positai/ was added to .gitignore, so it stayed tracked; stop tracking it now. - Remove the SVG snapshots, fixture RDS, and comment-only helper left over from the old internal graph_downloads() implementation now that the function delegates to gdl::graph_downloads(); none of them are referenced by the current test. - Drop @Keywords internal from graph_downloads() to match its explicit listing in pkgdown/_pkgdown.yml under "Visualize data", and trim the roxygen description to stop naming gdl's internal backend deps. - Drop the vestigial purrr (>= 1.0.0) version pin; the constraint was for list_rbind() in now-deleted helpers, and remaining purrr usage predates 1.0.0. Addresses the must-fix items flagged in the most recent review round (2026-06-05): #518 (comment)
ARD summary — latest review round (2026-06-05, comment)Pushed Must-fix items — Addressed:
Design/minor items from the same round — Addressed:
Earlier-round items — not revisited this round: the first-round Copilot findings (hardcoded package name/owner, missing unit tests, CI was green on the prior commit; re-running now against Generated by Claude Code |
|
Done for now — unclaimed. Generated by Claude Code |
|
Working on this (syncing with Generated by Claude Code |
# Conflicts: # DESCRIPTION # inst/WORDLIST
|
Synced with Heads-up: Generated by Claude Code |
|
👀 Picked up by workflow run #29481428820. Setup runs first; Claude itself responds after that. |
Code ReviewThis is a confirming review. All previously flagged must-fix items from the prior review are resolved in the current diff (head
The current implementation ( New (minor, non-blocking) observations
VerdictReady for merge — all prior must-fix items are resolved; only optional |
|
Claude finished review — View run Posted the confirming review to the PR: #518 (comment) Summary of findings: All previously flagged must-fix items are now resolved. The PR was substantially reworked since the last review round — the old internal implementation (which had the New minor, non-blocking observations in
None of these affect Verdict: Ready for merge |
|
📖 https://UCD-SERG.github.io/serocalculator/preview/pr518/ |
cranlogs, cranDownloads, cran, and validatePackage were added for the internal CRAN-fetching implementation that has since been replaced by the gdl wrapper; Serological was duplicated. None of these appear in any doc source anymore.
|
The WORDLIST diff against The PR's automated code-review already ran independently (comment #4989530112) and gave a "Ready for merge" verdict, flagging only cosmetic
I also independently re-ran — posted by @claude post-step from workflow run 💰 Cost: $1.602977 |
Summary
graph_downloads()to plot new and cumulative package download counts from CRAN (viapackageRank), with optional GitHub release download trackingday,week,month,quarter,year), start date filtering, and custom titles.fetch_cran_downloads(),.fetch_github_downloads(),.aggregate_by_unit(),.prepare_download_data(),.plot_downloads(),.check_suggests())@keywords internalCLAUDE.mdand updates copilot instructions with no-nested-function-calls ruleTest plan
graph_downloads()renders CRAN-only plot (default)graph_downloads(github = TRUE)renders 2x2 facet gridgraph_downloads(cumulative = FALSE)renders single-metric plotgraph_downloads(start = "2025-01-01")filters by dategraph_downloads(unit = "week")aggregates by weekgraph_downloads(new = FALSE, cumulative = FALSE)errorsdevtools::test())lintr::lint_package())devtools::document())🤖 Generated with Claude Code