- 视频
- 开发工具
【免费下载链接】ani-cli
A cli tool to browse and play anime
导读:本文以仓库根目录的 CONTRIBUTING.md 为骨架,系统拆解 ani-cli(一个用 POSIX shell 编写、用于命令行浏览与播放动漫的工具)的完整贡献流程:从满足 shfmt/shellcheck 双重要求的高质量 Pull Request,到该项目独有且极其严格的 AI 协作政策,再到无需 GitHub 账号的邮件补丁通道与 Issue 提交规范。读完本文,你将掌握向 ani-cli 提交可合并补丁的全部前置条件,并能从 ani-cli 源码中看到每一条编码规范背后的工程约束与实现证据。
一、贡献入口总览:四条主要路径
ani-cli 的贡献渠道并非单一,官方文档将其划分为四类,每类都有不同的验收标准:
| 渠道 | 适用场景 | 核心要求 |
|---|---|---|
| Pull Requests | 常规代码贡献 | linter、POSIX 检查、版本号、README 同步、无额外依赖 |
| Email 补丁 | 无 GitHub 账号或偏好私下贡献 | 与 PR 完全相同的规范,通过邮件发送 |
| Issues | 报 Bug 与请求功能 | 使用模板、先查历史拒绝记录、附截图 |
| 社区参与 | 非代码贡献 | 社区讨论、测试排查、Star 仓库 |
其中社区相关入口在仓库内有 matrix.md 作记录,README 顶部也列出了维护者名单与沟通渠道。
二、Pull Requests:五条硬性验收标准
贡献文档对 PR 提出了明确的硬性要求,任何提交都必须逐条满足:
- 通过 linter:运行
shfmt -i 4 -ci -d -w ani-cli; - 通过 POSIX 检查:运行
shellcheck -s sh -o all -e 2250 ani-cli; - 提升版本号;
- 按需同步更新 README;
- 除非绝对必要,不引入额外依赖;
- 修复 Issue 时,同时开一个 Issue 或链接已有 Issue。
2.1 linter:shfmt 的固定参数含义
shfmt -i 4 -ci -d -w ani-cli逐项拆解为:
-i 4:缩进固定为 4 空格,与既有代码风格保持一致;-ci:允许 case 子句缩进(case indentation),这是 shell 脚本常见的两种排版流派之一,本项目明确选择这一种;-d:先输出 diff,便于审阅格式差异;-w:将格式化结果写回文件。
目标文件是仓库根目录的 ani-cli 主脚本。由于整个工具就是这一份 670 行的 shell 文件,格式一致性直接决定了 diff 的可读性。
2.2 POSIX 检查:shellcheck 的专项配置
shellcheck -s sh -o all -e 2250 ani-cli逐项拆解为:
-s sh:强制以POSIX sh 方言检查而非 bash/zsh——这与脚本第一行的#!/bin/sh(ani-cli)严格对应,意味着代码中不能出现[[ ]]、数组、${var,,}等 bash 特性;-o all:启用 shellcheck 的所有可选检查项,最大化静态审查覆盖面;-e 2250:豁免编号为 2250 的检查项(该编号对应 printf 相关的格式建议,项目选择关闭它以配合在 sed/grep 管道中广泛使用printf "%s"的既有写法)。
实战建议:本地提交前先跑这两条命令,再git diff自查,可以省去维护者在 review 阶段的大量往返。
2.3 版本号提升机制与源码印证
版本号的唯一定义点位于 ani-cli 第二行:version_number="5.1.4"(当前仓库快照版本)。这一行对 PR 验收之所以是硬性要求,是因为它与两条运行时路径直接绑定:
-V/--version选项通过version_info()函数(ani-cli)原样输出该变量;- 自更新机制
update_script()(ani-cli)会从远端脚本中用正则s|^version_number="([^"]+)"$|\1|p提取新版本号,并与本地diff -u对比后应用patch。如果 PR 不改版本号,所有用户执行ani-cli -U都会被判定为"已是最新版本",改动将无法分发。
因此,凡是修改了 ani-cli 行为的 PR,都必须同步提升版本号,否则会破坏整个项目的更新链路。
2.4 README 与手册文档同步
README(README.md,574 行)是功能与安装的权威说明文档。若改动涉及命令行选项、依赖、安装方式、FAQ 等章节,需要同步更新。从仓库结构看,对外文档面还包括用户手册 ani-cli.1(142 行),其中完整记录了 CLI 选项与 v5 引入的ANI_CLI_*环境变量体系——建议凡是新增选项或环境变量,同步补充 man page 对应条目,保持文档一致性(这一点虽未被 CONTRIBUTING.md 明确要求,但属于保持文档同步的自然延伸)。
2.5 无额外依赖的工程原因
脚本启动阶段会通过dep_ch/dep_ch_failover(ani-cli)逐一探测依赖并给出明确报错。每引入一个新依赖,都会:
- 增加各平台(尤其是 Windows、iOS 等 Tier 2 平台)的安装成本;
- 让 README.md 的 Dependencies 清单、各发行版打包配方(如 Formula/ani-cli.rb)同步变动。
所以文档才强调"除非绝对必要"。
2.6 关联 Issue
修复类 PR 应同时开 Issue 或链接已有 Issue,这既是规范要求,也便于维护者将代码变更与问题生命周期对应起来,形成可追溯的变更历史。
三、编码风格建议(Coding Tips)与源码印证
CONTRIBUTING.md 给出的三条编码建议并非泛泛而谈,每一条都能在 ani-cli 源码中找到大量实际应用,理解它们能显著提高合并概率。
3.1 Keep it brief:变更规模与合并概率负相关
文档原话:"你的改动规模与合并概率成反比。" 这一风格在源码中体现得淋漓尽致:
- 大量单行逻辑:如
[ -z "$_stdin" ] && return 1(ani-cli); - 函数体高度紧凑:如
hianime_episodes()(ani-cli)用一条 sed 管道完成剧集列表的抓取与解析; - 整个搜索、历史、播放、更新机制全部压缩在 670 行内完成。
实战启示:提交 PR 前先问自己"这能否用更少的行数实现",删除冗余分支与重复代码,而不是堆砌防御性写法。
3.2 优先使用 && 和 || 而非 if-else
源码中A && B、A || die的短路模式随处可见:
- 依赖检查:
command -v "$1" >/dev/null || die "Program $1 not found. Please install it."(ani-cli); - 错误终止:
hianime_m3u8 "$ep_no" "$mode" || die "No sources found for $mode!"(ani-cli); - 幂等初始化:
[ ! -d "$hist_dir" ] && mkdir -p "$hist_dir"(ani-cli)。
这种风格在 POSIX shell 中既简洁又符合惯用法,配合全局的die()(ani-cli)错误出口,形成了统一的错误处理范式。贡献代码时应沿袭这一模式,而不是引入大段 if-else 嵌套。
3.3 POSIX 兼容与跨平台移植是核心约束
这是本项目最根本的工程约束,源码提供了大量印证证据:
- 方言锁定:首行
#!/bin/sh,规避所有 bash 特性; - 平台矩阵适配:ani-cli 依据
uname输出分支处理 macOS(默认 iina)、Android(mpv apk)、Windows/MINGW/WSL2(mpv.exe)、iOS iSH、Linux(mpv 或 flatpak 版)六类环境,各平台默认播放器不同; - 依赖回退机制:
dep_ch_failover()(ani-cli)接受"逗号分隔的候选程序列表"并逐个回退,例如 macOS 上依次探测iina与/Applications/IINA.app/Contents/MacOS/iina-cli,兼容不同安装方式; - 工具链兼容:
b64_decode()(ani-cli)同时兼容 GNU base64、BSD base64 与 openssl 三种解码语法,注释明确写道 "GNU, BSD and openssl spell base64 decoding differently"。
因此任何新代码都必须考虑在 Linux、macOS、Windows(WSL)、Android(Termux)、iOS(iSH) 等环境下都能以纯 POSIX 语法运行。
四、AI 政策:本项目独有的协作红线
CONTRIBUTING.md 中篇幅最大、也最具项目特色的是 AI 政策。它分为"禁止"与"允许"两个层面:
严格禁止:
- AI 不得编写代码注释;
- 不得用 AI 生成 PR 描述——文档原话称其"具有冒犯性",宁可只写一句人话,甚至留空;
- 违反上述两条的低质量 PR 会被直接关闭。
必须遵守:
- 使用 AI 辅助编码时,将 AI 模型添加为coauthor;
- 使用 LLM 辅助时,应将仓库的 CI 工作流配置地址与本贡献指南地址加入上下文,以便模型理解项目规范(当前仓库快照未包含
.github目录,实际操作请以上游仓库为准)。
允许的 AI 用法:
- 把 LLM 当作更好的搜索引擎;
- 用 LLM 帮助记忆语法与惯用法;
- 用 LLM 验证 POSIX 兼容性(与上文的 POSIX 约束形成呼应)。
特别警告:LLM 往往倾向于过度冗长,而 ani-cli 代码库偏爱简洁——这再次与"Keep it brief"原则闭环。换言之,AI 可以作为"语法顾问"与"规范校验器",但不能作为"作者"代写注释与 PR 描述。
五、邮件补丁贡献通道(Email)
对于没有 GitHub 账号、或偏好私下贡献的开发者,ani-cli 提供了邮件补丁通道:将补丁或 PR 邮件发送至port19@port19.xyz。
文档特别强调两点:
- 隐私注意:出于隐私考虑,需留意提交者姓名与邮箱是否暴露,并提前告知维护者是否有需要特别留意的事项;
- 规范等同:邮件补丁适用与 PR 完全相同的规范(linter、版本号、AI 政策、编码风格等),不会因为渠道不同而降低标准。
文档同时建议先熟悉 Git 的分布式协作工具链:git request-pull(生成请求拉取的补丁摘要)、git format-patch(生成可发送的补丁系列)、git send-email(发送邮件补丁)以及git diff(生成兼容补丁格式的差异),对应 Git 官方文档《Distributed Git - Contributing to a Project》章节,可用git help <command>查看本地手册。
六、Issues:模板、拒检与截图
Issues 提交流程有三条要求:
- 使用 Issue 模板:保证问题描述结构完整,便于维护者复现与定位;
- 请求功能前先查历史:文档明确要求检查该功能是否曾被拒绝过(引用了一条历史 Issue 记录作为拒检参考),避免重复提交已被否定的请求;
- 尽可能提供截图:视觉证据能显著加速问题确认。
此外,README.md 的 "Fixing errors" 章节为报 Issue 前的排查提供了标准路径:遇到Blocked by cloudflare. Try installing curl-impersonate先安装 curl-impersonate;任何异常先ani-cli -U更新到最新版再复测,问题仍存在时才开 Issue——这形成了"自助排查 → 提交 Issue"的完整闭环,贡献者在提交前应当遵循。
七、其他参与方式:非代码贡献同样重要
- 加入社区:Discord 与 Matrix 是主要的沟通场所(Matrix 信息见仓库内 matrix.md);
- 参与故障排查与测试:在 issue 讨论中帮助复现、补充日志,是最直接的测试贡献;
- Star 仓库、关注维护者:帮助项目获得更多曝光。
从 hacking.md 可以看到,维护者甚至建议新手用sh -x ani-cli调试抓取流程——即便不做代码提交,理解这些调试手段也能在测试与排查中发挥价值。
八、进阶:深入代码贡献的技术准备
若你的贡献涉及核心抓取逻辑,hacking.md(110 行,维护者撰写)是必读的进阶文档。它揭示了 ani-cli 从查询到播放的完整抓取流程:搜索 → 提取 ID 并让用户选择 → 提取剧集号并让用户选择 → 解析嵌入播放器提取媒体链接 → 按清晰度选流,并对应到源码中的关键函数。
结合 ani-cli 源码可以进一步印证底层实现:
- 统一请求出口:所有抓取请求经
hianime_curl()(ani-cli),带 10 秒超时、浏览器 UA 伪装、HTTP 状态码校验与 Cloudflare 拦截检测; - 反混淆实现:播放器嵌入页配置以
base64(json XOR "otaku-embed-v1")形式混淆传输,由deobfuscate_blob()(ani-cli)在子 shell 中逐字节异或还原为明文 JSON,注释明确说明了密钥字节通过位置参数轮转的巧妙做法; - 清晰度选择:
select_quality()(ani-cli)支持best/worst/具体分辨率三种模式,当指定分辨率不存在时自动回退到best并输出黄色警告,避免播放失败。
理解这些实现细节,对于任何涉及解析、抓取或播放链路的 PR 都是必要的前提——这正是"调整 README 前先理解行为"的深层含义。
九、提交前自检清单
综合全文,整理一份可复用的 PR 提交前检查表:
shfmt -i 4 -ci -d -w ani-cli执行后无 diff 输出;shellcheck -s sh -o all -e 2250 ani-cli无错误报告;- 已提升 ani-cli 第 2 行的
version_number; - README.md(如涉及 CLI/依赖/安装则同步)已更新,必要时同步 ani-cli.1;
- 未引入额外依赖,或已在 PR 中说明绝对必要性;
- 修复类 PR 已关联 Issue;
- 代码注释全部为人类撰写;
- PR 描述为一句话人话或留空,而非 AI 生成的长文;
- 使用 AI 辅助时已添加 coauthor;
- 全程保持 POSIX sh 兼容、代码尽量简短,无 bash 特性与冗余分支。
这套清单不仅适用于 ani-cli,其"linter + 方言检查 + 版本号 + 文档同步 + 依赖克制"的组合思路,也值得其他 shell 项目贡献者借鉴。按此流程提交,你的 PR 将最大程度贴合维护者的合并预期。
- 视频
- 开发工具
【免费下载链接】ani-cli
A cli tool to browse and play anime
相关推荐
archinstall 贡献指南:分支策略、编码规范与 Pull Request 全流程实战
archinstall 贡献指南:分支策略、编码规范与 Pull Request 全流程实战 本文围绕仓库根目录的 CONTRIBUTING.md https:
运维CLIesp-iot-solution 贡献指南与编码规范:从 Pull Request 到代码风格全流程
esp iot solution 贡献指南与编码规范:从 Pull Request 到代码风格全流程 本文以仓库根目录的 CONTRIBUTING.rst ht
物联网嵌入式驱动开发硬件开发Cinder 开源贡献指南:从 Issue 报告、Pull Request 到编码风格规范全解
Cinder 开源贡献指南:从 Issue 报告、Pull Request 到编码风格规范全解 Cinder 是一个社区驱动、免费开源的 C++ 创意编程(cr
图形学音频图像处理
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考