asdf 插件开发完全指南:从零编写可扩展版本管理插件的脚本 API 与实战

发布时间:2026/9/12 12:15:34

asdf 插件开发完全指南:从零编写可扩展版本管理插件的脚本 API 与实战 asdf 插件开发完全指南从零编写可扩展版本管理插件的脚本 API 与实战【免费下载链接】asdfExtendable version manager with support for Ruby, Node.js, Elixir, Erlang more项目地址: https://gitcode.com/GitHub_Trending/as/asdfasdf 是一个可扩展的多运行时版本管理器其核心思想是一切皆插件通过一套统一的脚本约定让任意语言或工具Ruby、Node.js、Elixir、Erlang 等都能接入 asdf 的asdf install、asdf list all、shim 机制等完整工作流。本篇指南以官方插件开发文档为主体结合本仓库 Go 源码中的插件加载、安装、shim 生成等实现细节系统讲解插件的目录结构、必备/可选脚本契约、环境变量、扩展命令、自定义 shim 模板、自动化测试与发布索引。读完本文你将能够独立编写、测试并发布一个生产可用的 asdf 插件。插件是什么一个 asdf 插件本质上是一个 Git 仓库其中包含若干可执行脚本用于支持某个语言/工具的版本管理。这些脚本由 asdf 核心以特定命令调用从而支撑asdf list-all name、asdf install name version等功能。从本仓库源码可以确认插件在磁盘上的布局internal/plugins/plugins.go 中的Plugin结构体记录了插件的Name、Dir插件安装目录、Ref当前 git ref与URL而CallbackPath方法则定义了回调脚本的固定查找规则任何回调脚本都位于插件目录下的bin/script-name见 CallbackPath例如bin/list-all、bin/install。插件本身被克隆到$ASDF_DATA_DIR/plugins/name默认~/.asdf/plugins/name。快速开始两种创建插件的方式使用官方插件模板仓库生成asdf-vm/asdf-plugin-template提供了带默认脚本的模板生成的仓库命名为asdf-tool_name。生成后克隆仓库并运行setup.bash脚本即可交互式地更新模板中的工具名、版本等占位内容。从零手写自建名为asdf-tool_name的仓库按下文列出的脚本契约逐一实现bin/下的脚本。插件脚本的黄金法则脚本不得调用其他 asdf 命令避免递归与状态竞争尽量保持 Shell 工具/命令依赖列表短小精悍避免使用不可移植的工具或命令标志例如sort -V。本仓库 test/banned_commands.bats 中维护了 asdf 核心禁止使用的命令清单插件作者应同步规避。此外从源码可见插件名有严格约束validatePluginName 使用正则^[[:lower:][:digit:]_-]$校验即插件名只能包含小写字母、数字、下划线和连字符否则asdf plugin add会直接报错。脚本总览下表为 asdf 可调用的全部插件脚本均位于插件仓库bin/目录脚本说明必填性bin/list-all列出全部可安装版本必填bin/download下载指定版本的源码或二进制推荐新插件必填bin/install安装指定版本必填bin/latest-stable输出工具的最新稳定版推荐bin/help.overview输出插件与工具的通用描述可选bin/help.deps按操作系统输出依赖列表可选bin/help.config输出插件或工具配置信息可选bin/help.links输出插件或工具相关链接可选bin/list-bin-paths列出包含可执行文件的相对目录用于生成 shim可选bin/exec-env执行二进制前准备运行环境可选bin/exec-path输出某版本工具的二进制路径可选bin/uninstall卸载指定版本工具可选bin/list-legacy-filenames输出旧版版本文件名如.ruby-version可选bin/parse-legacy-file自定义解析旧版版本文件可选bin/post-plugin-add插件被添加后执行的钩子可选bin/post-plugin-update插件被更新后执行的钩子可选bin/pre-plugin-remove插件被移除前执行的钩子可选环境变量总览asdf 核心通过环境变量向插件脚本传递上下文。并非所有环境变量在所有脚本中都可用具体以各脚本说明为准环境变量说明ASDF_INSTALL_TYPEversion或refASDF_INSTALL_VERSION完整版本号或根据ASDF_INSTALL_TYPE为 Git RefASDF_INSTALL_PATH工具应被安装到/已被安装的路径ASDF_CONCURRENCY编译源码时使用的核心数可用于设置make -jASDF_DOWNLOAD_PATHbin/download下载源码/二进制的目标路径ASDF_PLUGIN_PATH插件安装路径ASDF_PLUGIN_SOURCE_URL插件的源 URLASDF_PLUGIN_PREV_REF插件仓库更新前的git-refASDF_PLUGIN_POST_REF插件仓库更新后的git-refASDF_CMD_FILE被 source 的文件的完整路径这些变量的设置可以从源码中得到印证internal/versions/versions.go 中InstallOneVersion在调用download/install回调前构造了ASDF_INSTALL_TYPE、ASDF_INSTALL_VERSION、ASDF_INSTALL_PATH、ASDF_DOWNLOAD_PATH、ASDF_CONCURRENCY五个环境变量而 internal/plugins/plugins.go 中Update在调用post-plugin-update前设置了ASDF_PLUGIN_PATH、ASDF_PLUGIN_PREV_REF、ASDF_PLUGIN_POST_REF。必备脚本详解bin/list-all必填职责列出所有可安装版本。输出格式必须打印一个以空格分隔的版本列表例如1.0.1 1.0.2 1.3.0 1.4最新版本应放在最后。asdf 核心会将该输出逐行打印因此在终端中每个版本占一行。排序建议如果版本来自网站 releases 页面通常已按正确顺序排列直接原样输出即可若为逆序通过tac反转即可。若必须排序注意sort -V不可移植建议使用 Git 的排序能力需要 Git v2.18.0或自行编写排序方法依赖sed、sort与awk。可用环境变量无。调用方命令asdf list all name [version]asdf list all nodejs逐行列出脚本返回的全部版本asdf list all nodejs 18逐行列出所有以18开头的版本核心侧过滤。核心调用签名无参数${plugin_path}/bin/list-all从源码看AllVersions 通过plugin.RunCallback(list-all, ...)调用该脚本随后用空格切分并 trim 得到版本切片——这与文档规定的空格分隔格式严格对应。bin/download新插件必填职责将指定版本工具的源码或二进制下载到指定位置。实现要求必须将源码/二进制下载到ASDF_DOWNLOAD_PATH指定的目录该目录中只能放置解压后的源码或二进制失败时不得在ASDF_DOWNLOAD_PATH留下任何文件成功退出码为0失败为非零退出码。Legacy 插件兼容性虽然该脚本对所有插件标记为必填但对于在其引入之前就已存在的 legacy 插件是可选的。若脚本缺失asdf 会假定bin/install存在并承担下载安装双重职责。所有插件最终都应包含此脚本legacy 支持未来将被移除。可用环境变量ASDF_INSTALL_TYPEversion或refASDF_INSTALL_VERSION版本号为完整版本号ASDF_INSTALL_TYPEversion时为 Git reftag/commit/branchASDF_INSTALL_TYPEref时ASDF_INSTALL_PATH工具已安装/应安装的路径ASDF_DOWNLOAD_PATH源码/二进制的下载目标路径调用方命令asdf install tool [version]asdf install tool latest[:version]asdf install nodejs 18.0.0下载 Node.js 18.0.0 的源码/二进制到ASDF_DOWNLOAD_PATH随后执行bin/install核心调用签名无参数${plugin_path}/bin/download源码佐证InstallOneVersion 先调用download回调若返回NoCallbackError则忽略兼容 legacy 插件否则报错中止。下载完成后ASDF_DOWNLOAD_PATH目录会按需保留或删除默认删除除非配置always_keep_download或使用--keep-download标志见 internal/versions/versions.go。bin/install必填职责将指定版本的工具安装到指定位置。实现要求将指定版本安装到ASDF_INSTALL_PATH默认情况下asdf 会为$ASDF_INSTALL_PATH/bin中的文件创建 shim可通过可选的bin/list-bin-paths脚本定制此行为成功退出码为0失败为非零为避免 TOCTOUTime-of-Check-to-Time-of-Use问题只有构建与安装都判定成功之后才向ASDF_INSTALL_PATH写入文件。Legacy 插件兼容性若bin/download缺失本脚本需同时承担下载与安装。为兼容 0.7._ 之前与 0.8._ 之后的 asdf 核心版本应检查ASDF_DOWNLOAD_PATH环境变量是否存在若已设置说明bin/download已完成下载否则需在bin/install内自行下载源码。可用环境变量ASDF_INSTALL_TYPEversion或refASDF_INSTALL_VERSION完整版本号或 Git refASDF_INSTALL_PATH安装路径ASDF_CONCURRENCY编译使用的核心数可用于make -jASDF_DOWNLOAD_PATH下载目录调用方命令asdf installasdf install toolasdf install tool [version]asdf install tool latest[:version]asdf install nodejs 18.0.0核心调用签名无参数${plugin_path}/bin/install源码佐证安装失败时asdf 核心会清理已创建的installDir并返回错误internal/versions/versions.go安装成功后会调用shims.GenerateAll为所有可执行文件生成 shiminternal/versions/versions.go。可选脚本详解bin/latest-stable推荐职责确定工具的最新稳定版本。若缺失asdf 核心会tailbin/list-all的输出可能不符合预期。实现要求向 stdout 打印工具的最新稳定版本应排除非稳定版本或候选版本如 RC脚本的第一个参数是过滤查询filter query应按版本号或工具提供方过滤输出。例如 ruby 插件输出中混有jruby、rbx、truffleruby等多个提供方的版本用户提供的过滤条件可用于筛选 semver 版本或提供方 asdf latest ruby 3.2.2 asdf latest ruby 2 2.7.8 asdf latest ruby truffleruby trufflerubygraalvm-22.3.1成功退出码为0失败为非零。可用环境变量ASDF_INSTALL_TYPE、ASDF_INSTALL_VERSION、ASDF_INSTALL_PATH。调用方命令asdf set tool latest将该工具版本设为最新稳定版asdf install tool latestasdf latest tool [version]按可选过滤条件输出最新版本asdf latest --all输出 asdf 管理的所有工具的最新版本及安装状态核心调用签名接受一个参数——过滤查询${plugin_path}/bin/latest-stable $query源码佐证Latest 优先调用latest-stable回调若回调缺失则回退到list-all输出通过正则过滤掉-src、-dev、-rc、-alpha、-beta、snapshot、master等不稳定版本见latestFilterRegex再根据查询条件做前缀精确匹配最终取最后一个版本。bin/help.overview职责输出插件与被管理工具的通用描述。实现要求该脚本是插件显示任何 help 输出的前提不要打印标题asdf 核心会打印标题输出可以是自由文本但理想情况下仅一段简短描述不得输出 asdf-vm 核心文档已覆盖的信息应根据操作系统与所装工具版本使用可选的ASDF_INSTALL_VERSION、ASDF_INSTALL_TYPE定制内容成功退出码为0失败为非零。可用环境变量ASDF_INSTALL_TYPE、ASDF_INSTALL_VERSION、ASDF_INSTALL_PATH。调用方命令asdf help name [version]核心调用签名${plugin_path}/bin/help.overviewbin/help.deps职责输出按操作系统定制的依赖列表每行一个依赖git curl sed实现要求需要bin/help.overview存在其输出才会被采纳应根据操作系统与版本定制成功退出码为0失败为非零。可用环境变量ASDF_INSTALL_TYPE、ASDF_INSTALL_VERSION、ASDF_INSTALL_PATH。调用方命令asdf help name [version]核心调用签名${plugin_path}/bin/help.depsbin/help.config职责输出插件与工具所需或可选的配置信息例如安装/编译工具所需的环境变量或其他标志。实现要求需要bin/help.overview存在输出可为自由文本应根据操作系统与版本定制成功退出码为0失败为非零。可用环境变量ASDF_INSTALL_TYPE、ASDF_INSTALL_VERSION、ASDF_INSTALL_PATH。调用方命令asdf help name [version]核心调用签名${plugin_path}/bin/help.configbin/help.links职责输出与插件和工具相关的链接列表每行一个链接Git Repository: https://github.com/vlang/v Documentation: https://vlang.io实现要求需要bin/help.overview存在每行一个链接格式必须是title: link或仅link应根据操作系统与版本定制成功退出码为0失败为非零。可用环境变量ASDF_INSTALL_TYPE、ASDF_INSTALL_VERSION、ASDF_INSTALL_PATH。调用方命令asdf help name [version]核心调用签名${plugin_path}/bin/help.linksbin/list-bin-paths职责列出包含指定版本工具可执行文件的目录。实现要求若脚本缺失asdf 会默认在${ASDF_INSTALL_PATH}/bin目录查找二进制并为其创建 shim输出空格分隔的路径列表路径必须相对于ASDF_INSTALL_PATH。示例输出bin tools veggies该输出将指示 asdf 为以下目录中的文件创建 shim${ASDF_INSTALL_PATH}/bin${ASDF_INSTALL_PATH}/tools${ASDF_INSTALL_PATH}/veggies可用环境变量ASDF_INSTALL_TYPE、ASDF_INSTALL_VERSION、ASDF_INSTALL_PATH。调用方命令asdf install tool [version]安装时初次创建 shimasdf reshim tool version重建 shim核心调用签名${plugin_path}/bin/list-bin-paths源码佐证ExecutableDirs 调用该回调若回调缺失则默认返回[bin]随后 ToolExecutables 遍历这些目录为其中可执行且非目录的文件逐个生成 shim。bin/exec-env职责在执行工具的 shim 之前准备运行环境。可用环境变量ASDF_INSTALL_TYPE、ASDF_INSTALL_VERSION、ASDF_INSTALL_PATH。调用方命令asdf which command显示可执行文件路径asdf exec command [args...]为当前版本执行命令 shimasdf env command [util]在命令 shim 的执行环境中运行 util默认env核心调用签名${plugin_path}/bin/exec-envbin/exec-path职责获取指定版本工具的二进制路径。必须打印相对二进制路径的字符串使插件能有条件地覆盖 shim 指定的可执行路径否则返回 shim 指定的默认路径。实现要求必须打印相对可执行路径字符串有条件地覆盖 shim 指定的可执行路径否则返回 shim 默认路径。Usage: plugin/bin/exec-path install-path command executable-path Example Call: ~/.asdf/plugins/foo/bin/exec-path ~/.asdf/installs/foo/1.0 foo bin/foo Output: bin/foox可用环境变量ASDF_INSTALL_TYPE、ASDF_INSTALL_VERSION、ASDF_INSTALL_PATH。调用方命令asdf which command、asdf exec command [args...]、asdf env command [util]。核心调用签名${plugin_path}/bin/exec-path $install_path $cmd $relative_path源码佐证getCustomExecutablePath 以installPath、shim 名和相对路径三个参数调用exec-path回调若回调存在则用其输出拼接出最终可执行路径实现 shim 路径的条件覆盖。bin/uninstall职责卸载指定版本的工具。输出格式输出应视情况发送到stdout或stderr核心后续执行不会读取任何输出。可用环境变量无。调用方命令asdf uninstall name versionasdf uninstall nodejs 18.15.0卸载 nodejs 18.15.0移除所有 shim包括通过npm i -g全局安装的核心调用签名无参数${plugin_path}/bin/uninstall源码佐证Uninstall 先调用uninstall回调缺失则忽略再删除安装目录期间会触发pre_asdf_uninstall_name/post_asdf_uninstall_name命令钩子。bin/list-legacy-filenames职责列出用于确定工具版本的旧版配置文件legacy file名称。实现要求输出空格分隔的文件名列表.ruby-version .rvmrc仅对在${HOME}/.asdfrc中启用了legacy_version_file选项的用户生效。可用环境变量ASDF_INSTALL_TYPE、ASDF_INSTALL_VERSION、ASDF_INSTALL_PATH。调用方命令任何读取工具版本的命令。核心调用签名无参数${plugin_path}/bin/list-legacy-filenames源码佐证LegacyFilenames 调用该回调将 stdout 按空格切分得到文件名列表回调缺失时返回空列表。这一机制使 asdf 兼容.ruby-version、.nvmrc、.node-version等既有配置文件实现平滑迁移。bin/parse-legacy-file职责解析 asdf 找到的旧版文件以确定工具版本。对于 JavaScript 的package.json、Golang 的go.mod这类需要提取版本号的文件尤其有用。实现要求若缺失asdf 会直接cat旧版文件来确定版本应确定性地工作解析同一旧版文件总是返回完全相同的确切版本与机器上安装了什么、旧版本是否有效或完整无关某些旧版文件格式可能不适合输出单行版本1.2.3可用环境变量无调用前不会专门设置环境变量。调用方命令任何读取工具版本的命令。核心调用签名接受一个参数——旧版文件的路径${plugin_path}/bin/parse-legacy-file $file_path源码佐证ParseLegacyVersionFile 检查bin/parse-legacy-file是否存在存在则带文件路径参数调用回调并取输出否则直接os.ReadFile读取文件内容。无论哪种方式最终都会按空格拆分并 trim 得到版本列表。bin/post-plugin-add职责在插件通过asdf plugin add tool被添加后执行的回调脚本。相关命令钩子hookpre_asdf_plugin_addpre_asdf_plugin_add_${plugin_name}post_asdf_plugin_addpost_asdf_plugin_add_${plugin_name}可用环境变量ASDF_PLUGIN_PATH插件安装路径ASDF_PLUGIN_SOURCE_URL插件源 URL也可以是本地目录路径核心调用签名无参数${plugin_path}/bin/post-plugin-add源码佐证Add 在克隆插件仓库并创建下载目录后以ASDF_PLUGIN_SOURCE_URL和ASDF_PLUGIN_PATH为环境变量调用post-plugin-add回调随后执行 post 系列命令钩子。bin/post-plugin-update职责在 asdf 通过asdf plugin update tool [git-ref]下载插件更新后执行的回调脚本。相关命令钩子pre_asdf_plugin_updatepre_asdf_plugin_update_${plugin_name}post_asdf_plugin_updatepost_asdf_plugin_update_${plugin_name}可用环境变量ASDF_PLUGIN_PATH插件安装路径ASDF_PLUGIN_PREV_REF插件更新前的 git-refASDF_PLUGIN_POST_REF插件更新后的 git-ref核心调用签名无参数${plugin_path}/bin/post-plugin-update源码佐证Update 通过repo.Update(ref)得到新旧 SHA随后以ASDF_PLUGIN_PREV_REF/ASDF_PLUGIN_POST_REF等环境变量调用post-plugin-update回调。bin/pre-plugin-remove职责在 asdf 通过asdf plugin remove tool移除插件前执行的回调脚本。相关命令钩子pre_asdf_plugin_removepre_asdf_plugin_remove_${plugin_name}post_asdf_plugin_removepost_asdf_plugin_remove_${plugin_name}可用环境变量ASDF_PLUGIN_PATH插件安装路径ASDF_PLUGIN_SOURCE_URL插件源 URL核心调用签名无参数${plugin_path}/bin/pre-plugin-remove源码佐证Remove 在调用pre-plugin-remove回调并传入ASDF_PLUGIN_PATH、ASDF_PLUGIN_SOURCE_URL之后依次删除插件的下载目录、插件目录与安装目录再执行 post 系列命令钩子。进阶为 asdf CLI 扩展命令插件可以为 asdf 定义新的子命令在插件仓库提供lib/commands/command*.bash脚本或可执行文件用户即可通过asdf plugin_name ...调用。例如假设foo插件包含foo/ lib/commands/ command.bash command-bat.bash command-bat-man.bash command-help.bash用户可以执行$ asdf foo # 等同运行 $ASDF_DATA_DIR/plugins/foo/lib/commands/command.bash $ asdf foo bar # 等同运行 $ASDF_DATA_DIR/plugins/foo/lib/commands/command.bash bar $ asdf foo help # 等同运行 $ASDF_DATA_DIR/plugins/foo/lib/commands/command-help.bash $ asdf foo bat man # 等同运行 $ASDF_DATA_DIR/plugins/foo/lib/commands/command-bat-man.bash $ asdf foo bat baz # 等同运行 $ASDF_DATA_DIR/plugins/foo/lib/commands/command-bat.bash baz插件作者可以用此特性提供与工具相关的实用功能甚至可以创建纯粹作为 asdf 自身命令扩展的插件。若脚本设置了可执行位asdf 将直接执行它替换 asdf 进程若未设置可执行位asdf 会将其作为 Bash 脚本 source。$ASDF_CMD_FILE解析为被 source 文件的完整路径。请务必在插件 README 中列出你的 asdf 扩展命令。源码佐证ExtensionCommandPath 将命令名映射为lib/commands/command[-name]路径缺失时报NoCommandErrorGetExtensionCommands 遍历lib/commands目录收集全部可用扩展命令。对应 CLI 子命令asdf cmd的实现在 internal/cli/cli.go 中可见。进阶自定义 Shim 模板仅在绝对必要时使用。对名为foo的可执行文件若插件中存在shims/foo文件asdf 将复制该文件而不是使用标准 shim 模板。必须谨慎使用。据 asdf 核心团队所知该特性目前仅在官方 Elixir 插件中使用——因为其可执行文件本身还会被当作 Elixir 文件读取无法使用标准 Bash shim。源码佐证ShimTemplatePath 要求模板文件存在于shims/name且具有可执行位mode0o111而 ExecutablePaths 也会将插件自身的shims/目录纳入可执行文件扫描范围shim 文件的生成含# asdf-plugin:注释与exec asdf exec ...调用见 shims.go。测试你的插件asdf 内置plugin-test命令用于测试插件asdf plugin test plugin_name plugin_url [--asdf-tool-version version] [--asdf-plugin-gitref git_ref] [test_command...]plugin_name与plugin_url为必填指定[--asdf-tool-version version]时将安装该特定版本默认值为asdf latest plugin-name指定[--asdf-plugin-gitref git_ref]时插件会检出到该 commit/branch/tag便于在 CI 中测试 pull-request默认使用插件仓库默认分支可选参数[test_command...]是用于验证安装工具正常工作的命令通常为tool --version或tool --help。例如测试 NodeJS 插件# asdf plugin test plugin_name plugin_url [test_command] asdf plugin test nodejs https://github.com/asdf-vm/asdf-nodejs.git node --version建议在 Linux 与 macOS 两种 CI 环境中测试。仓库中的测试用例对命令行为做了精确验证例如 test/plugin_test_command.bats 验证缺少 name/URL 时报错FAILED: please provide a plugin name and url同文件 验证--asdf-tool-version与--asdf-plugin-gitref组合使用成功。GitHub Actions 配置asdf-vm/actions 仓库提供了在 GitHub 上托管插件的测试 Action。示例.github/workflows/test.yamlname: Test on: push: branches: - main pull_request: jobs: plugin_test: name: asdf plugin test strategy: matrix: os: - ubuntu-latest - macos-latest runs-on: ${{ matrix.os }} steps: - name: asdf_plugin_test uses: asdf-vm/actions/plugin-testv2 with: command: MY_TOOL --versionTravisCI 配置示例.travis.yml可按需定制language: c script: asdf plugin test MY_TOOL $TRAVIS_BUILD_DIR MY_TOOL --version before_script: - git clone https://github.com/asdf-vm/asdf.git asdf - . asdf/asdf.sh os: - linux - osx使用其他 CI 时可能需要传递插件的相对路径asdf plugin test tool_name path tool_command --version处理 API 限流若某命令依赖外部 API如bin/list-all或bin/latest-stable在自动化测试期间可能遭遇限流。缓解措施是确保存在一条通过环境变量提供认证令牌的代码路径例如cmdcurl --silent if [ -n $GITHUB_API_TOKEN ]; then cmd$cmd -H Authorization: token $GITHUB_API_TOKEN fi cmd$cmd $releases_pathGITHUB_API_TOKEN使用GITHUB_API_TOKEN时需创建一个仅具有public_repo权限的 personal token然后将其加入 CI 流水线的环境变量。警告切勿将认证令牌发布到代码仓库中。插件短名索引Shortname Index推荐的插件安装方式是直接通过 URL 安装# asdf plugin add name git_url asdf plugin add nodejs https://github.com/asdf-vm/asdf-nodejs若未提供git_urlasdf 将使用Shortname Index 仓库来确定确切的git_url。你可以按照该仓库的说明将自己的插件加入 Shortname Index之后用户即可直接asdf plugin add your-plugin完成安装。源码佐证Add 在pluginURL 时会检查disable_plugin_short_name_repository配置然后通过pluginindex包见 internal/pluginindex/pluginindex.go 的GetPluginSourceURL查询短名对应的仓库 URL。该索引仓库会克隆到本地并按配置周期更新。总结编写 asdf 插件的本质是遵循一套清晰、稳定的脚本契约bin/list-all与bin/install是安装流程的基石bin/download、bin/latest-stable提供推荐体验bin/list-bin-paths、bin/exec-env、bin/exec-path控制 shim 与执行环境bin/help.*系列输出帮助信息而bin/post-plugin-add、bin/post-plugin-update、bin/pre-plugin-remove则接入插件的生命周期管理。通过本仓库源码internal/plugins/plugins.go、internal/versions/versions.go、internal/shims/shims.go可以看到这些脚本由 asdf 核心以固定路径和固定环境变量调用输出按空格分隔解析——理解这一调用契约即可写出健壮、可移植、可持续维护的插件并借助asdf plugin test与 CI 矩阵确保其在各平台可靠运行。【免费下载链接】asdfExtendable version manager with support for Ruby, Node.js, Elixir, Erlang more项目地址: https://gitcode.com/GitHub_Trending/as/asdf创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/9/12 12:15:34

