vx-provider-creator
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseVX Provider Creator
VX Provider Creator
This skill guides the creation of new runtime providers for the vx universal tool manager.
本技能指导你为vx通用工具管理器创建新的runtime provider。
When to Use
适用场景
- Creating a new provider for a tool (e.g., "add support for ripgrep")
- Implementing a new runtime in vx
- Adding a new tool to the vx ecosystem
- Adding project analyzer support for a language/ecosystem
- Adding tools that require system package manager installation
- 为某一工具创建新provider(例如:"添加对ripgrep的支持")
- 在vx中实现新的runtime
- 为vx生态系统添加新工具
- 为某一语言/生态系统添加项目分析器支持
- 添加需要通过系统包管理器安装的工具
Workflow Overview
工作流程概述
- Check license compatibility (MUST DO FIRST)
- Create a feature branch from remote main
- Determine installation type (direct download vs system package manager)
- Generate provider directory structure (including )
provider.toml - Implement core files (lib.rs, provider.rs, runtime.rs, config.rs)
- Add system package manager fallback if needed
- Register the provider in workspace and CLI
- (Optional) Add project analyzer integration for language-specific tools
- Update snapshot tests
- Verify and test
- 检查许可证兼容性(必须首先完成)
- 从远程main分支创建功能分支
- 确定安装类型(直接下载 vs 系统包管理器)
- 生成provider目录结构(包含)
provider.toml - 实现核心文件(lib.rs、provider.rs、runtime.rs、config.rs)
- 按需添加系统包管理器回退
- 在工作区和CLI中注册provider
- (可选) 为特定语言工具添加项目分析器集成
- 更新快照测试
- 验证与测试
⚠️ License Compliance (MANDATORY - Step 0)
⚠️ 许可证合规性(强制要求 - 第0步)
Before creating ANY provider, you MUST check the upstream tool's license.
在创建任何provider之前,你必须检查上游工具的许可证。
Blocked Licenses (DO NOT integrate)
禁止集成的许可证
These licenses have "copyleft infection" that would require vx itself to change license:
| License | Risk | Example |
|---|---|---|
| AGPL-3.0 | Entire project must be AGPL | x-cmd |
| SSPL | Server-side copyleft | MongoDB |
| CC BY-NC | No commercial use | - |
| Proprietary (no redistribution) | Cannot bundle/distribute | - |
这些许可证具有“左版感染”特性,会要求vx本身更改许可证:
| 许可证 | 风险 | 示例 |
|---|---|---|
| AGPL-3.0 | 整个项目必须采用AGPL许可证 | x-cmd |
| SSPL | 服务器端左版 | MongoDB |
| CC BY-NC | 禁止商业使用 | - |
| Proprietary (no redistribution) | 无法捆绑/分发 | - |
Allowed Licenses (Safe to integrate)
允许集成的许可证
| License | Type | Notes |
|---|---|---|
| MIT | Permissive | ✅ No restrictions |
| Apache-2.0 | Permissive | ✅ Patent grant included |
| BSD-2/BSD-3 | Permissive | ✅ Minimal restrictions |
| ISC | Permissive | ✅ Similar to MIT |
| MPL-2.0 | Weak copyleft | ✅ File-level copyleft only |
| Unlicense/CC0 | Public domain | ✅ No restrictions |
| 许可证 | 类型 | 说明 |
|---|---|---|
| MIT | 宽松许可证 | ✅ 无限制 |
| Apache-2.0 | 宽松许可证 | ✅ 包含专利授权 |
| BSD-2/BSD-3 | 宽松许可证 | ✅ 限制极少 |
| ISC | 宽松许可证 | ✅ 与MIT类似 |
| MPL-2.0 | 弱左版 | ✅ 仅文件级左版 |
| Unlicense/CC0 | 公有领域 | ✅ 无限制 |
Caution Licenses (Allowed with notes)
需谨慎使用的许可证(允许集成但有说明)
| License | Type | Notes |
|---|---|---|
| GPL-2.0/GPL-3.0 | Strong copyleft | ⚠️ OK for vx since we only download and execute the tool (not link to it). Add |
| LGPL-2.1/LGPL-3.0 | Weak copyleft | ⚠️ Same as GPL - OK for download/execute. Document in provider.toml |
| BSL-1.1 | Source-available | ⚠️ HashiCorp tools (terraform, vault). OK for version management. Document restriction |
| Proprietary (free to use) | Proprietary | ⚠️ OK if tool is free to download/use (e.g., dotnet, msvc). Add note |
| 许可证 | 类型 | 说明 |
|---|---|---|
| GPL-2.0/GPL-3.0 | 强左版 | ⚠️ 对vx来说是可行的,因为我们仅下载并执行工具(而非链接到它)。需在provider.toml中添加 |
| LGPL-2.1/LGPL-3.0 | 弱左版 | ⚠️ 与GPL相同 - 下载/执行是可行的。需在provider.toml中记录 |
| BSL-1.1 | 源码可用 | ⚠️ HashiCorp工具(terraform、vault)。适用于版本管理。需记录限制 |
| Proprietary (free to use) | 专有许可证 | ⚠️ 若工具可免费下载/使用则可行(例如dotnet、msvc)。需添加说明 |
How to Check
检查方法
- Visit the tool's GitHub repository
- Check the LICENSE file or repository metadata
- Search for in the repo's About section
license - If no license found, treat as proprietary and document
- 访问工具的GitHub仓库
- 查看LICENSE文件或仓库元数据
- 在仓库的About部分搜索
license - 若未找到许可证,视为专有许可证并记录
provider.toml License Fields
provider.toml中的许可证字段
Every MUST include:
provider.tomltoml
[provider]
name = "example"
license = "MIT" # SPDX identifier of upstream tool's license每个必须包含:
provider.tomltoml
[provider]
name = "example"
license = "MIT" # 上游工具许可证的SPDX标识符license_note = "..." # Optional: any special notes about license implications
license_note = "..." # 可选:关于许可证影响的特殊说明
**If the license is in the "Blocked" category, DO NOT create the provider. Inform the user:**
> ⚠️ Cannot integrate {tool}: it uses {license} which has copyleft infection
> that would require the entire vx project to adopt the same license.
> Consider using it via system package manager instead.
**若许可证属于“禁止”类别,请勿创建provider,并告知用户:**
> ⚠️ 无法集成{tool}:它使用的{license}具有左版感染特性,会要求整个vx项目采用相同许可证。
> 建议通过系统包管理器使用该工具。Installation Type Decision Tree
安装类型决策树
Before creating a provider, determine the installation method:
Does the tool provide portable binaries for all platforms?
├─ Yes → Standard Download Provider
│ └─ Examples: terraform, just, kubectl, helm, go, node
└─ No → Check platform availability
├─ Some platforms have binaries → Hybrid Provider (download + package manager)
│ └─ Examples: imagemagick (Linux AppImage, macOS/Windows via brew/winget)
│ └─ Examples: ffmpeg (Windows binary, macOS/Linux via brew/apt)
└─ No portable binaries → System Package Manager Only
└─ Examples: make, git (on non-Windows), curl, openssl创建provider前,确定安装方式:
工具是否为所有平台提供可移植二进制文件?
├─ 是 → 标准下载Provider
│ └─ 示例:terraform、just、kubectl、helm、go、node
└─ 否 → 检查平台可用性
├─ 部分平台有二进制文件 → 混合Provider(下载 + 包管理器)
│ └─ 示例:imagemagick(Linux用AppImage,macOS/Windows用brew/winget)
│ └─ 示例:ffmpeg(Windows用二进制,macOS/Linux用brew/apt)
└─ 无任何可移植二进制文件 → 仅系统包管理器
└─ 示例:make、git(非Windows平台)、curl、opensslProvider Types Summary
Provider类型总结
| Type | Direct Download | Package Manager Fallback | Examples |
|---|---|---|---|
| Standard | ✅ All platforms | ❌ Not needed | terraform, just, go, node |
| Hybrid | ✅ Some platforms | ✅ For others | imagemagick, ffmpeg, docker |
| System-only | ❌ None | ✅ All platforms | make, curl, openssl |
| Detection-only | ❌ None | ❌ System-installed | msbuild, xcodebuild, systemctl |
| 类型 | 直接下载 | 包管理器回退 | 示例 |
|---|---|---|---|
| 标准 | ✅ 所有平台 | ❌ 无需 | terraform、just、go、node |
| 混合 | ✅ 部分平台 | ✅ 其他平台使用 | imagemagick、ffmpeg、docker |
| 仅系统 | ❌ 无 | ✅ 所有平台 | make、curl、openssl |
| 仅检测 | ❌ 无 | ❌ 仅系统已安装 | msbuild、xcodebuild、systemctl |
Step 1: Create Feature Branch
步骤1:创建功能分支
bash
git fetch origin main
git checkout -b feature/{name}-provider origin/mainReplace with the tool name (lowercase, e.g., , ).
{name}ripgrepfdbash
git fetch origin main
git checkout -b feature/{name}-provider origin/main将替换为工具名称(小写,例如、)。
{name}ripgrepfdStep 2: Create Provider Directory Structure
步骤2:创建Provider目录结构
Create the following structure under :
crates/vx-providers/{name}/crates/vx-providers/{name}/
├── Cargo.toml
├── provider.toml # Provider manifest (metadata, runtimes, constraints)
├── src/
│ ├── lib.rs # Module exports + create_provider() factory
│ ├── provider.rs # Provider trait implementation
│ ├── runtime.rs # Runtime trait implementation
│ └── config.rs # URL builder and platform configuration
└── tests/
└── runtime_tests.rs # Unit tests (using rstest)在下创建以下结构:
crates/vx-providers/{name}/crates/vx-providers/{name}/
├── Cargo.toml
├── provider.toml # Provider清单(元数据、运行时、约束)
├── src/
│ ├── lib.rs # 模块导出 + create_provider()工厂函数
│ ├── provider.rs # Provider trait实现
│ ├── runtime.rs # Runtime trait实现
│ └── config.rs # URL构建器和平台配置
└── tests/
└── runtime_tests.rs # 单元测试(使用rstest)Step 2.1: Create provider.toml Manifest
步骤2.1:创建provider.toml清单
The file is the declarative manifest for the provider. It defines:
provider.toml- Provider metadata (name, description, homepage, ecosystem)
- Runtime definitions (executable, aliases, bundled tools)
- Version source configuration
- RFC 0019: Layout configuration (for binary/archive downloads)
- Platform-specific settings
- Dependency constraints
Ecosystems available: , , , , , ,
nodejspythonrustgodevtoolssystemzigVersion sources:
- - GitHub Release API (most common)
github-releases - - GitHub Tags API
github-tags - - Node.js official releases
nodejs-org - - Python standalone builds
python-build-standalone - - Go official downloads
go-dev - - Zig official downloads
zig-download
RFC 0019 Layout Types:
- - Single file download (needs renaming/placement)
binary - - Compressed archive (tar.gz, zip, tar.xz)
archive
See for complete provider.toml template.
See for RFC 0019 layout configuration guide.
references/templates.mdreferences/rfc-0019-layout.mdprovider.toml- Provider元数据(名称、描述、主页、生态系统)
- Runtime定义(可执行文件、别名、捆绑工具)
- 版本源配置
- RFC 0019:布局配置(用于二进制/归档文件下载)
- 平台特定设置
- 依赖约束
可用的生态系统: 、、、、、、
nodejspythonrustgodevtoolssystemzig版本源:
- - GitHub Release API(最常用)
github-releases - - GitHub Tags API
github-tags - - Node.js官方发布源
nodejs-org - - Python独立构建版本
python-build-standalone - - Go官方下载源
go-dev - - Zig官方下载源
zig-download
RFC 0019布局类型:
- - 单文件下载(需要重命名/放置)
binary - - 压缩归档(tar.gz、zip、tar.xz)
archive
完整的provider.toml模板请参考。
RFC 0019布局配置指南请参考。
references/templates.mdreferences/rfc-0019-layout.mdStep 3: Implement Core Files
步骤3:实现核心文件
Refer to for complete code templates.
references/templates.md完整代码模板请参考。
references/templates.mdKey Implementation Points
关键实现要点
Cargo.toml: Use workspace dependencies, package name
vx-provider-{name}lib.rs: Export types and provide factory function
create_provider()provider.rs: Implement Provider trait with:
- - Provider name (lowercase)
name() - - Human-readable description
description() - - Return all Runtime instances
runtimes() - - Check if runtime name is supported
supports(name) - - Get Runtime by name
get_runtime(name)
runtime.rs: Implement Runtime trait with:
- - Runtime name
name() - - Description
description() - - Alternative names (if any)
aliases() - - One of: System, NodeJs, Python, Rust, Go
ecosystem() - - Homepage, documentation, category
metadata() - - Fetch available versions
fetch_versions(ctx) - - Build download URL
download_url(version, platform) - Executable Path Configuration (layered approach, most providers only need 1-2):
- - Base name of executable (default:
executable_name())name() - - Windows extensions (default:
executable_extensions(), use[".exe"]for npm/yarn)[".cmd", ".exe"] - - Directory containing executable (default: install root)
executable_dir_path(version, platform) - - Full path (auto-generated from above, rarely override)
executable_relative_path(version, platform)
- - Verify installation
verify_installation(version, install_path, platform)
config.rs: Implement URL builder with:
- - Full download URL
download_url(version, platform) - - Platform target triple
get_target_triple(platform) - - Archive extension (zip/tar.gz)
get_archive_extension(platform) - - Executable name with extension
get_executable_name(platform)
Cargo.toml:使用工作区依赖,包名为
vx-provider-{name}lib.rs:导出类型并提供工厂函数
create_provider()provider.rs:实现Provider trait,包含:
- - Provider名称(小写)
name() - - 人类可读的描述
description() - - 返回所有Runtime实例
runtimes() - - 检查是否支持该runtime名称
supports(name) - - 通过名称获取Runtime
get_runtime(name)
runtime.rs:实现Runtime trait,包含:
- - Runtime名称
name() - - 描述
description() - - 替代名称(如有)
aliases() - - 可选值:System、NodeJs、Python、Rust、Go
ecosystem() - - 主页、文档、分类
metadata() - - 获取可用版本
fetch_versions(ctx) - - 构建下载URL
download_url(version, platform) - 可执行文件路径配置(分层方法,大多数provider仅需1-2种配置):
- - 可执行文件的基础名称(默认:
executable_name())name() - - Windows平台的扩展名(默认:
executable_extensions(),npm/yarn使用[".exe"])[".cmd", ".exe"] - - 包含可执行文件的目录(默认:安装根目录)
executable_dir_path(version, platform) - - 完整路径(由上述配置自动生成,极少需要覆盖)
executable_relative_path(version, platform)
- - 验证安装
verify_installation(version, install_path, platform)
config.rs:实现URL构建器,包含:
- - 完整下载URL
download_url(version, platform) - - 平台目标三元组
get_target_triple(platform) - - 归档文件扩展名(zip/tar.gz)
get_archive_extension(platform) - - 带扩展名的可执行文件名称
get_executable_name(platform)
Step 4: Register Provider
步骤4:注册Provider
4.1 Update Root Cargo.toml
4.1 更新根目录Cargo.toml
Add to members:
[workspace]toml
"crates/vx-providers/{name}",Add to :
[workspace.dependencies]toml
vx-provider-{name} = { path = "crates/vx-providers/{name}" }在 members中添加:
[workspace]toml
"crates/vx-providers/{name}",在中添加:
[workspace.dependencies]toml
vx-provider-{name} = { path = "crates/vx-providers/{name}" }4.2 Update vx-cli/Cargo.toml
4.2 更新vx-cli/Cargo.toml
Add dependency:
toml
vx-provider-{name} = { workspace = true }添加依赖:
toml
vx-provider-{name} = { workspace = true }4.3 Update registry.rs
4.3 更新registry.rs
In , add:
crates/vx-cli/src/registry.rsrust
// Register {Name} provider
registry.register(vx_provider_{name}::create_provider());在中添加:
crates/vx-cli/src/registry.rsrust
// 注册{Name} provider
registry.register(vx_provider_{name}::create_provider());Step 5: Project Analyzer Integration (Optional)
步骤5:项目分析器集成(可选)
If the new tool corresponds to a language/ecosystem (e.g., Go, Java, PHP), add project analyzer support.
如果新工具对应某一语言/生态系统(例如Go、Java、PHP),可添加项目分析器支持。
5.1 Create Language Analyzer Directory
5.1 创建语言分析器目录
crates/vx-project-analyzer/src/languages/{lang}/
├── mod.rs # Module exports
├── analyzer.rs # {Lang}Analyzer implementation
├── dependencies.rs # Dependency parsing
├── rules.rs # Script detection rules
└── scripts.rs # Explicit script parsingcrates/vx-project-analyzer/src/languages/{lang}/
├── mod.rs # 模块导出
├── analyzer.rs # {Lang}Analyzer实现
├── dependencies.rs # 依赖解析
├── rules.rs # 脚本检测规则
└── scripts.rs # 显式脚本解析5.2 Define Script Detection Rules
5.2 定义脚本检测规则
rust
// rules.rs
use crate::languages::rules::ScriptRule;
pub const {LANG}_RULES: &[ScriptRule] = &[
ScriptRule::new("build", "{build_command}", "Build the project")
.triggers(&["{config_file}"])
.priority(50),
ScriptRule::new("test", "{test_command}", "Run tests")
.triggers(&["{test_config}", "tests"])
.priority(50),
ScriptRule::new("lint", "{lint_command}", "Run linter")
.triggers(&["{lint_config}"])
.excludes(&["{task_runner_config}"])
.priority(50),
];rust
// rules.rs
use crate::languages::rules::ScriptRule;
pub const {LANG}_RULES: &[ScriptRule] = &[
ScriptRule::new("build", "{build_command}", "构建项目")
.triggers(&["{config_file}"])
.priority(50),
ScriptRule::new("test", "{test_command}", "运行测试")
.triggers(&["{test_config}", "tests"])
.priority(50),
ScriptRule::new("lint", "{lint_command}", "运行代码检查")
.triggers(&["{lint_config}"])
.excludes(&["{task_runner_config}"])
.priority(50),
];5.3 Implement LanguageAnalyzer
5.3 实现LanguageAnalyzer
rust
// analyzer.rs
use super::rules::{LANG}_RULES;
use crate::languages::rules::{apply_rules, merge_scripts};
use crate::languages::LanguageAnalyzer;
pub struct {Lang}Analyzer {
script_parser: ScriptParser,
}
#[async_trait]
impl LanguageAnalyzer for {Lang}Analyzer {
fn detect(&self, root: &Path) -> bool {
root.join("{config_file}").exists()
}
fn name(&self) -> &'static str {
"{Lang}"
}
async fn analyze_dependencies(&self, root: &Path) -> AnalyzerResult<Vec<Dependency>> {
// Parse {config_file} for dependencies
}
async fn analyze_scripts(&self, root: &Path) -> AnalyzerResult<Vec<Script>> {
// 1. Parse explicit scripts from config
let explicit = parse_config_scripts(root, &self.script_parser).await?;
// 2. Apply detection rules
let detected = apply_rules(root, {LANG}_RULES, &self.script_parser);
// 3. Merge (explicit takes priority)
Ok(merge_scripts(explicit, detected))
}
fn required_tools(&self, _deps: &[Dependency], _scripts: &[Script]) -> Vec<RequiredTool> {
vec![RequiredTool::new(
"{tool}",
Ecosystem::{Ecosystem},
"{Tool} runtime",
InstallMethod::vx("{tool}"),
)]
}
fn install_command(&self, dep: &Dependency) -> Option<String> {
Some(format!("{package_manager} add {}", dep.name))
}
}rust
// analyzer.rs
use super::rules::{LANG}_RULES;
use crate::languages::rules::{apply_rules, merge_scripts};
use crate::languages::LanguageAnalyzer;
pub struct {Lang}Analyzer {
script_parser: ScriptParser,
}
#[async_trait]
impl LanguageAnalyzer for {Lang}Analyzer {
fn detect(&self, root: &Path) -> bool {
root.join("{config_file}").exists()
}
fn name(&self) -> &'static str {
"{Lang}"
}
async fn analyze_dependencies(&self, root: &Path) -> AnalyzerResult<Vec<Dependency>> {
// 解析{config_file}获取依赖
}
async fn analyze_scripts(&self, root: &Path) -> AnalyzerResult<Vec<Script>> {
// 1. 从配置文件解析显式脚本
let explicit = parse_config_scripts(root, &self.script_parser).await?;
// 2. 应用检测规则
let detected = apply_rules(root, {LANG}_RULES, &self.script_parser);
// 3. 合并(显式脚本优先级更高)
Ok(merge_scripts(explicit, detected))
}
fn required_tools(&self, _deps: &[Dependency], _scripts: &[Script]) -> Vec<RequiredTool> {
vec![RequiredTool::new(
"{tool}",
Ecosystem::{Ecosystem},
"{Tool} runtime",
InstallMethod::vx("{tool}"),
)]
}
fn install_command(&self, dep: &Dependency) -> Option<String> {
Some(format!("{package_manager} add {}", dep.name))
}
}5.4 Register Analyzer
5.4 注册分析器
In :
crates/vx-project-analyzer/src/languages/mod.rsrust
mod {lang};
pub use {lang}::{Lang}Analyzer;
pub fn all_analyzers() -> Vec<Box<dyn LanguageAnalyzer>> {
vec![
// ... existing analyzers
Box::new({Lang}Analyzer::new()),
]
}在中:
crates/vx-project-analyzer/src/languages/mod.rsrust
mod {lang};
pub use {lang}::{Lang}Analyzer;
pub fn all_analyzers() -> Vec<Box<dyn LanguageAnalyzer>> {
vec![
// ... 现有分析器
Box::new({Lang}Analyzer::new()),
]
}5.5 Add Analyzer Tests
5.5 添加分析器测试
rust
// crates/vx-project-analyzer/tests/analyzer_tests.rs
#[tokio::test]
async fn test_{lang}_project_detection() {
let temp = TempDir::new().unwrap();
std::fs::write(temp.path().join("{config_file}"), "...").unwrap();
let analyzer = {Lang}Analyzer::new();
assert!(analyzer.detect(temp.path()));
}
#[tokio::test]
async fn test_{lang}_scripts() {
let temp = TempDir::new().unwrap();
std::fs::write(temp.path().join("{config_file}"), "...").unwrap();
let analyzer = {Lang}Analyzer::new();
let scripts = analyzer.analyze_scripts(temp.path()).await.unwrap();
assert!(scripts.iter().any(|s| s.name == "test"));
}rust
// crates/vx-project-analyzer/tests/analyzer_tests.rs
#[tokio::test]
async fn test_{lang}_project_detection() {
let temp = TempDir::new().unwrap();
std::fs::write(temp.path().join("{config_file}"), "...").unwrap();
let analyzer = {Lang}Analyzer::new();
assert!(analyzer.detect(temp.path()));
}
#[tokio::test]
async fn test_{lang}_scripts() {
let temp = TempDir::new().unwrap();
std::fs::write(temp.path().join("{config_file}"), "...").unwrap();
let analyzer = {Lang}Analyzer::new();
let scripts = analyzer.analyze_scripts(temp.path()).await.unwrap();
assert!(scripts.iter().any(|s| s.name == "test"));
}Step 6: Update Snapshot Tests
步骤6:更新快照测试
Update provider/runtime counts in:
- - Increment "Total providers" and "Total runtimes"
tests/cmd/plugin/plugin-stats.md - - Add the new runtime to the search results
tests/cmd/search/search.md
在以下文件中更新provider/runtime计数:
- - 增加“Total providers”和“Total runtimes”的数值
tests/cmd/plugin/plugin-stats.md - - 在搜索结果中添加新的runtime
tests/cmd/search/search.md
Step 7: Add Documentation
步骤7:添加文档
Add documentation for the new tool in the appropriate category:
在对应分类中添加新工具的文档:
English Documentation (docs/tools/
)
docs/tools/英文文档(docs/tools/
)
docs/tools/| Category | File | Tools |
|---|---|---|
| DevOps | | terraform, docker, kubectl, helm, git |
| Cloud CLI | | aws, az, gcloud |
| Build Tools | | just, task, cmake, ninja, protoc, vite |
| AI Tools | | ollama |
| Scientific/HPC | | spack, rez |
| Code Quality | | pre-commit |
| Other | | deno, zig, java, vscode, rcedit, choco |
| 分类 | 文件 | 工具 |
|---|---|---|
| DevOps | | terraform、docker、kubectl、helm、git |
| Cloud CLI | | aws、az、gcloud |
| Build Tools | | just、task、cmake、ninja、protoc、vite |
| AI Tools | | ollama |
| Scientific/HPC | | spack、rez |
| Code Quality | | pre-commit |
| Other | | deno、zig、java、vscode、rcedit、choco |
Chinese Documentation (docs/zh/tools/
)
docs/zh/tools/中文文档(docs/zh/tools/
)
docs/zh/tools/Create corresponding Chinese documentation with the same structure.
创建结构相同的对应中文文档。
Documentation Template
文档模板
markdown
undefinedmarkdown
undefined{Tool Name}
{Tool Name}
{Brief description}
bash
vx install {name} latest
vx {name} --version
vx {name} {common-command-1}
vx {name} {common-command-2}Key Features: (optional)
- Feature 1
- Feature 2
Platform Support: (if special)
- Windows: {notes}
- Linux/macOS: {notes}
undefined{简要描述}
bash
vx install {name} latest
vx {name} --version
vx {name} {common-command-1}
vx {name} {common-command-2}主要特性:(可选)
- 特性1
- 特性2
平台支持:(如有特殊说明)
- Windows: {说明}
- Linux/macOS: {说明}
undefinedStep 8: Version Fetching Strategies
步骤8:版本获取策略
GitHub Releases (Preferred)
GitHub Releases(首选)
rust
ctx.fetch_github_releases(
"runtime-name",
"owner",
"repo",
GitHubReleaseOptions::new()
.strip_v_prefix(false) // Set true if versions have 'v' prefix
.skip_prereleases(true),
).awaitrust
ctx.fetch_github_releases(
"runtime-name",
"owner",
"repo",
GitHubReleaseOptions::new()
.strip_v_prefix(false) // 若版本带有'v'前缀则设为true
.skip_prereleases(true),
).awaitManual GitHub API
手动调用GitHub API
rust
let url = "https://api.github.com/repos/{owner}/{repo}/releases";
let response = ctx.http.get_json_value(url).await?;
// Parse response and build VersionInforust
let url = "https://api.github.com/repos/{owner}/{repo}/releases";
let response = ctx.http.get_json_value(url).await?;
// 解析响应并构建VersionInfoStep 9: Verification and Testing
步骤9:验证与测试
bash
undefinedbash
undefinedCheck compilation
检查编译
cargo check -p vx-provider-{name}
cargo check -p vx-provider-{name}
Run tests
运行测试
cargo test -p vx-provider-{name}
cargo test -p vx-provider-{name}
If analyzer was added
若添加了分析器
cargo test -p vx-project-analyzer
cargo test -p vx-project-analyzer
Verify full workspace
验证整个工作区
cargo check
cargo check
Run snapshot tests
运行快照测试
cargo test --test cli_tests
undefinedcargo test --test cli_tests
undefinedCommon Patterns
常见模式
VersionInfo Construction
VersionInfo构建
rust
VersionInfo::new(version)
.with_lts(false)
.with_prerelease(false)
.with_release_date(date_string)rust
VersionInfo::new(version)
.with_lts(false)
.with_prerelease(false)
.with_release_date(date_string)VerificationResult
VerificationResult
rust
// Success
VerificationResult::success(exe_path)
// Failure
VerificationResult::failure(
vec!["Error message".to_string()],
vec!["Suggested fix".to_string()],
)rust
// 成功
VerificationResult::success(exe_path)
// 失败
VerificationResult::failure(
vec!["错误信息".to_string()],
vec!["建议修复方案".to_string()],
)Platform Matching
平台匹配
rust
match (&platform.os, &platform.arch) {
(Os::Windows, Arch::X86_64) => Some("x86_64-pc-windows-msvc"),
(Os::Windows, Arch::Aarch64) => Some("aarch64-pc-windows-msvc"),
(Os::MacOS, Arch::X86_64) => Some("x86_64-apple-darwin"),
(Os::MacOS, Arch::Aarch64) => Some("aarch64-apple-darwin"),
(Os::Linux, Arch::X86_64) => Some("x86_64-unknown-linux-musl"),
(Os::Linux, Arch::Aarch64) => Some("aarch64-unknown-linux-musl"),
_ => None,
}rust
match (&platform.os, &platform.arch) {
(Os::Windows, Arch::X86_64) => Some("x86_64-pc-windows-msvc"),
(Os::Windows, Arch::Aarch64) => Some("aarch64-pc-windows-msvc"),
(Os::MacOS, Arch::X86_64) => Some("x86_64-apple-darwin"),
(Os::MacOS, Arch::Aarch64) => Some("aarch64-apple-darwin"),
(Os::Linux, Arch::X86_64) => Some("x86_64-unknown-linux-musl"),
(Os::Linux, Arch::Aarch64) => Some("aarch64-unknown-linux-musl"),
_ => None,
}Executable Path Configuration (Layered API)
可执行文件路径配置(分层API)
The framework provides a layered approach - most providers only need 1-2 overrides:
rust
// 1. Simple case: executable in root with standard .exe
// No overrides needed, defaults work
// 2. Tool uses .cmd on Windows (npm, yarn, npx)
fn executable_extensions(&self) -> &[&str] {
&[".cmd", ".exe"]
}
// 3. Executable in subdirectory
fn executable_dir_path(&self, version: &str, _platform: &Platform) -> Option<String> {
Some(format!("myapp-{}", version))
}
// 4. Different executable name than runtime name
fn executable_name(&self) -> &str {
"python3" // Runtime name is "python"
}
// 5. Complex platform-specific paths (Node.js style)
fn executable_dir_path(&self, version: &str, platform: &Platform) -> Option<String> {
let dir = format!("node-v{}-{}", version, platform.as_str());
if platform.is_windows() {
Some(dir) // Windows: no bin subdir
} else {
Some(format!("{}/bin", dir)) // Unix: has bin subdir
}
}框架提供分层方法 - 大多数provider仅需1-2种覆盖配置:
rust
// 1. 简单情况:可执行文件在根目录,使用标准.exe扩展名
// 无需覆盖,默认配置即可
// 2. 工具在Windows上使用.cmd扩展名(npm、yarn、npx)
fn executable_extensions(&self) -> &[&str] {
&[".cmd", ".exe"]
}
// 3. 可执行文件在子目录中
fn executable_dir_path(&self, version: &str, _platform: &Platform) -> Option<String> {
Some(format!("myapp-{}", version))
}
// 4. 可执行文件名称与runtime名称不同
fn executable_name(&self) -> &str {
"python3" // Runtime名称是"python"
}
// 5. 复杂的平台特定路径(Node.js风格)
fn executable_dir_path(&self, version: &str, platform: &Platform) -> Option<String> {
let dir = format!("node-v{}-{}", version, platform.as_str());
if platform.is_windows() {
Some(dir) // Windows:无bin子目录
} else {
Some(format!("{}/bin", dir)) // Unix:有bin子目录
}
}ScriptRule Priority Guidelines
ScriptRule优先级指南
| Priority | Use Case |
|---|---|
| 100 | Task runners (nox, tox, just, make) |
| 90 | Secondary task runners |
| 50 | Default tools (pytest, ruff, cargo) |
| 优先级 | 使用场景 |
|---|---|
| 100 | 任务运行器(nox、tox、just、make) |
| 90 | 次要任务运行器 |
| 50 | 默认工具(pytest、ruff、cargo) |
System Package Manager Integration
系统包管理器集成
For tools without portable binaries on all platforms, implement system package manager fallback.
对于并非所有平台都有可移植二进制文件的工具,实现系统包管理器回退。
When to Use System Package Manager
何时使用系统包管理器
| Platform | No Direct Download | Package Manager Options |
|---|---|---|
| macOS | No portable binary | brew (priority 90) |
| Windows | No portable binary | winget (95), choco (80), scoop (60) |
| Linux | No portable binary | apt (90), dnf (85), pacman (80) |
| 平台 | 无直接下载包 | 包管理器选项 |
|---|---|---|
| macOS | 无可移植二进制文件 | brew(优先级90) |
| Windows | 无可移植二进制文件 | winget(95)、choco(80)、scoop(60) |
| Linux | 无可移植二进制文件 | apt(90)、dnf(85)、pacman(80) |
Step 1: Add system_deps.pre_depends in provider.toml
步骤1:在provider.toml中添加system_deps.pre_depends
Declare which package managers are required as dependencies:
toml
undefined声明所需的包管理器依赖:
toml
undefinedmacOS requires Homebrew
macOS需要Homebrew
[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "brew"
platforms = ["macos"]
reason = "Required to install {tool} on macOS (no portable binary available)"
optional = false # brew is required
[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "brew"
platforms = ["macos"]
reason = "在macOS上安装{tool}需要依赖Homebrew(无可移植二进制文件)"
optional = false # brew是必需的
Windows: winget (preferred), choco, or scoop (any one is sufficient)
Windows:winget(首选)、choco或scoop(任意一个即可)
[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "winget"
platforms = ["windows"]
reason = "Preferred package manager for Windows (built-in on Windows 11)"
optional = true # any one of winget/choco/scoop is sufficient
[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "choco"
platforms = ["windows"]
reason = "Alternative to winget for Windows installation"
optional = true
[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "scoop"
platforms = ["windows"]
reason = "Alternative to winget for Windows installation"
optional = true
undefined[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "winget"
platforms = ["windows"]
reason = "Windows首选包管理器(Windows 11内置)"
optional = true # winget/choco/scoop任意一个即可
[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "choco"
platforms = ["windows"]
reason = "Windows安装的替代包管理器"
optional = true
[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "scoop"
platforms = ["windows"]
reason = "Windows安装的替代包管理器"
optional = true
undefinedStep 2: Add system_install.strategies in provider.toml
步骤2:在provider.toml中添加system_install.strategies
Define how to install via each package manager:
toml
undefined定义通过各包管理器安装的方式:
toml
undefinedSystem installation strategies for platforms without direct download
无直接下载包的平台使用系统安装策略
[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "brew"
package = "mytool" # Homebrew package name
platforms = ["macos"]
priority = 90
[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "winget"
package = "Publisher.Package" # winget uses Publisher.Package format
platforms = ["windows"]
priority = 95 # Highest priority on Windows (built-in on Win11)
[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "choco"
package = "mytool"
platforms = ["windows"]
priority = 80
[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "scoop"
package = "mytool"
platforms = ["windows"]
priority = 60
undefined[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "brew"
package = "mytool" # Homebrew中的包名
platforms = ["macos"]
priority = 90
[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "winget"
package = "Publisher.Package" # winget使用Publisher.Package格式
platforms = ["windows"]
priority = 95 # Windows上优先级最高(Win11内置)
[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "choco"
package = "mytool"
platforms = ["windows"]
priority = 80
[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "scoop"
package = "mytool"
platforms = ["windows"]
priority = 60
undefinedStep 3: Implement install() Method with Fallback
步骤3:实现带有回退的install()方法
For hybrid providers, override to try direct download first, then fall back to package manager:
install()rust
use vx_system_pm::{PackageInstallSpec, PackageManagerRegistry};
use vx_runtime::{InstallResult, Runtime, RuntimeContext};
impl MyRuntime {
/// Get package name for specific package manager
fn get_package_name_for_manager(manager: &str) -> &'static str {
match manager {
"winget" => "Publisher.MyTool", // winget uses Publisher.Package format
"brew" | "choco" | "scoop" | "apt" => "mytool",
"dnf" | "yum" => "MyTool", // Some use different casing
_ => "mytool",
}
}
/// Install via system package manager
async fn install_via_package_manager(
&self,
version: &str,
_ctx: &RuntimeContext,
) -> Result<InstallResult> {
let registry = PackageManagerRegistry::new();
let available_managers = registry.get_available().await;
if available_managers.is_empty() {
return Err(anyhow::anyhow!(
"No package manager available. Please install brew (macOS) or winget/choco/scoop (Windows)"
));
}
// Try each available package manager (sorted by priority)
for pm in &available_managers {
let package_name = Self::get_package_name_for_manager(pm.name());
let spec = PackageInstallSpec {
package: package_name.to_string(),
..Default::default()
};
match pm.install_package(&spec).await {
Ok(_) => {
// Return system-installed result with actual executable path
let exe_path = which::which("mytool").ok();
return Ok(InstallResult::system_installed(
format!("{} (via {})", version, pm.name()),
exe_path,
));
}
Err(e) => {
tracing::warn!("Failed to install via {}: {}", pm.name(), e);
continue;
}
}
}
Err(anyhow::anyhow!("All package managers failed"))
}
}
#[async_trait]
impl Runtime for MyRuntime {
async fn install(&self, version: &str, ctx: &RuntimeContext) -> Result<InstallResult> {
let platform = Platform::current();
// Try direct download first (if available for this platform)
if let Some(url) = self.download_url(version, &platform).await? {
return self.install_via_download(version, &url, ctx).await;
}
// Fall back to system package manager
self.install_via_package_manager(version, ctx).await
}
}对于混合provider,覆盖方法,先尝试直接下载,失败则回退到包管理器:
install()rust
use vx_system_pm::{PackageInstallSpec, PackageManagerRegistry};
use vx_runtime::{InstallResult, Runtime, RuntimeContext};
impl MyRuntime {
/// 获取特定包管理器对应的包名
fn get_package_name_for_manager(manager: &str) -> &'static str {
match manager {
"winget" => "Publisher.MyTool", // winget使用Publisher.Package格式
"brew" | "choco" | "scoop" | "apt" => "mytool",
"dnf" | "yum" => "MyTool", // 部分包管理器使用不同大小写
_ => "mytool",
}
}
/// 通过系统包管理器安装
async fn install_via_package_manager(
&self,
version: &str,
_ctx: &RuntimeContext,
) -> Result<InstallResult> {
let registry = PackageManagerRegistry::new();
let available_managers = registry.get_available().await;
if available_managers.is_empty() {
return Err(anyhow::anyhow!(
"无可用包管理器。请安装brew(macOS)或winget/choco/scoop(Windows)"
));
}
// 按优先级尝试每个可用的包管理器
for pm in &available_managers {
let package_name = Self::get_package_name_for_manager(pm.name());
let spec = PackageInstallSpec {
package: package_name.to_string(),
..Default::default()
};
match pm.install_package(&spec).await {
Ok(_) => {
// 返回系统安装结果及实际可执行文件路径
let exe_path = which::which("mytool").ok();
return Ok(InstallResult::system_installed(
format!("{} (via {})", version, pm.name()),
exe_path,
));
}
Err(e) => {
tracing::warn!("通过{}安装失败: {}", pm.name(), e);
continue;
}
}
}
Err(anyhow::anyhow!("所有包管理器安装均失败"))
}
}
#[async_trait]
impl Runtime for MyRuntime {
async fn install(&self, version: &str, ctx: &RuntimeContext) -> Result<InstallResult> {
let platform = Platform::current();
// 首先尝试直接下载(若该平台支持)
if let Some(url) = self.download_url(version, &platform).await? {
return self.install_via_download(version, &url, ctx).await;
}
// 回退到系统包管理器
self.install_via_package_manager(version, ctx).await
}
}Step 4: Handle InstallResult Correctly
步骤4:正确处理InstallResult
Important: System-installed tools have different paths than store-installed tools:
rust
// Store-installed: executable in ~/.vx/store/{tool}/{version}/bin/
InstallResult::success(install_path, exe_path, version)
// System-installed: executable in system PATH (e.g., /opt/homebrew/bin/)
InstallResult::system_installed(version, Some(exe_path))The test handler and other code must check from rather than computing store paths.
executable_pathInstallResult重要提示:系统安装的工具路径与存储安装的工具路径不同:
rust
// 存储安装:可执行文件在~/.vx/store/{tool}/{version}/bin/
InstallResult::success(install_path, exe_path, version)
// 系统安装:可执行文件在系统PATH中(例如/opt/homebrew/bin/)
InstallResult::system_installed(version, Some(exe_path))测试处理程序及其他代码必须从中获取,而非计算存储路径。
InstallResultexecutable_pathPackage Manager Priority Reference
包管理器优先级参考
| Manager | Platform | Priority | Notes |
|---|---|---|---|
| winget | Windows | 95 | Built-in on Win11, App Installer on Win10 |
| brew | macOS | 90 | De-facto standard for macOS |
| apt | Linux (Debian) | 90 | Debian/Ubuntu default |
| dnf | Linux (Fedora) | 85 | Fedora/RHEL default |
| choco | Windows | 80 | Popular third-party |
| pacman | Linux (Arch) | 80 | Arch Linux default |
| scoop | Windows | 60 | Developer-focused |
| 管理器 | 平台 | 优先级 | 说明 |
|---|---|---|---|
| winget | Windows | 95 | Windows 11内置,Windows 10需安装App Installer |
| brew | macOS | 90 | macOS事实上的标准包管理器 |
| apt | Linux (Debian) | 90 | Debian/Ubuntu默认包管理器 |
| dnf | Linux (Fedora) | 85 | Fedora/RHEL默认包管理器 |
| choco | Windows | 80 | 流行的第三方包管理器 |
| pacman | Linux (Arch) | 80 | Arch Linux默认包管理器 |
| scoop | Windows | 60 | 面向开发者的包管理器 |
Common Package Names
常见包名对应表
| Tool | brew | winget | choco | scoop | apt |
|---|---|---|---|---|---|
| ImageMagick | imagemagick | ImageMagick.ImageMagick | imagemagick | imagemagick | imagemagick |
| FFmpeg | ffmpeg | Gyan.FFmpeg | ffmpeg | ffmpeg | ffmpeg |
| Git | git | Git.Git | git | git | git |
| AWS CLI | awscli | Amazon.AWSCLI | awscli | aws | awscli |
| Azure CLI | azure-cli | Microsoft.AzureCLI | azure-cli | - | azure-cli |
| Docker | docker | Docker.DockerDesktop | docker-desktop | - | docker.io |
| 工具 | brew | winget | choco | scoop | apt |
|---|---|---|---|---|---|
| ImageMagick | imagemagick | ImageMagick.ImageMagick | imagemagick | imagemagick | imagemagick |
| FFmpeg | ffmpeg | Gyan.FFmpeg | ffmpeg | ffmpeg | ffmpeg |
| Git | git | Git.Git | git | git | git |
| AWS CLI | awscli | Amazon.AWSCLI | awscli | aws | awscli |
| Azure CLI | azure-cli | Microsoft.AzureCLI | azure-cli | - | azure-cli |
| Docker | docker | Docker.DockerDesktop | docker-desktop | - | docker.io |
provider.toml Quick Reference
provider.toml快速参考
Minimal Example (GitHub Releases with Layout)
最小示例(GitHub Releases + 布局配置)
toml
[provider]
name = "mytool"
description = "My awesome tool"
homepage = "https://github.com/owner/repo"
repository = "https://github.com/owner/repo"
ecosystem = "devtools"
[[runtimes]]
name = "mytool"
description = "My tool CLI"
executable = "mytool"
[runtimes.versions]
source = "github-releases"
owner = "owner"
repo = "repo"
strip_v_prefix = truetoml
[provider]
name = "mytool"
description = "My awesome tool"
homepage = "https://github.com/owner/repo"
repository = "https://github.com/owner/repo"
ecosystem = "devtools"
[[runtimes]]
name = "mytool"
description = "My tool CLI"
executable = "mytool"
[runtimes.versions]
source = "github-releases"
owner = "owner"
repo = "repo"
strip_v_prefix = trueRFC 0019: Executable Layout Configuration
RFC 0019:可执行文件布局配置
[runtimes.layout]
download_type = "archive" # or "binary"
[runtimes.layout.archive]
strip_prefix = "mytool-{version}"
executable_paths = [
"bin/mytool.exe", # Windows
"bin/mytool" # Unix
]
[runtimes.platforms.windows]
executable_extensions = [".exe"]
[runtimes.platforms.unix]
executable_extensions = []
undefined[runtimes.layout]
download_type = "archive" # 或"binary"
[runtimes.layout.archive]
strip_prefix = "mytool-{version}"
executable_paths = [
"bin/mytool.exe", # Windows
"bin/mytool" # Unix
]
[runtimes.platforms.windows]
executable_extensions = [".exe"]
[runtimes.platforms.unix]
executable_extensions = []
undefinedBinary Download Example
二进制下载示例
toml
[runtimes.layout]
download_type = "binary"
[runtimes.layout.binary."windows-x86_64"]
source_name = "mytool-{version}-win64.exe"
target_name = "mytool.exe"
target_dir = "bin"
[runtimes.layout.binary."linux-x86_64"]
source_name = "mytool-{version}-linux"
target_name = "mytool"
target_dir = "bin"
target_permissions = "755"toml
[runtimes.layout]
download_type = "binary"
[runtimes.layout.binary."windows-x86_64"]
source_name = "mytool-{version}-win64.exe"
target_name = "mytool.exe"
target_dir = "bin"
[runtimes.layout.binary."linux-x86_64"]
source_name = "mytool-{version}-linux"
target_name = "mytool"
target_dir = "bin"
target_permissions = "755"Hybrid Provider Example (Direct Download + Package Manager Fallback)
混合Provider示例(直接下载 + 包管理器回退)
For tools like ImageMagick that have direct download on some platforms but need package managers on others:
toml
[provider]
name = "mytool"
description = "My awesome tool"
homepage = "https://example.com"
ecosystem = "devtools"
[[runtimes]]
name = "mytool"
description = "My tool CLI"
executable = "mytool"
[runtimes.versions]
source = "github-releases"
owner = "owner"
repo = "repo"适用于像ImageMagick这样部分平台有直接下载包、其他平台需要包管理器的工具:
toml
[provider]
name = "mytool"
description = "My awesome tool"
homepage = "https://example.com"
ecosystem = "devtools"
[[runtimes]]
name = "mytool"
description = "My tool CLI"
executable = "mytool"
[runtimes.versions]
source = "github-releases"
owner = "owner"
repo = "repo"Linux: Direct download available (AppImage, binary, etc.)
Linux:支持直接下载(AppImage、二进制文件等)
[runtimes.layout]
download_type = "binary"
[runtimes.layout.binary."linux-x86_64"]
source_name = "mytool-{version}-linux-x64"
target_name = "mytool"
target_dir = "bin"
target_permissions = "755"
[runtimes.layout]
download_type = "binary"
[runtimes.layout.binary."linux-x86_64"]
source_name = "mytool-{version}-linux-x64"
target_name = "mytool"
target_dir = "bin"
target_permissions = "755"
Note: No Windows/macOS binary configs = download_url returns None
注意:未配置Windows/macOS二进制文件 = download_url返回None
Triggers package manager fallback
触发包管理器回退
macOS requires Homebrew
macOS需要Homebrew
[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "brew"
platforms = ["macos"]
reason = "Required to install mytool on macOS (no portable binary available)"
optional = false
[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "brew"
platforms = ["macos"]
reason = "在macOS上安装mytool需要依赖Homebrew(无可移植二进制文件)"
optional = false
Windows: winget (preferred) or choco/scoop
Windows:winget(首选)或choco/scoop
[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "winget"
platforms = ["windows"]
reason = "Preferred package manager for Windows (built-in on Windows 11)"
optional = true
[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "choco"
platforms = ["windows"]
reason = "Alternative to winget for Windows installation"
optional = true
[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "winget"
platforms = ["windows"]
reason = "Windows首选包管理器(Windows 11内置)"
optional = true
[[runtimes.system_deps.pre_depends]]
type = "runtime"
id = "choco"
platforms = ["windows"]
reason = "Windows安装的替代包管理器"
optional = true
System installation strategies
系统安装策略
[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "brew"
package = "mytool"
platforms = ["macos"]
priority = 90
[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "winget"
package = "Publisher.MyTool"
platforms = ["windows"]
priority = 95
[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "choco"
package = "mytool"
platforms = ["windows"]
priority = 80
undefined[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "brew"
package = "mytool"
platforms = ["macos"]
priority = 90
[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "winget"
package = "Publisher.MyTool"
platforms = ["windows"]
priority = 95
[[runtimes.system_install.strategies]]
type = "package_manager"
manager = "choco"
package = "mytool"
platforms = ["windows"]
priority = 80
undefinedprovider.toml Fields Reference
provider.toml字段参考
| Section | Field | Description |
|---|---|---|
| | Provider name (required) |
| Human-readable description | |
| Project homepage URL | |
| Source repository URL | |
| | |
| | Restrict to platforms: |
| | Runtime name (required) |
| Runtime description | |
| Executable file name (required) | |
| Alternative names list | |
| If bundled with another runtime | |
| | Version source type |
| GitHub owner (for github-releases/tags) | |
| GitHub repo name | |
| Remove 'v' from version tags | |
| | |
| | Downloaded file name (supports |
| Final executable name | |
| Target directory (e.g., | |
| Unix permissions (e.g., | |
| | Directory prefix to remove (supports |
| Paths to executables after stripping | |
| | Directory pattern (e.g., |
| Executable extensions list | |
| | |
| Package manager runtime id (brew, winget, choco, scoop) | |
| Array of platforms: | |
| Human-readable reason for dependency | |
| | |
| | |
| Package manager name (brew, winget, choco, scoop, apt, dnf) | |
| Package name in that manager | |
| Array of platforms this strategy applies to | |
| Priority (higher = preferred). winget=95, brew=90, choco=80, scoop=60 | |
| | Version condition (e.g., |
| Required dependencies list | |
| Recommended dependencies list |
| 章节 | 字段 | 描述 |
|---|---|---|
| | Provider名称(必填) |
| 人类可读的描述 | |
| 项目主页URL | |
| 源码仓库URL | |
| | |
| | 限制支持的平台: |
| | Runtime名称(必填) |
| Runtime描述 | |
| 可执行文件名(必填) | |
| 替代名称列表 | |
| 若该runtime与其他runtime捆绑 | |
| | 版本源类型 |
| GitHub所有者(适用于github-releases/tags) | |
| GitHub仓库名 | |
| 移除版本标签中的'v'前缀 | |
| | |
| | 下载文件名(支持 |
| 最终可执行文件名 | |
| 目标目录(例如 | |
| Unix权限(例如 | |
| | 要移除的目录前缀(支持 |
| 解压后可执行文件的路径 | |
| | 目录模式(例如 |
| 可执行文件扩展名列表 | |
| | |
| 包管理器runtime id(brew、winget、choco、scoop) | |
| 适用平台数组: | |
| 依赖该包管理器的原因(人类可读) | |
| | |
| | |
| 包管理器名称(brew、winget、choco、scoop、apt、dnf) | |
| 该包管理器中的包名 | |
| 该策略适用的平台数组 | |
| 优先级(数值越高越优先)。winget=95、brew=90、choco=80、scoop=60 | |
| | 版本条件(例如 |
| 必填依赖列表 | |
| 推荐依赖列表 |
Reference Files
参考文件
For complete code templates, see .
references/templates.md完整代码模板请参考。
references/templates.md