
asdf 核心贡献指南从环境搭建、Bats 测试到 Conventional Commits 的完整开发流程【免费下载链接】asdfExtendable version manager with support for Ruby, Node.js, Elixir, Erlang more项目地址: https://gitcode.com/GitHub_Trending/as/asdf本文以 docs/ja-jp/contribute/core.md及对应的英文版 docs/contribute/core.md为主体结合仓库内的 scripts/lint.bash、scripts/test.bash、scripts/checkstyle.py、release-please-config.json、.github/workflows/semantic-pr.yml 以及 test/ 目录中的大量 Bats 测试用例系统讲解如何为 asdf 核心仓库做贡献从克隆仓库、安装开发工具链到本地构建与调试、编写与运行 Bats 测试再到遵循 Conventional Commits 规范提交 Pull Request 的完整工作流。读完本文你将能够独立搭建 asdf 核心开发环境理解其 Lint/Format/Test 三件套的使用方式写出符合项目规范的测试与提交信息并掌握利用.git-blame-ignore-revs减少代码审查噪音的实用技巧。概览asdf 核心贡献意味着什么asdf 是一个可扩展的版本管理器支持 Ruby、Node.js、Elixir、Erlang 等多种运行时其核心仓库既包含大量 ShellBash实现与 Bats 测试也在向 Go 方向演进见仓库根目录的 go.mod 与 cmd/ 目录。对核心仓库做贡献通常意味着修复asdf命令本身的 Bug如安装、卸载、版本解析、shim 生成等为新的功能或行为补充 Bats 集成测试改进 Shell 脚本的格式、静态检查与可维护性更新文档并遵循 Conventional Commits 规范提交 PR。本指南正是围绕这一流程展开。整份指南对应的顶层入口见 CONTRIBUTING.md其中描述了 Bug 报告、功能提案与文档改进等更多贡献途径本文聚焦于「核心代码开发」这一条主线。初始搭建克隆仓库并准备开发工具链1. Fork 并克隆仓库在 GitHub 上 Forkasdf仓库或将默认分支克隆到本地# clone your fork git clone https://github.com/GITHUB_USER/asdf.git # or clone asdf git clone https://github.com/asdf-vm/asdf.git2. 使用 asdf 自身管理核心开发工具asdf 核心开发所用的工具版本定义在仓库根目录的.tool-versions文件中。当前仓库中该文件内容为bats 1.8.2 shellcheck 0.10.0 shfmt 3.6.0 golang 1.26.3即核心开发需要 Bats测试框架、ShellCheck静态分析、shfmtShell 格式化器以及 Go 工具链golang。如果你希望用 asdf 自己来管理这些工具先添加对应的插件asdf plugin add bats https://github.com/timgluz/asdf-bats.git asdf plugin add shellcheck https://github.com/luizm/asdf-shellcheck.git asdf plugin add shfmt https://github.com/luizm/asdf-shfmt.git然后一次性安装.tool-versions中声明的全部版本asdf install3. 一个重要提醒开发时是否用 asdf 管理工具文档特别提醒在本地机器上开发时可能最好不要使用 asdf 来管理这些开发工具。原因很直白——你在开发 asdf 的过程中可能会改动并破坏某些功能而这些功能恰好是支撑你自身开发工具链Bats、ShellCheck、shfmt所依赖的一旦 break 就会连带影响你的日常开发。此时一个更稳妥的做法是直接安装这些工具的独立版本bats-coreBash 自动测试系统用于对 Bash 或 POSIX 兼容脚本做单元测试shellcheckShell 脚本静态分析工具shfmt带 Bash 支持的 Shell 解析器、格式化器与解释器。此外从 .tool-versions 可以看出 Gogolang 1.26.3也是核心开发的一部分——这与仓库中 go.mod、internal/ 下的 Go 实现以及 cmd/asdf/main.go 入口相吻合在 Go 测试代码中HOME、ASDF_BIN等环境变量即由 Go 侧测试代码定义见 test/test_helpers.bash 中的注释说明。开发在不动已安装 asdf 的前提下试运行你的改动使用$ASDF_DIR指向克隆仓库当你修改了 asdf 源码想在不影响已安装 asdf 的情况下试运行改动可以设置$ASDF_DIR环境变量指向克隆仓库的路径并把该目录下的bin与shims目录临时加到PATH最前面export ASDF_DIR/path/to/your/asdf-clone export PATH$ASDF_DIR/bin:$ASDF_DIR/shims:$PATH这样asdf命令就会优先解析到你克隆的仓库中。同样的思路也体现在测试基础设施中Bats 测试通过setup_asdf_dir()把ASDF_DIR指向临时目录并执行PATH$ASDF_BIN:$ASDF_DIR/shims:$PATH来隔离被测环境参见 test/test_helpers.bash。提交前格式化、Lint 与测试在 commit 或 push 到远端之前建议先在本地完成格式化、Lint 与测试。文档给出的命令如下# Lint ./scripts/lint.bash --check # Fix Format ./scripts/lint.bash --fix # Test: all tests ./scripts/test.bash # Test: for specific command bats test/list_commands.bash注意文档原文示例中的test/list_commands.bash是示意路径当前仓库中真实的测试文件位于 test/ 目录如 test/list_command.bats、test/install_command.bats 等运行单个测试时请替换为你实际要调试的文件。scripts/lint.bash到底检查什么从源码看scripts/lint.bash 要求必须从仓库根目录执行脚本会通过git rev-parse --show-toplevel与当前目录比对不一致则直接报错退出见第 126-135 行。它依次执行四类检查且同时支持--check发现问题即报错与--fix自动修复两种模式shfmt 风格检查run_shfmt_stylecheck对internal/completions/*.bash、scripts/*.bash、test/test_helpers.bash以及test/fixtures/下各 dummy 插件的bin/*文件以--language-dialect bash --indent 2检查对test/*.bats以--language-dialect bats --indent 2检查。--check模式用--diff展示差异--fix模式用--write直接落盘。自定义 Python 风格检查run_custom_python_stylecheck调用 scripts/checkstyle.py。这是一个正则规则驱动的检查器内置了 5 条 shellcheck 覆盖不到的规则例如no-double-backslashprintf %s\\n中多余的转义反斜杠no-pwd-capture要求用$PWD而不是$(pwd)no-test-double-equals要求[ a b ]而不是[ a b ]no-function-keyword只允许fn_name() { ... }风格禁止function fn关键字no-verbose-redirection要求用/dev/null替代/dev/null 21。这些规则都带有正/负向正则测试可用./scripts/checkstyle.py --internal-test-regex自检。需要注意的是--fix模式需要 python3 环境若本地没有 python3脚本会打印警告并跳过此步骤但在 CIGITHUB_ACTIONS环境变量存在中缺少 python3 则会直接报错退出。ShellCheck 静态分析run_shellcheck_linter对.bash文件使用--shell bash --external-sources对.bats文件使用--shell bats --external-source覆盖范围与 shfmt 相同。fish_indent 检查run_fish_linter对internal/completions/asdf.fish做格式化检查同样在 CI 下缺少fish_indent会报错本地则跳过。此外脚本中还保留了 Elvish、Nushell、PowerShell 的 lint 占位注释形式并注明 Elvish 尚无成熟 lint/format 工具、Nushell 暂无相应工具这些注释可以作为了解项目现状的参考。Go 侧的工程化命令补充除了 Shell 侧脚本仓库根目录的 Makefile 还提供了一套 Go 工程命令与文档描述的「本地先验证再提交」理念一致make fmt # go fmt gofumpt make lint # staticcheck revive make vet # go vet make test # go test -coverprofile ... -race ./... make audit # verify vet test make build # go build 生成 ./asdf 二进制如果你的改动涉及 Go 代码如 internal/ 下的实现这两套工具链需要同时通过。代码规范细节.gitignore与.git-blame-ignore-revs.gitignore的职责边界仓库的 .gitignore 只负责忽略项目特定的文件当前内容为/installs /downloads /shims repository .vagrant keyrings /tmp dist/ # ignore build binary asdf其中installs、downloads、shims、tmp是 asdf 运行时产生的数据目录asdf是构建产物二进制。而每个开发者 OS、工具、工作流相关的文件如编辑器的临时文件不应提交到仓库的.gitignore而应放在你自己的全局.gitignore配置中这样每个仓库都能自动继承也避免污染共享仓库。文档中推荐了相关博客作为进一步参考。用.git-blame-ignore-revs让git blame更干净大规模格式重排如整库 shfmt 格式化会让git blame充满噪音——每个格式化提交都会把大段代码标记为「最后一手改动」。asdf 使用 .git-blame-ignore-revs 来解决这个问题该文件列出了一批只做格式调整、无实质逻辑变化的 commit当前仓库中记录了b8dc5f1604...Run shfmt on bash files、d81b81f9de...fix: Remove inside [等 9 个 commit执行 blame 时自动跳过它们git blame --ignore-revs-file .git-blame-ignore-revs ./test/install_command.bats如果不想每次手动带参数可以配置 Git 全局或仓库级选项让每次blame调用都自动读取该文件git config blame.ignoreRevsFile .git-blame-ignore-revs也可以让 IDE 使用该文件。以 VSCode GitLens 为例在.vscode/settings.json中写入{ gitlens.advanced.blame.customArguments: [ --ignore-revs-file, .git-blame-ignore-revs ] }关于git blame的更多细节可参阅 Git 官方文档。Bats 测试asdf 核心的测试体系如何运行测试在本地执行全部测试./scripts/test.bash从 scripts/test.bash 源码看它同样要求从仓库根目录执行然后调用 bats 并携带--timing --print-output-on-failure参数如果检测到parallel命令还会追加--jobs 2 --no-parallelize-within-files以并行加速CI 环境中若缺少 GNU parallel 会直接报错。因此本地安装 GNU parallel 可以显著加快测试。写测试前必读的三样东西文档要求在编写测试之前务必先通读test/ 目录下已有的测试当前仓库包含install_command.bats、set_command.bats、shim_exec.bats、version_commands.bats等 20 余个.bats文件bats-core 的官方文档scripts/test.bash 中使用的既有 Bats 配置。测试基础设施速览仓库的测试通过 test/test_helpers.bash 提供辅助函数理解它们有助于写出符合项目惯例的测试setup_asdf_dir()为每个测试建立隔离的$HOME、$ASDF_DIR、$ASDF_DATA_DIR并把被测的bin与shims目录注入PATHinstall_mock_plugin/install_dummy_plugin系列把test/fixtures/dummy_plugin等夹具复制为插件并初始化 Git 仓库test/fixtures/dummy_plugin 等夹具可在 test/fixtures/ 下找到install_mock_plugin_version/install_dummy_version在installs/plugin/version下创建假安装目录用于测试版本相关命令init_git_repo()以--initial-branchmaster初始化夹具仓库并完成首次提交clean_asdf_dir()清理测试目录并取消相关环境变量。这些辅助函数会被install_command.bats、uninstall_command.bats、set_command.bats等大量测试文件复用是理解 asdf 测试风格的最佳入口。Bats 调试技巧用-t与3输出到终端Bats 的调试有时比较棘手。默认情况下测试中被执行的命令的 stdout/stderr 会被 bats 吞掉除非失败否则不展示。文档推荐使用-t开启 TAP 输出配合特殊文件描述符3可以在测试执行过程中即时打印内容极大简化调试# test/some_tests.bats printf %s\n Will not be printed during bats test/some_tests.bats printf %s\n Will be printed during bats -t test/some_tests.bats 3即普通printf在bats test/some_tests.bats运行时不会显示而写入3的输出在bats -t test/some_tests.bats下会实时打印到终端。该机制在 bats-core 文档的 Printing to the Terminal 一节有更详细的说明。测试的必要性文档以醒目提示强调请为你的改动编写测试新功能必须有测试覆盖这是硬性要求Bug 修复附上测试也能显著加快 Review 速度。在提交 Pull Request 之前请确保新代码路径已有对应的测试用例。提交与发布Pull Request、Conventional Commits 与 Release Please提交信息格式Conventional Commitsasdf 使用自动发布工具 Release Please其依据是自上次发布以来的提交历史。因此提交信息必须遵循 Conventional Commits 规范——它在默认分支上定义了提交消息格式也即 Pull Request 标题的格式。该规范由 GitHub Actionamannn/action-semantic-pull-request强制校验仓库中的 .github/workflows/semantic-pr.yml 即该 Action 的实际配置并额外限制了允许的 scope 列表docs、website、plugin、completions、deps、golang-rewrite等。Conventional Commit 的格式如下type[optional scope][optional !]: description !-- examples -- fix: some fix feat: a new feature docs: some documentation update docs(website): some change for the website feat!: feature with breaking change可用的types完整列表为feat、fix、docs、style、refactor、perf、test、build、ci、chore、revert。type 与 SemVer 版本的对应关系!表示这是一个破坏性变更breaking changefix触发 SemVerpatch版本提升feat触发 SemVerminor版本提升type!如feat!、fix!触发 SemVermajor版本提升。Pull Request 的标题必须遵循该格式这是合并的前置条件。Release Please 与版本管理仓库根目录的 release-please-config.json 是发布配置的仓库内证据包类型为go开启bump-minor-pre-major1.x 之前以 minor 递增changelog-types将feat/fix/docs分别归入 Features/Patches/Documentation 三个章节并指定SECURITY.md、多语言 getting-started 文档含 docs/ja-jp/guide/getting-started.md以及 cmd/asdf/main.go 中的版本信息作为发布时需要同步更新的额外文件。发布的版本清单记录在 .release-please-manifest.json当前版本号为0.16.x阶段可结合 version.txt 与 docs/ja-jp/guide/upgrading-to-v0-16.md 了解对应升级说明。进阶把 asdf 打包进 Docker 镜像asdf-alpine 和 asdf-ubuntu 是持续进行的社区项目为部分 asdf 工具提供 Docker 化镜像。这些镜像既可以用作开发服务器的基础镜像也可以直接用于运行生产应用——如果你需要把 asdf 管理的运行时部署到容器环境这两个项目值得关注它们不属于本仓库请到对应项目了解详情。常见问题与检查清单脚本必须在仓库根目录运行scripts/lint.bash与scripts/test.bash都会校验当前目录是否为仓库根目录否则直接报错。本地没有 python3 / fish_indent / parallel 怎么办本地环境下对应检查会被跳过并给出[WARNING]Go 工具链与 bats 不受影响但 CI 环境下缺少这些依赖会直接失败。改动会不会影响我的开发环境文档建议开发 asdf 时谨慎使用 asdf 管理开发工具防止改坏自身依赖如需隔离使用$ASDF_DIR 临时 PATH 的方式试运行。PR 标题规范必须使用 Conventional Commit 格式否则会被 .github/workflows/semantic-pr.yml 拦截。提交前自查./scripts/lint.bash --check→./scripts/test.bash→ 为改动补充 Bats 测试 → 检查git blame噪音用.git-blame-ignore-revs。按照上述流程你就可以在保持本地开发环境安全的前提下完成「克隆 → 装工具 → 改代码 → 试运行 → Lint/Format → 写测试 → 跑测试 → 提交 PR」的完整 asdf 核心贡献闭环。【免费下载链接】asdfExtendable version manager with support for Ruby, Node.js, Elixir, Erlang more项目地址: https://gitcode.com/GitHub_Trending/as/asdf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考