Conductor 工作流如何调用远程 A2A Agent(AGENT 任务)?

Conductor 工作流如何调用远程 A2A Agent(AGENT 任务)? 【免费下载链接】conductor Conductor is an event driven agentic workflow engine providing durable and highly resilient execution engine for applications and AI Agents 项目…

2026/9/12 12:10:34

EasyClaw实测:个人效能提升200%的6大应用场景

1. 项目概述"一个人EasyClaw能顶几个人?真实用户的6个使用场景实测报告"这个标题揭示了现代生产力工具如何赋能个人工作效能的主题。EasyClaw作为一款新兴的效率工具,正在改变传统工作模式中的人力资源配置方式。通过6个真实使用场景的实测数据…

2026/9/12 13:10:36

Java面向对象编程:继承与多态的核心原理与实践

1. 继承与多态的核心概念在面向对象编程(OOP)中,继承和多态是两个最基础也最重要的特性。它们共同构成了代码复用和扩展的基石,让程序设计变得更加灵活和高效。继承就像生物学中的遗传机制。当创建一个新类时,不需要从零开始编写所有代码&…

2026/9/12 13:10:36

STM32F103驱动AD5272数字电位器:SPI时序、增益校准与工程实践

简介:面向电子设计竞赛(电赛)中的数字电位器控制场景,这份资源以STM32F103单片机为控制核心,提供AD5272数字电位器的I2C总线驱动与工程实现方案。内容覆盖I2C接口初始化、寄存器配置、数据帧构造与阻值读写等关键环节&…

