Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 30 additions & 23 deletions build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,26 @@ fn codegen_registry() {
.and_then(|v| v.as_str())
.unwrap_or_else(|| panic!("[{short}] 'test.expected' must be a string"))
.to_string();
(cmd, expected)
let tools = t
.get("tools")
.map(|tools| {
let mut tools = tools
.as_array()
.unwrap_or_else(|| panic!("[{short}] 'test.tools' must be an array"))
.iter()
.map(|v| {
v.as_str()
.unwrap_or_else(|| {
panic!("[{short}] 'test.tools' must contain only strings")
})
.to_string()
})
.collect::<Vec<_>>();
tools.sort();
tools
})
.unwrap_or_default();
(cmd, expected, tools)
});
let mut backends = vec![];
for backend in info.get("backends").unwrap().as_array().unwrap() {
Expand Down Expand Up @@ -202,18 +221,6 @@ fn codegen_registry() {
let description = info
.get("description")
.map(|d| d.as_str().unwrap().to_string());
let depends = info
.get("depends")
.map(|depends| {
let depends = depends.as_array().unwrap();
let mut depends = depends
.iter()
.map(|d| d.as_str().unwrap().to_string())
.collect::<Vec<_>>();
depends.sort();
depends
})
.unwrap_or_default();
let idiomatic_files = info
.get("idiomatic_files")
.map(|idiomatic_files| {
Expand Down Expand Up @@ -248,7 +255,7 @@ fn codegen_registry() {
})
.unwrap_or_default();
let rt = format!(
r#"RegistryTool{{short: "{short}", description: {description}, backends: &[{backends}], aliases: &[{aliases}], test: &{test}, os: &[{os}], depends: &[{depends}], idiomatic_files: &[{idiomatic_files}], detect: &[{detect}], overrides: &[{overrides}]}}"#,
r#"RegistryTool{{short: "{short}", description: {description}, backends: &[{backends}], aliases: &[{aliases}], test: &{test}, os: &[{os}], idiomatic_files: &[{idiomatic_files}], detect: &[{detect}], overrides: &[{overrides}]}}"#,
description = description
.map(|d| format!("Some({})", raw_string_literal(&d)))
.unwrap_or("None".to_string()),
Expand All @@ -259,22 +266,22 @@ fn codegen_registry() {
.collect::<Vec<_>>()
.join(", "),
test = test
.map(|(t, v)| format!(
"Some(({}, {}))",
raw_string_literal(&t),
raw_string_literal(&v)
.map(|(cmd, expected, tools)| format!(
"Some(RegistryToolTest{{ cmd: {}, expected: {}, tools: &[{}] }})",
raw_string_literal(&cmd),
raw_string_literal(&expected),
tools
.iter()
.map(|tool| format!("\"{tool}\""))
.collect::<Vec<_>>()
.join(", ")
))
.unwrap_or("None".to_string()),
os = os
.iter()
.map(|o| format!("\"{o}\""))
.collect::<Vec<_>>()
.join(", "),
depends = depends
.iter()
.map(|d| format!("\"{d}\""))
.collect::<Vec<_>>()
.join(", "),
idiomatic_files = idiomatic_files
.iter()
.map(|f| format!("\"{f}\""))
Expand Down
13 changes: 9 additions & 4 deletions docs/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -704,15 +704,20 @@ backend, but can override with explicit syntax like `mise use aqua:owner/repo`.
All tools must include a test to verify proper installation:

```toml
test = [
"command-to-run",
"expected-output-pattern"
]
test = { cmd = "command-to-run", expected = "expected-output-pattern" }
```

The test command should be reliable and the output pattern should use
<code v-pre>{{version}}</code> to match any version number.

If `test.cmd` needs extra mise-managed tools on PATH, declare them with
`test.tools`. This is used only by `mise test-tool`; it does not affect normal
tool installation.

```toml
test = { cmd = "gradle -V", expected = "Gradle", tools = ["java"] }
```

### Registry Examples

Recent tool additions:
Expand Down
3 changes: 1 addition & 2 deletions registry/android-sdk.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
backends = ["vfox:mise-plugins/vfox-android-sdk"]
depends = ["java"]
description = "Android Command-line tools"
test = { cmd = "sdkmanager --version", expected = ".0" }
test = { cmd = "sdkmanager --version", expected = ".0", tools = ["java"] }
1 change: 0 additions & 1 deletion registry/elixir.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
backends = ["core:elixir"]
depends = ["erlang"]
description = "Elixir is a dynamic, functional language for building scalable and maintainable applications"
1 change: 0 additions & 1 deletion registry/google-java-format.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
backends = ["aqua:google/google-java-format"]
depends = ["java"]
description = "Reformats Java source code to comply with Google Java Style"
test = { cmd = "google-java-format --version", expected = "google-java-format: Version {{version}}" }
3 changes: 1 addition & 2 deletions registry/gradle.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
backends = ["aqua:gradle/gradle", "vfox:mise-plugins/vfox-gradle"]
depends = ["java"]
description = "Gradle is the open source build system of choice for Java, Android, and Kotlin developers"
test = { cmd = "gradle -V", expected = "Gradle" }
test = { cmd = "gradle -V", expected = "Gradle", tools = ["java"] }
5 changes: 3 additions & 2 deletions registry/kscript.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
backends = ["github:kscripting/kscript", "asdf:edgelevel/asdf-kscript"]
depends = ["kotlin"]
description = "Scripting enhancements for Kotlin"
test = { cmd = "kscript --version", expected = "Version : {{version}}" }
test = { cmd = "kscript --version", expected = "Version : {{version}}", tools = [
"kotlin",
] }
1 change: 0 additions & 1 deletion registry/ktlint.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
backends = ["aqua:pinterest/ktlint", "asdf:mise-plugins/mise-ktlint"]
depends = ["java"]
description = "An anti-bikeshedding Kotlin linter with built-in formatter"
# test = ["ktlint --version", "ktlint version {{version}}"] # DISABLED: upstream bug - release 1.7.2 not found on GitHub
1 change: 0 additions & 1 deletion registry/kubecolor.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
backends = ["aqua:kubecolor/kubecolor", "asdf:dex4er/asdf-kubecolor"]
depends = ["kubectl"]
description = "Colorize your kubectl output"
test = { cmd = "kubecolor --kubecolor-version", expected = "{{version}}" }
5 changes: 3 additions & 2 deletions registry/pipenv.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
backends = ["vfox:mise-plugins/vfox-pipenv", "pipx:pipenv"]
depends = ["python"]
description = "Python Development Workflow for Humans"
test = { cmd = "pipenv --version", expected = "pipenv, version {{version}}" }
test = { cmd = "pipenv --version", expected = "pipenv, version {{version}}", tools = [
"python",
] }
3 changes: 1 addition & 2 deletions registry/pipx.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
backends = ["aqua:pypa/pipx", "asdf:mise-plugins/mise-pipx"]
depends = ["python"]
test = { cmd = "pipx --version", expected = "{{version}}" }
test = { cmd = "pipx --version", expected = "{{version}}", tools = ["python"] }
5 changes: 3 additions & 2 deletions registry/rebar.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
backends = [
{ full = "github:erlang/rebar3", options = { asset_pattern = "rebar3" } },
]
depends = ["erlang"]
description = "Erlang build tool that makes it easy to compile and test Erlang applications and releases"
test = { cmd = "rebar3 --version", expected = "rebar {{version}}" }
test = { cmd = "rebar3 --version", expected = "rebar {{version}}", tools = [
"erlang",
] }
1 change: 0 additions & 1 deletion registry/sbt.toml
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
backends = ["conda:sbt", "asdf:mise-plugins/mise-sbt"]
depends = ["java"]
description = "sbt, the interactive build tool"
test = { cmd = "sbt --version", expected = "sbt" }
1 change: 0 additions & 1 deletion registry/spark.toml
Original file line number Diff line number Diff line change
@@ -1,3 +1,2 @@
backends = ["aqua:apache/spark", "asdf:mise-plugins/mise-spark"]
depends = ["java"]
description = "Apache Spark - A unified analytics engine for large-scale data processing"
1 change: 0 additions & 1 deletion registry/tridentctl.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ backends = [
"aqua:NetApp/trident/tridentctl",
"asdf:asdf-community/asdf-tridentctl",
]
depends = ["kubectl"]
description = "Storage orchestrator for containers"
os = ["linux", "macos"]
test = { cmd = "tridentctl version --client", expected = "{{version}}" }
16 changes: 8 additions & 8 deletions schema/mise-registry-tool.json
Original file line number Diff line number Diff line change
Expand Up @@ -74,14 +74,6 @@
"description": "List of backends that can install this tool",
"minItems": 1
},
"depends": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-zA-Z0-9_.-]+$"
},
"description": "Other tools this tool depends on"
},
"description": {
"type": "string",
"description": "A brief description of the tool"
Expand Down Expand Up @@ -126,6 +118,14 @@
"expected": {
"type": "string",
"description": "Expected substring in the command output"
},
"tools": {
"type": "array",
"items": {
"type": "string",
"pattern": "^[a-zA-Z0-9_.-]+$"
},
"description": "Additional mise tools to install before running test.cmd. Used only by mise test-tool."
}
},
"required": ["cmd", "expected"],
Expand Down
4 changes: 0 additions & 4 deletions src/backend/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -714,10 +714,6 @@ pub trait Backend: Debug + Send + Sync {
deps.extend(self.get_optional_dependencies()?);
}
let mut deps: IndexSet<_> = deps.into_iter().map(BackendArg::from).collect();
if let Some(rt) = REGISTRY.get(self.ba().short.as_str()) {
// add dependencies from registry/
deps.extend(rt.depends.iter().map(BackendArg::from));
}
deps.retain(|ba| &**self.ba() != ba);
deps.retain(|ba| !all_fulls.contains(&ba.full()));
for ba in deps.clone() {
Expand Down
31 changes: 27 additions & 4 deletions src/cli/test_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,10 +60,18 @@ impl TestTool {
{
continue;
}
let (cmd, expected) = if let Some(test) = &rt.test {
(test.0.to_string(), test.1.to_string())
let (cmd, expected, tools) = if let Some(test) = rt.test.as_ref() {
(
test.cmd.to_string(),
test.expected.to_string(),
test.tools.iter().map(|tool| tool.to_string()).collect(),
)
} else if self.include_non_defined {
(format!("{} --version", tool.short), "__TODO__".to_string())
(
format!("{} --version", tool.short),
"__TODO__".to_string(),
vec![],
)
} else {
continue;
};
Expand All @@ -72,6 +80,7 @@ impl TestTool {
tool,
cmd,
expected,
tools,
});
}

Expand Down Expand Up @@ -135,7 +144,13 @@ impl TestTool {
let tool = target.tool.short.clone();
let start = std::time::Instant::now();
let result = match self
.test(&config, &target.tool, &target.cmd, &target.expected)
.test(
&config,
&target.tool,
&target.cmd,
&target.expected,
&target.tools,
)
.await
{
Ok(output) => TestToolResult {
Expand Down Expand Up @@ -337,6 +352,7 @@ impl TestTool {
tool: &ToolArg,
cmd: &str,
expected: &str,
test_tools: &[String],
) -> Result<String> {
let mut config = config.clone();
let mut args = vec![tool.clone()];
Expand All @@ -348,6 +364,12 @@ impl TestTool {
.map(|ba| ba.to_string().parse())
.collect::<Result<Vec<ToolArg>>>()?,
);
args.extend(
test_tools
.iter()
.map(|tool| tool.parse())
.collect::<Result<Vec<ToolArg>>>()?,
);
let mut ts = ToolsetBuilder::new()
.with_args(&args)
.with_default_to_latest(true)
Expand Down Expand Up @@ -444,6 +466,7 @@ struct TestToolTarget {
tool: ToolArg,
cmd: String,
expected: String,
tools: Vec<String>,
}

struct TestToolResult {
Expand Down
10 changes: 8 additions & 2 deletions src/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,19 @@ pub struct RegistryTool {
#[allow(unused)]
pub aliases: &'static [&'static str],
pub overrides: &'static [&'static str],
pub test: &'static Option<(&'static str, &'static str)>,
pub test: &'static Option<RegistryToolTest>,
pub os: &'static [&'static str],
pub depends: &'static [&'static str],
pub idiomatic_files: &'static [&'static str],
pub detect: &'static [&'static str],
}

#[derive(Debug, Clone)]
pub struct RegistryToolTest {
pub cmd: &'static str,
pub expected: &'static str,
pub tools: &'static [&'static str],
}

#[derive(Debug, Clone)]
pub struct RegistryBackend {
pub full: &'static str,
Expand Down
Loading