Skip to content

fix(plugins): install and compare git:: subdirectory sources from [plugins] - #14150

Merged
jdx merged 3 commits into
jdx:mainfrom
onokonem:fix/plugins-git-subdir-sources
Oct 8, 2026
Merged

jdx merged 3 commits into
jdx:mainfrom
onokonem:fix/plugins-git-subdir-sources

Conversation

@onokonem

@onokonem onokonem commented Oct 8, 2026 •

Copy link
Copy Markdown

Fixes the first two points of #14149.

A [plugins] entry in the git::<url>//<subdir>?ref=<ref> form installs, but:

  • On a data dir that never held a plugin, the install clones into plugin-repos/ and fails linking plugins/<name> because nothing created plugins/ (failed to ln -sf … No such file or directory). install_git_plugin_source now creates the parent before make_symlink.
  • configured_plugin_url expanded the entry as a registry shorthand (https://github.com/:ssh://….git). The drift check then warned on every mise install, and mise plugins install --force <name> reinstalled from the mangled URL, failed and left no plugin. plugin_entry_to_url now keeps a source that RemoteSource::parse_git recognises as is.

Tests:

  • test_plugin_entry_to_url_keeps_ref_outside_shorthand_expansion gets git:: ssh/https cases (with and without ?ref=).
  • test_install_git_plugin_source_subdir_creates_the_plugins_dir installs a local subdirectory plugin into a plugins/ that does not exist yet.

Both fail on main without the change (left: "https://github.com/:ssh://…"; failed to ln -sf … No such file or directory) and pass with it. cargo fmt --check and cargo clippy --lib --tests -- -D warnings are clean.

The third point of the issue (auto-install of mise run / mise exec resolving tools before [plugins] is installed) is not addressed here.


Drafted with AI assistance (Claude Code); I reviewed the change and the tests before opening it.

Summary by CodeRabbit

  • Bug Fixes
    • Git plugin sources using SSH or HTTPS URLs are now preserved, including sources that specify a subdirectory.
    • Installing a plugin from a checked-out subdirectory now works when the plugins directory does not yet exist.

…ugins]

A `[plugins]` entry in the `git::<url>//<subdir>?ref=<ref>` form installs,
but two paths around it break:

- On a data dir that has never held a plugin, the install clones into
  plugin-repos/ and then fails linking plugins/<name>: nothing created
  plugins/ yet ("failed to ln -sf ... No such file or directory").
  Create the parent before the symlink.
- `configured_plugin_url` expands the entry as a registry shorthand, so
  `git::ssh://host/org/repo.git//plugin?ref=v1` becomes
  `https://github.com/:ssh://host/org/repo.git//plugin?ref=v1.git`. The drift
  check then warns on every `mise install` that the plugin is installed from
  a different URL, and `mise plugins install --force <name>` reinstalls from
  the mangled URL, fails and leaves no plugin. Keep a `git::` source as is.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@coderabbitai

coderabbitai Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack β†’

Warning

Review limit reached

You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository.

Next included review available in 17 minutes.

Check out review usage here.

View limit details

Limit details: You’ve used all 10 included reviews currently available.

Learn how review limits work.

Review configuration:

βš™οΈ Run configuration
  • Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 56c375c0-1d89-4a2b-93a7-5b49d1383f5a
πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between e57c274 and bc9b666.

πŸ“’ Files selected for processing (2)
  • src/config/mod.rs
  • src/plugins/mod.rs

No actionable comments were generated in the recent review. πŸŽ‰

ℹ️ Recent review info
βš™οΈ Run configuration
  • Configuration used: Repository YAML (base), Central YAML (inherited), Organization UI (inherited)
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 1c5227cf-bfcf-4dba-b19a-6700538f48b6
πŸ“₯ Commits

Reviewing files that changed from the base of the PR and between 4a98b02 and e57c274.

πŸ“’ Files selected for processing (2)
  • src/config/mod.rs
  • src/plugins/mod.rs

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.


πŸ“ Walkthrough

Walkthrough

The change preserves recognized git:: plugin sources during URL expansion and creates a missing parent directory before installing a checked-out Git subdirectory.

Changes

Git Plugin Sources

Layer / File(s) Summary
Preserve Git source URLs
src/config/mod.rs
Recognized git:: sources are returned unchanged before shorthand URL expansion. Tests cover SSH and HTTPS sources, with and without a subdirectory ref.
Create parent directory for subdirectory installs
src/plugins/mod.rs
The installer creates the plugin path’s parent directory before symlinking a checked-out subdirectory. A test covers installation when the target plugins/ directory does not exist.