2026/9/12 13:10:36

Linux进程创建:fork()机制深度解析与实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/12 13:10:36

STT-MRAM替代低功耗SRAM:掉电不丢数据的嵌入式存储方案

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/12 2:05:33

超人会飞不算本事:系统稳定依赖清晰规则与边界设计

开头先不绕弯子。“#斯坦李吐槽dc 所以超人是无缘无故会飞的嘛哈哈哈哈哈哈哈锤哥真是技术人才啊!#雷神 #复联”这类调侃式短标题,第一波冲击力在于它把两个宇宙的角色塞进同一个吐槽箱里,但细想一下就能发现,它真正碰到的根本不是…

2026/9/12 3:55:12

超人VS蜘蛛侠:拆解超级IP的影响力与传播方法论

把“蜘蛛侠 vs 超人”放在 CSDN 上聊,可能很多人第一反应是走错片场了。但如果把这两个角色看成“两个持续运营了 80 多年的文化产品”,你会发现,这场比较本质上是两个不同 IP 策略的长期结果对比:超人赢在定义了整个超级英雄题材…

2026/9/12 10:09:03

基于CNN的调制信号识别:MATLAB实现时频图分类实战

简介:本资源是一套面向通信工程与信号处理方向学习者、研究者的深度学习实践方案,聚焦调制信号自动检测与识别这一典型无线通信任务,解决传统方法依赖人工特征、低信噪比下性能下降等痛点。压缩包共12个文件(10.73MB)&…

