-
-
Notifications
You must be signed in to change notification settings - Fork 948
feat(install): auto-install plugins from [plugins] config section #7856
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
feb19c1
5dea1f0
b69a871
4d1a3ea
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,48 @@ | ||
| #!/usr/bin/env bash | ||
|
|
||
| # Test that plugins in [plugins] section are auto-installed during mise install | ||
| # even when there are no corresponding tools in [tools] | ||
|
|
||
| # Use mise-env-fnox - an env-only plugin with no corresponding tool | ||
| rm -rf "$MISE_DATA_DIR/plugins/fnox-env" | ||
| mise plugin uninstall fnox-env 2>/dev/null || true | ||
|
|
||
| # Create a config with only a plugin (no tools using it) | ||
| cat <<EOF >mise.toml | ||
| [plugins] | ||
| fnox-env = "https://github.com/jdx/mise-env-fnox" | ||
| EOF | ||
|
|
||
| # Run mise install - plugin should be auto-installed even with no tools | ||
| mise install | ||
|
|
||
| # Verify plugin was actually installed (has git refs, not just registered) | ||
| # Using --refs shows URL and git info only for installed plugins | ||
| assert_contains "mise plugin ls --refs" "fnox-env" | ||
| assert_contains "mise plugin ls --refs" "https://github.com/jdx/mise-env-fnox" | ||
|
|
||
| # Now test with both a plugin-only entry and a tool | ||
| rm -rf "$MISE_DATA_DIR/plugins/fnox-env" | ||
| rm -rf "$MISE_DATA_DIR/plugins/zprint" | ||
| mise plugin uninstall fnox-env 2>/dev/null || true | ||
| mise plugin uninstall zprint 2>/dev/null || true | ||
|
|
||
| cat <<EOF >mise.toml | ||
| [plugins] | ||
| fnox-env = "https://github.com/jdx/mise-env-fnox" | ||
| zprint = "https://github.com/mise-plugins/mise-zprint" | ||
|
|
||
| [tools] | ||
| zprint = "latest" | ||
| EOF | ||
|
|
||
| # Run mise install - both plugins should be installed, zprint tool should be installed | ||
| mise install | ||
|
|
||
| # Verify both plugins were actually installed (have git refs) | ||
| # The URL only appears in --refs output when the plugin is actually installed | ||
| assert_contains "mise plugin ls --refs" "https://github.com/jdx/mise-env-fnox" | ||
| assert_contains "mise plugin ls --refs" "https://github.com/mise-plugins/mise-zprint" | ||
|
|
||
| # Verify zprint tool was installed | ||
| assert_contains "mise ls --installed zprint" "zprint" |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -11,6 +11,7 @@ use crate::config::settings::Settings; | |
| use crate::errors::Error; | ||
| use crate::hooks::{Hooks, InstalledToolInfo}; | ||
| use crate::install_context::InstallContext; | ||
| use crate::plugins::PluginType; | ||
| use crate::toolset::Toolset; | ||
| use crate::toolset::helpers::{get_leaf_dependencies, show_python_install_hint}; | ||
| use crate::toolset::install_options::InstallOptions; | ||
|
|
@@ -87,6 +88,11 @@ impl Toolset { | |
| mut versions: Vec<ToolRequest>, | ||
| opts: &InstallOptions, | ||
| ) -> Result<Vec<ToolVersion>> { | ||
| // Install all plugins from [plugins] config section first | ||
| // This must happen before the empty check so plugins are installed | ||
| // even when there are no tools to install (e.g., env-only plugins) | ||
| Self::ensure_config_plugins_installed(config, opts.dry_run).await?; | ||
|
|
||
| if versions.is_empty() { | ||
| return Ok(vec![]); | ||
| } | ||
|
|
@@ -464,4 +470,50 @@ impl Toolset { | |
| } | ||
| Ok(None) | ||
| } | ||
|
|
||
| /// Install all plugins defined in [plugins] config section | ||
| pub async fn ensure_config_plugins_installed( | ||
| config: &Arc<Config>, | ||
| dry_run: bool, | ||
| ) -> Result<()> { | ||
| if config.repo_urls.is_empty() { | ||
| return Ok(()); | ||
| } | ||
|
|
||
| let mpr = MultiProgressReport::get(); | ||
|
|
||
| for (plugin_key, url) in &config.repo_urls { | ||
| let (plugin_type, name) = Self::parse_plugin_key(plugin_key, url); | ||
|
|
||
| // Skip empty plugin names (e.g., from malformed keys like "" or "vfox:") | ||
| if name.is_empty() { | ||
| warn!("skipping empty plugin name from key: {plugin_key}"); | ||
| continue; | ||
| } | ||
|
|
||
| let plugin = plugin_type.plugin(name.to_string()); | ||
|
|
||
| if !plugin.is_installed() { | ||
| plugin | ||
| .ensure_installed(config, &mpr, false, dry_run) | ||
| .await?; | ||
| } | ||
| } | ||
| Ok(()) | ||
| } | ||
|
|
||
| fn parse_plugin_key<'a>(key: &'a str, url: &str) -> (PluginType, &'a str) { | ||
| if let Some(name) = key.strip_prefix("vfox:") { | ||
| (PluginType::Vfox, name) | ||
| } else if let Some(name) = key.strip_prefix("vfox-backend:") { | ||
| (PluginType::VfoxBackend, name) | ||
| } else if let Some(name) = key.strip_prefix("asdf:") { | ||
| (PluginType::Asdf, name) | ||
| } else if url.contains("vfox-") { | ||
| // Match existing behavior from config/mod.rs:226-228 | ||
| (PluginType::Vfox, key) | ||
| } else { | ||
| (PluginType::Asdf, key) | ||
| } | ||
| } | ||
|
Comment on lines
+505
to
+518
|
||
| } | ||
Uh oh!
There was an error while loading. Please reload this page.