Priority: ⬇️ Low

Estimated code review effort: 2 (Simple) | ~10 minutes

Change: Bug fix

Suggested reviewers: jdx

Merge Risk: βšͺ Minimal Β· up to e57c2

Git subdirectory sources now reach the existing drift and install paths, and installs can create a missing plugins directory. No material merge risk is established.

πŸš₯ Pre-merge checks | βœ… 5
βœ… Passed checks (5 passed)
Check name Status Explanation
Description Check βœ… Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check βœ… Passed The title clearly identifies the plugin fixes for installing and comparing git:: subdirectory sources from the [plugins] configuration.
Docstring Coverage βœ… Passed Docstring coverage is 83.33% which is sufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 6 functions across 2 files.
Linked Issues check βœ… Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check βœ… Passed Check skipped because no linked issues were found for this pull request.
  • Autopilot Β· Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❀️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor

RetriggerConfidence Score: 5/5

[Medium risk] Adds subdirectory support to plugin installation from git sources.

The PR appears safe to merge; no actionable issues were found.

What we checked:

  • Git sources reach the right repository: Both paths parse the preserved entry before using it. The drift check compares the extracted URL, and installation clones that URL with the extracted ref and subdirectory.

Summary

Keeps recognized git:: plugin entries unchanged instead of expanding them as registry shorthand.

  • Adds SSH and HTTPS cases to the URL conversion test.
  • Adds a local repository test for installing a subdirectory plugin when plugins/ does not exist.
  • The directory-creation fix described in the PR is already present in the target commit; this diff adds its regression test.

Reviews (2) Β· Last reviewed commit: "fix(plugins): drop the plugins dir creat..." Β· Reviewed by Greptile

jdx and others added 2 commits October 8, 2026 13:01
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Entire-Checkpoint: 01M4DSZAK4D3YHD7D5H567SAHY
@jdx
jdx enabled auto-merge (squash) October 8, 2026 13:47
@jdx
jdx merged commit bdd2505 into jdx:main Oct 8, 2026
59 checks passed
mise-en-dev added a commit that referenced this pull request Oct 8, 2026
<!-- entire-trail-link-start -->
https://entire.io/gh/jdx/mise/trails/493
<!-- entire-trail-link-end -->

### πŸš€ Features