2026/9/12 0:04:17

MATLAB仿生优化框架:长鼻浣熊算法多策略融合实现

简介:本资源是一份面向智能优化算法研究者与MATLAB初学者的仿生智能算法实践代码包,聚焦于长鼻浣熊优化算法(COA)的多策略改进与性能验证。针对传统COA易陷局部最优、收敛精度不足等问题,作者融合Circle映射初始化提升…

2026/9/12 0:04:17

【JAVA毕设源码分享】基于 JavaWeb 的校园一卡通管理系统的设计与实现 基于 JavaWeb 的校园卡业务管理系统(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/12 0:04:17

【JAVA毕设源码分享】基于 Java 的图书馆借阅管理平台的搭建与实现 基于 Java 的图书馆综合管理系统(程序+文档+代码讲解+一条龙定制)

博主介绍:✌️码农一枚 ,专注于大学生项目实战开发、讲解和毕业🚢文撰写修改等。全栈领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java、小程序技术领域和毕业项目实战 ✌️技术范围:&am…

2026/9/12 6:29:36

USB Type-C PCB布局分区设计:电源、高速信号与PD协议全攻略

做硬件这行,Type-C接口算是典型的“看着简单,做起来全坑”的东西。光引脚就24个,高低速信号、电源、控制线全部塞在一个小小的连接器里,如果PCB布局不做规划,打样回来基本就是“插上没反应”、“高速掉线”、“静电一打…

2026/9/10 15:19:50

系统编程学习原型如何补齐稳定性边界

系统编程学习原型如何补齐稳定性边界预算有限时&#xff0c;我先优化明显多余的复制&#xff0c;而不是猜测性地换容器。用借用传递只读数据通常就能减少分配&#xff1a; fn parse(line: &str) -> Result<Item, Error> { /* ... */ }用基准确认热点确实在分配&am…

2026/9/12 6:37:43

雨花区哪家财务公司代理记账比较好?

在雨花区&#xff0c;企业处理财税事务常常面临诸多挑战&#xff0c;选择一家靠谱的财务公司至关重要。湖南巨勤财务管理咨询有限公司就是本地正规实体财税服务机构&#xff0c;深耕本地工商财税行业多年&#xff0c;熟悉当地工商局、税务局最新政策与申报流程。主营公司注册、…

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
咨询二维码