feat(install): auto-install plugins from [plugins] config section#7856
feat(install): auto-install plugins from [plugins] config section#7856
Conversation
845b72c to
918bd03
Compare
There was a problem hiding this comment.
Pull request overview
This PR adds automatic installation of plugins defined in the [plugins] configuration section during tool installation. Previously, plugins were only installed when a tool using them was being installed, leaving standalone plugins (like env plugins) uninstalled.
Changes:
- Added
ensure_config_plugins_installed()method to install all plugins from config before tool installation - Added
parse_plugin_key()helper to determine plugin type from configuration keys - Integrated plugin installation into all tool install code paths
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| 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) | ||
| } | ||
| } |
There was a problem hiding this comment.
The plugin type parsing logic is duplicated from config/mod.rs (lines 226-228). Consider extracting this logic into a shared helper function in a common module to avoid code duplication and ensure consistent behavior across the codebase.
918bd03 to
4095e71
Compare
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.1.8 x -- echo |
19.8 ± 0.6 | 18.8 | 24.3 | 1.00 |
mise x -- echo |
20.2 ± 0.8 | 19.1 | 22.4 | 1.02 ± 0.05 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.1.8 env |
19.2 ± 0.7 | 18.2 | 23.3 | 1.00 |
mise env |
19.9 ± 0.8 | 18.7 | 24.9 | 1.04 ± 0.06 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.1.8 hook-env |
19.1 ± 0.3 | 18.4 | 20.5 | 1.00 |
mise hook-env |
19.2 ± 0.3 | 18.5 | 21.3 | 1.01 ± 0.02 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.1.8 ls |
16.9 ± 0.5 | 16.2 | 19.0 | 1.00 |
mise ls |
17.4 ± 0.7 | 16.6 | 19.9 | 1.03 ± 0.05 |
xtasks/test/perf
| Command | mise-2026.1.8 | mise | Variance |
|---|---|---|---|
| install (cached) | 109ms | 109ms | +0% |
| ls (cached) | 65ms | 66ms | -1% |
| bin-paths (cached) | 69ms | 69ms | +0% |
| task-ls (cached) | 281ms | 287ms | -2% |
4095e71 to
d764385
Compare
Previously, plugins defined in [plugins] were only auto-installed when a tool using that plugin was being installed. Plugins without a corresponding tool in [tools] (like env plugins) never got auto-installed. This adds plugin auto-installation to Toolset::install_all_versions() so it works across all tool install paths (mise install, mise upgrade, mise use, etc.). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
d764385 to
feb19c1
Compare
…_runtimes The previous implementation placed ensure_config_plugins_installed inside install_all_versions, but install_missing_runtimes has an early return when no tools need installing. This meant plugins from [plugins] config section were never installed when running `mise install` with only plugins defined. Also fixes the e2e test to verify plugins are actually installed (cloned) by checking for URLs in --refs output, rather than just checking if the plugin name appears in the list (which happens via config registration). Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
Bugbot Autofix is OFF. To automatically fix reported issues with Cloud Agents, enable Autofix in the Cursor dashboard.
| } else { | ||
| (PluginType::Asdf, key) | ||
| } | ||
| } |
There was a problem hiding this comment.
Empty plugin name causes panic in debug builds
Medium Severity
The parse_plugin_key function can return an empty string for the plugin name when the config key is empty ("") or contains only a prefix like "vfox:". This empty name is then passed to plugin_type.plugin(), which calls AsdfPlugin::new or VfoxPlugin::new - both have #[requires(!name.is_empty())] contracts that panic in debug builds. In release builds, the plugin path becomes the plugins directory itself (dirs::PLUGINS), causing silent incorrect behavior.
Additional Locations (1)
Adds validation to skip empty plugin names that could result from malformed config keys like "" or "vfox:". This prevents panics in debug builds from the #[requires(!name.is_empty())] contract in AsdfPlugin::new and VfoxPlugin::new. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
### 🚀 Features - **(doctor)** add backend mismatch warnings by @jdx in [#7847](#7847) - **(http)** add rename_exe support for archive extraction by @jdx in [#7874](#7874) - **(http)** send x-mise-ci header for CI environment tracking by @jdx in [#7875](#7875) - **(install)** auto-install plugins from [plugins] config section by @jdx in [#7856](#7856) - **(registry)** add vercel by @mikecurtis in [#7844](#7844) - **(task)** support glob patterns in task_config.includes by @jdx in [#7870](#7870) - **(task)** add task templates for reusable task definitions by @jdx in [#7873](#7873) ### 🐛 Bug Fixes - **(backend)** change registry mismatch log from info to debug by @jdx in [#7858](#7858) - **(ci)** use squash merge for auto-merge-release workflow by @jdx in [7e5e71e](7e5e71e) - **(ci)** remove --auto flag to merge immediately when CI passes by @jdx in [23ed2ed](23ed2ed) - **(github)** select platform-matching provenance file for SLSA verification by @jdx in [#7853](#7853) - **(go)** filter out version "1" from available versions by @jdx in [#7871](#7871) - **(install)** skip CurDir components when detecting archive structure by @jdx in [#7868](#7868) - **(pipx)** ensure Python minor version symlink exists for postinstall hooks by @jdx in [#7869](#7869) - **(registry)** prevent duplicate -stable suffix in Flutter download URLs by @jdx in [#7872](#7872) - **(task)** pass env to usage parser for env-backed arguments by @jdx in [#7848](#7848) - **(task)** propagate MISE_ENV to child tasks when using -E flag by @jdx in [06ee776](06ee776) - **(vfox-dotnet)** use os.execute() to fix Windows installation by @prodrigues1912 in [#7843](#7843) ### 📚 Documentation - update cache-behavior with env_cache information by @jdx in [#7849](#7849) ###◀️ Revert - remove task inheritance from parent configs in monorepos by @jdx in [#7851](#7851) - Revert "fix(ci): remove --auto flag to merge immediately when CI passes" by @jdx in [0606187](0606187) ### 📦 Registry - add mago ([aqua:carthage-software/mago](https://github.com/carthage-software/mago)) by @scop in [#7845](#7845) ### Chore - **(ci)** auto-merge release branch into main daily at 4am CST by @jdx in [#7852](#7852) ### New Contributors - @mikecurtis made their first contribution in [#7844](#7844) - @prodrigues1912 made their first contribution in [#7843](#7843)
Summary
[plugins]config section during tool installation[tools](like env plugins) never got auto-installedChanges
Added
ensure_config_plugins_installed()toToolset::install_all_versions()which:config.repo_urls(the[plugins]section)This works across all tool install paths:
mise install,mise upgrade,mise use, and internal auto-install.Test plan
mise run test:unit)e2e/plugins/test_plugin_install,e2e/plugins/test_tiny)e2e/cli/test_install_before)🤖 Generated with Claude Code
Note
Ensures plugins listed in
mise.toml[plugins]are installed even without corresponding tools, enabling env-only plugins to be set up during installs.Toolset::ensure_config_plugins_installedto install all plugins fromconfig.repo_urlsbefore resolving tools; integrates intoinstall_missing_runtimesandinstall_all_versionsPluginType(asdf,vfox,vfox-backend) with sane fallbacks viaparse_plugin_keydry_runand skips empty/malformed plugin namese2e/plugins/test_plugins_section_auto_installverifying auto-install with plugin-only and plugin+tool scenariosWritten by Cursor Bugbot for commit 4d1a3ea. This will update automatically on new commits. Configure here.