- **(bootstrap)** add an os filter to files and directories by @jdx in
[#14058](#14058)
- **(bootstrap)** add auto mode for fish shell activation by @jdx in
[#14172](#14172)
- **(config)** merge [bootstrap] from config includes by @jdx in
[#14176](#14176)
- **(doctor)** show dotfiles repo path and origin by @jdx in
[#14173](#14173)
- **(dotfiles)** give each machine its own tracked version with a
machine variant by @jdx in
[#14062](#14062)
- **(dotfiles)** infer merge sources and keep app state when switching
from symlink by @jdx in [#14076](#14076)
- **(dotfiles)** add merge = "missing" to fill in defaults the app may
change by @jdx in [#14081](#14081)
- **(dotfiles)** add track-local for history that never leaves the
machine by @jdx in [#14082](#14082)
- **(dotfiles)** refuse to publish saved versions that look like secrets
by @jdx in [#14171](#14171)
- **(installs)** move installs that cannot be reinstalled into the
identity layout during migrate by @jdx in
[#14079](#14079)
- **(java)** **breaking** default java versions to Temurin builds by
@jdx in [#14146](#14146)
- **(mcp)** implement install_tool and require a trusted project for
run_task by @jdx in [#14111](#14111)
- **(packslip)** add a workflow option to pin the signing workflow by
@jdx in [#14075](#14075)
- **(packslip)** accept a list of signing workflows by @jdx in
[#14093](#14093)

### πŸ› Bug Fixes

- **(backend)** respect disable_backends in ls-remote by @jdx in
[#14130](#14130)
- **(bootstrap)** keep applying other package managers after one fails
by @jdx in [#14138](#14138)
- **(bootstrap)** skip the firewall section where it is unsupported by
@jdx in [#14137](#14137)
- **(bootstrap)** keep shell activation when a dotfile is tracked by
@jdx in [#14135](#14135)
- **(bootstrap)** warn on legacy command spellings and mise direnv by
@jdx in [#14113](#14113)
- **(bootstrap)** show hooks that use exec() in dry runs by @jdx in
[#14136](#14136)
- **(bootstrap)** support absent and unapply for systemd units by @jdx
in [#14139](#14139)
- **(brew)** infer formula version from the GitHub release tag path by
@JamBalaya56562 in [#14165](#14165)
- **(brew)** detach a DMG left attached by an interrupted install by
@jdx in [#14177](#14177)
- **(cargo)** do not resolve dependencies to mise shims by @jdx in
[#14070](#14070)
- **(cli)** accept yes/no booleans, prefix: in latest, and warn log
level by @jdx in [#14125](#14125)
- **(cli)** print the invoked command name in help by @jdx in
[#14123](#14123)
- **(cli)** replace unimplemented!() in --monorepo flags with an error
by @jdx in [#14116](#14116)
- **(config)** report an invalid tool version in config ls instead of
panicking by @JamBalaya56562 in
[#14094](#14094)
- **(config)** verify .monorepo markers in paranoid mode by @jdx in
[#14105](#14105)
- **(config)** apply config environment files in directory order by @jdx
in [#14148](#14148)
- **(config)** ignore project bootstrap and dotfiles config in safe mode
by @jdx in [#14110](#14110)
- **(daemons)** quote deferred daemon commands for cmd.exe on Windows by
@JamBalaya56562 in [#14055](#14055)
- **(daemons)** run argv and Windows readiness probes in the tool
environment by @JamBalaya56562 in
[#14080](#14080)
- **(doctor)** recognize a `mise` entry in the dedicated shims dir by
@jdx in [#14069](#14069)
- **(dotfiles)** say when incoming history changes no files on this
machine by @jdx in [#14066](#14066)
- **(dotfiles)** let MISE_YES confirm rollback, undo, and recover by
@jdx in [#14067](#14067)
- **(dotfiles)** save files replaced when adopting a setup, and add
--take-remote-all by @jdx in
[#14065](#14065)
- **(dotfiles)** don't require --yes without a TTY for recoverable
confirmations by @jdx in
[#14071](#14071)
- **(dotfiles)** stop prompting for recoverable operations by @jdx in
[#14077](#14077)
- **(edit)** do not overwrite an existing config without a terminal by
@jdx in [#14124](#14124)
- **(env)** honor redact = false exclusions in mise env --redacted by
@jdx in [#14109](#14109)
- **(env)** skip watch_files runs in safe mode and with --no-hooks by
@jdx in [#14108](#14108)
- **(exec)** install exact versions when the version list times out by
@jdx in [#14164](#14164)
- **(generate)** update the GitHub Actions and devcontainer templates by
@jdx in [#14145](#14145)
- **(generate)** skip hidden and global tasks in task-stubs by @jdx in
[#14127](#14127)
- **(github)** check asset size without a checksum by @jdx in
[#14128](#14128)
- **(github)** percent-encode the tag in gitlab release lookups by
@thespags in [#14102](#14102)
- **(java)** key the version cache by vendor and keep release_type by
@jdx in [#14131](#14131)
- **(migrate)** keep an unwritable stderr from aborting mise during a
migration by @JamBalaya56562 in
[#14158](#14158)
- **(node)** verify GPG signatures for every node version by @jdx in
[#14132](#14132)
- **(npm)** stop npm view from re-entering mise through a foreign shim
by @jdx in [#14084](#14084)
- **(packslip)** let a user signer option replace a registry workflow
default by @jdx in [#14091](#14091)
- **(plugins)** install git:: plugins from a subdirectory by @jdx in
[#14140](#14140)
- **(plugins)** install packslip entries in [plugins] as vfox plugins by
@jdx in [#14141](#14141)
- **(plugins)** stop mise plugins uninstall --purge from panicking by
@jdx in [#14117](#14117)
- **(plugins)** install and compare git:: subdirectory sources from
[plugins] by @onokonem in
[#14150](#14150)
- **(prune)** skip a tracked config whose tool version no longer parses
by @JamBalaya56562 in [#14103](#14103)
- **(ruby)** expand {os} and {arch} in precompiled URLs correctly by
@jdx in [#14133](#14133)
- **(sandbox)** clear inherited variables for --deny-env on Windows by
@jdx in [#14107](#14107)
- **(sandbox)** reject allow_net on macOS instead of writing invalid
rules by @jdx in [#14106](#14106)
- **(settings)** reject settings set in places mise ignores them by @jdx
in [#14126](#14126)
- **(shim)** skip version lookups for lazy tools that are not installed
by @jdx in [#14063](#14063)
- **(shim)** stop system fallback cycles through wrappers by @jdx in
[#14088](#14088)
- **(shim)** match Windows lazy shim names regardless of ASCII case by
@jdx in [#14090](#14090)
- **(spm)** use a custom api_url for cloning and skip lockfile URLs by
@jdx in [#14129](#14129)
- **(task)** report unmatched sources, show depends_post, and load
global tasks by @jdx in [#14122](#14122)
- **(task)** resolve mise run ./script relative to the current directory
by @jdx in [#14120](#14120)
- **(task)** send mbx-cache headers to the remote task cache by @jdx in
[#14147](#14147)
- **(task)** strip script extensions only from file task names by @jdx
in [#14159](#14159)
- **(task)** skip fresh raw and interactive cached tasks when their
cache key is unchanged by @jdx in
[#14121](#14121)
- **(task)** keep secret values out of remote cache keys by @jdx in
[#14104](#14104)
- **(use)** create config.toml instead of writing global tools to
config.<env>.toml by @jdx in
[#14179](#14179)
- **(vfox)** do not fail every command for an env plugin with no source
by @jdx in [#14119](#14119)
- **(vfox)** resolve embedded plugin files from the manifest dir by @jdx
in [#14167](#14167)
- **(watch)** pass watchexec flags through to watchexec by @jdx in
[#14115](#14115)
- keep temporary files out of the cache directory by @jdx in
[#14134](#14134)
- point error hints at current commands by @jdx in
[#14142](#14142)
- replace panics on bad input with errors by @jdx in
[#14118](#14118)
- require experimental for remote task sources, OpenTelemetry and spinel
by @jdx in [#14114](#14114)

### πŸ“š Documentation

- **(agents)** treat 12 months as the default deprecation window by @jdx
in [#14100](#14100)
- **(cli)** hide mise bootstrap dotfiles and mise tasks run from help by
@jdx in [#14101](#14101)
- restructure and rewrite the documentation site by @jdx in
[#14097](#14097)
- rewrite CLI help and settings descriptions by @jdx in
[#14098](#14098)
- update pages for behavior changed by recent fixes by @jdx in
[#14163](#14163)

### πŸ§ͺ Testing

- **(backend)** give test_ubi a longer version-fetch timeout by @jdx in
[#14162](#14162)
- **(config)** don't rely on teleport plugins being absent in not-found
test by @jdx in [#14059](#14059)
- **(windows)** isolate install fixtures and wait for executable
teardown by @jdx in [#14089](#14089)

### πŸ“¦οΈ Dependency Updates

- update rust crate demand to v2.4.0 by @renovate[bot] in
[#14054](#14054)
- update aube to v2.7.0 by @renovate[bot] in
[#14074](#14074)

### πŸ“¦ Registry

- pin packslip tools to the workflow that signs their releases by @jdx
in [#14092](#14092)
- rename mprocs to dekit and keep mprocs as an alias by @jdx in
[#14169](#14169)

### Chore

- **(docs)** keep moved pages reachable and fail on dead anchors by @jdx
in [#14096](#14096)
- **(settings)** deprecate settings that have no effect by @jdx in
[#14112](#14112)
- run e2e tests from mise run test and fix the registry test example by
@jdx in [#14143](#14143)

### Ci

- install mold from its GitHub release instead of apt by @jdx in
[#14085](#14085)
- stop installing direnv for the e2e tests by @jdx in
[#14170](#14170)

### Security

- **(http)** redact URL credentials in debug logs by @jdx in
[#14155](#14155)
- **(npm)** redact credentials in Git-source diagnostics by @jdx in
[#14057](#14057)
- **(npm)** redact normalized SSH diagnostics by @jdx in
[#14064](#14064)
- **(worktrunk)** pin the registry default to the release workflow on
tags by @max-sixty in [#14073](#14073)

### New Contributors

- @onokonem made their first contribution in
[#14150](#14150)
- @max-sixty made their first contribution in
[#14073](#14073)

## πŸ“¦ Aqua Registry Updates

### Updated Packages (2)

- [`charmbracelet/skate`](https://github.com/charmbracelet/skate)
- [`pvolok/dekit`](https://github.com/pvolok/dekit)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants