- 后端
- Web框架
- 前端
【免费下载链接】shiny
Easy interactive web applications with R
Shiny 作为 R 生态中最具基础性的 Web 应用框架(DESCRIPTION 中定义为 “Web Application Framework for R”),其每一次开发版变更都可能波及成百上千个依赖它的下游包。为了在发版前量化这种影响,Shiny 仓库维护了revdep/反向依赖检查(reverse dependency check)目录,其中 revdep/revdep_cran.md 就是一次完整检查生成的摘要报告。本文将以这份报告为骨架,逐段讲解反向依赖检查的统计口径、报告结构、新问题(new problems)的处置闭环与无法检查(failed to check)的人工裁定,并结合仓库内其他快照与测试代码,还原一套可复用的 CRAN 兼容性保障工作流。
这份报告从哪来:什么是反向依赖检查
反向依赖(reverse dependency)指的是“依赖本包的其他包”。对于 Shiny 而言,任何Imports、Depends或Suggests中引用了shiny的 CRAN 或 Bioconductor 包,都是它的反向依赖。反向依赖检查要回答的问题非常明确:当前开发版 Shiny 的改动,有没有破坏下游包的构建与测试?
核心方法论:双环境 R CMD check 比对
revdep/revdep_cran.md 开篇即点出检查方法:
We checked 902 reverse dependencies (778 from CRAN + 124 from BioConductor), comparing R CMD check results across CRAN and dev versions of this package.
这句话包含三层关键信息:
- 检查对象:本次覆盖 902 个反向依赖包,其中 778 个来自 CRAN、124 个来自 Bioconductor;
- 检查方式:对每个下游包分别运行
R CMD check,但依赖环境不同——一次安装已发布到 CRAN 的 Shiny,另一次安装当前开发版 Shiny; - 比对逻辑:将两次检查结果逐包对照,找出只有开发版环境下才新出现的失败,这类差异才是 Shiny 自身改动可能引入的回归,值得优先排查。
从文件布局看,revdep/目录遵循 r-lib 生态标准反向依赖检查工具 revdepcheck 的产物约定:摘要报告以 Markdown 提交入库,而原始检查数据库与逐包失败详情则被排除在版本控制之外。revdep/.gitignore 中明确忽略了data.sqlite(检查结果数据库)、failures.md(失败明细)以及*.noindex*文件,仓库内只保留可供人读的汇总文档。
三类结果的分类口径
报告把下游包划分为三种状态:
- New problems:在开发版环境下新出现的失败(CRAN 版环境下没有),疑似 Shiny 改动引发的回归,需要逐一定位;
- Failed to check:因环境、安装或第三方依赖问题根本无法完成检查的包,不能据此断定与 Shiny 有关;
- 未列出的其余包:两种环境下均通过或均有历史性失败,不在本次关注范围内。
解剖 revdep_cran.md:一行行读懂报告
revdep_cran.md是一份高度凝练的自动生成摘要,结构如下:
## revdepcheck results We checked 902 reverse dependencies (778 from CRAN + 124 from BioConductor), comparing R CMD check results across CRAN and dev versions of this package. * We saw 1 new problems * We failed to check 2 packages Issues with CRAN packages are summarised below. ### New problems (This reports the first line of each new failure) ... ### Failed to check ...总览行:三个数字的读法
902:反向依赖总规模,括号内拆分为778 (CRAN) + 124 (BioConductor);1 new problems:只有 1 个下游包在开发版环境下出现新失败;2 failed to check:2 个包未能完成检查。
值得一提的是 “Issues with CRAN packages are summarised below” 这句限定语——本文件只汇总 CRAN 侧的问题,Bioconductor 侧的问题按惯例由独立报告承载。
New problems 区块:只报第一行
报告特别注明(This reports the first line of each new failure),即每个新问题只给出R CMD check输出中失败检查项的第一行,用于快速定位失败发生在哪个检查阶段(如checking tests ...)。完整堆栈与输出需回查原始检查产物(即被 .gitignore 排除的明细数据)。
新问题(New problems)的处置闭环:bsplus 案例
本次唯一的新问题是bsplus,报告记录如下:
* bsplus checking tests ... * Notified on May 11, 2020 * PR: https://github.com/ijlyttle/bsplus/pull/74 * Merged: May 12, 2020从记录可以还原完整的处置流程:
- 定位:
bsplus的失败发生在checking tests ...阶段——即其测试套件在开发版 Shiny 环境下运行失败; - 上报:2020-05-11 将该问题通知给
bsplus维护者; - 修复:维护者提交 PR #74;
- 闭环:2020-05-12(次日)PR 被合并,问题消除。
这正是反向依赖检查的标准价值所在:问题不在 Shiny 仓库内部修复,而是定位到下游包后驱动其上游修复。由于“新问题”的判定基准是 CRAN 版环境下没有失败,因此这类结果通常指向下游包对 Shiny 内部行为(如输出协议、响应格式)的脆弱依赖,而非 Shiny 本身的功能缺陷。
无法检查(Failed to check)的分类:环境限制与误报
frailtypack:环境与构建限制
* frailtypack * I can not figure out a way to install from source on macOSfrailtypack无法在 macOS 上从源码安装,因而根本进入不了R CMD check阶段。这类失败属于检查基础设施问题(平台依赖、源码构建链等),与 Shiny 代码无关,记录者仅作备注,不进入回归排查。
skeleSim:明确标记为误报
* skeleSim * Error: object ‘strata<-’ is not exported by 'namespace:strataG' * False positiveskeleSim的失败信息指向strataG包未导出strata<-对象——这是skeleSim所依赖的第三方包strataG自身的命名空间问题,与 Shiny 毫无关联。报告用一行False positive直接裁定为误报,说明记录者已人工核对失败来源并排除。
这两则案例展示了failed to check ≠ new problems的关键区别:前者未产生有效的双环境比对结果,后者才是真正需要回应的疑似回归。人工裁定(triage)是报告中不可或缺的一环。
revdep 目录的配套快照:跨版本看依赖生态演进
revdep_cran.md并非仓库中唯一一份报告,与其并存的还有三份文件,共同构成可对比的历史快照:
revdep/cran.md:更近期的检查结果
revdep/cran.md 记录了另一次检查:1383 个反向依赖(1376 个来自 CRAN + 7 个来自 Bioconductor),0 个新问题,31 个包未能检查,并附带了 31 个包名的完整清单(如AssumpSure、brms、rstanarm、rstanarm等)。这组数字与 cran-comments.md 中 2025-12 提交 CRAN 时的 revdepcheck 结果完全一致(同为 1383/1376/7、0 新问题、31 失败),可以推断revdep/cran.md对应的正是那一次正式发版前的检查。
revdep/README.md:失败清单表格
revdep/README.md 以package / version / error / warning / note五列表格形式列出了 38 个未能完成检查的包。其中boinet (1.5.0)、ctsem (3.10.4)、fio (0.1.6)、MOsemiind (0.1.0)、RCTrep (1.2.0)、rstanarm (2.32.2)等少数包带出了明确的版本号与 1 个 error 计数,其余大多数包版本标记为?,说明其连稳定版本信息都未取得。
revdep/problems.md:零问题宣言
revdep/problems.md 只有一行:
*Wow, no problems at all. :)*这行内容代表某次检查中新问题数量为零——是 revdepcheck 在结果干净时的友好输出,也说明仓库维护者在大多数快照里看到的是“零回归”的理想状态。
快照之间的数字对比
将两份主报告横向比较,可以观察 Shiny 依赖生态的规模变化:
| 指标 | revdep_cran.md(约 2020-05) | revdep/cran.md(约 2025-12) |
|---|---|---|
| 反向依赖总数 | 902 | 1383 |
| 其中 CRAN | 778 | 1376 |
| 其中 Bioconductor | 124 | 7 |
| 新问题 | 1(bsplus) | 0 |
| 无法检查 | 2 | 31 |
需要说明的是,两次快照的检查规模与方法存在差异(早期侧重 Bioconductor 覆盖,近期以 CRAN 覆盖为主),因此该表用于观察趋势而非直接比较优劣。
质量保障体系中的上下游证据
反向依赖检查并非孤立存在,它嵌在 Shiny 完整的发版质量保障链路中,仓库里可以找到多处置证:
发版说明中的 R CMD check 与 revdep 记录
cran-comments.md 是提交 CRAN 时写给审核者的说明,其中记录了 2025-12 发版时R CMD check的结论为0 errors | 0 warning | 1 note(唯一的 note 是 “Days since last update: 5”),随后接续的正是 revdepcheck 段落。可见维护者将“自身检查干净 + 反向依赖零回归”作为发版准入标准。
测试代码对并行检查的适配
反向依赖检查往往需要并行运行大量下游包的检查任务,而 Shiny 自带的测试套件同样可能被并行触发。为避免端口冲突导致误报,tests/testthat/test-app.R 中的测试专门使用httpuv::randomPort()随机分配测试端口,并注释说明:
Use random ports to avoid errors while running revdepcheck in parallel
测试会最多尝试 100 次以确保三个测试端口互不重复,再通过SHINY_TESTTHAT_PORT_*环境变量传入被测应用。这处细节印证了仓库对“检查结果可复现、不被并行干扰”的刻意设计——反向依赖检查的可靠性,恰恰建立在这些底层适配之上。
小结
从 revdep/revdep_cran.md 这份不足 30 行的摘要中,可以还原 Shiny 一整套反向依赖质量保障方法:以“CRAN 版 vs 开发版双环境R CMD check比对”为核心方法论,将下游包归类为新问题、无法检查与正常三类,通过通知上游、提交 PR 的方式闭环处置回归(bsplus 案例),并对环境限制(frailtypack)与第三方误报(skeleSim)做人工裁定;同时以 revdep/cran.md、revdep/README.md、revdep/problems.md 构成可追溯的历史快照,配合 cran-comments.md 与随机端口测试,把“零回归”变成可验证、可复现的发版闸门。对于维护自身同样拥有大量下游依赖的 R 包开发者而言,这套“报告结构—结果分类—处置闭环—人工裁定”的流程完全可以直接照搬。
- 后端
- Web框架
- 前端
【免费下载链接】shiny
Easy interactive web applications with R
相关推荐
ggplot2 CRAN 提交实战:从 cran-comments.md 读懂补丁发布与反向依赖检查(revdepcheck)
ggplot2 CRAN 提交实战:从 cran comments.md 读懂补丁发布与反向依赖检查(revdepcheck) 本文以 ggplot2 仓库根目
数据可视化ggplot2 反向依赖检查(revdepcheck)结果深度解读:从 6300 个依赖包看 API 变更影响面
ggplot2 反向依赖检查(revdepcheck)结果深度解读:从 6300 个依赖包看 API 变更影响面 本文以 ggplot2 仓库 revdep/c
数据可视化dplyr 反向依赖检查(revdep)报告解读:172 个生态级问题与 API 变迁全景
dplyr 反向依赖检查(revdep)报告解读:172 个生态级问题与 API 变迁全景 dplyr 是 R 生态中"数据操作语法"(A Grammar of
数据分析
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考