feat(http): add rename_exe support for archive extraction#7874
Conversation
Adds the `rename_exe` option to the HTTP backend, matching the functionality available in the GitHub backend. This option renames the first executable found in an extracted archive to the specified name. Use cases: - Archives with platform-specific binary names (e.g., just "linux") - Installing kubectl plugins that need specific naming conventions - Tools where the binary name inside the archive differs from desired Example: ```toml [tools."http:openunison-cli"] version = "1.0.0" url = "https://example.com/openunison-cli-v{{version}}-linux.zip" rename_exe = "kubectl-openunison-cli" ``` Closes #7689 Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
This PR adds rename_exe support to the HTTP backend, allowing users to rename executables extracted from archives. This brings feature parity with the GitHub backend and addresses use cases where archive contents have platform-specific or non-standard binary names.
Changes:
- Made
rename_executable_in_dirfunction public instatic_helpers.rs - Added
rename_exehandling in HTTP backend's archive extraction flow - Updated documentation with examples and usage guidance
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/backend/static_helpers.rs | Changed function visibility from private to public |
| src/backend/http.rs | Added rename_exe logic after archive extraction and registered the option key |
| docs/dev-tools/backends/http.md | Added documentation section explaining rename_exe usage with examples |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| .tool_name | ||
| .rsplit('/') | ||
| .next() | ||
| .unwrap_or(&self.ba.tool_name); |
There was a problem hiding this comment.
The rsplit('/') logic extracts the last segment after a forward slash, but the fallback to self.ba.tool_name when next() returns None is unreachable. The rsplit iterator always returns at least one element (the entire string if no delimiter is found), so next() will never return None. Consider removing the unwrap_or or adding a comment explaining why it's kept for defensive programming.
| .unwrap_or(&self.ba.tool_name); | |
| // `rsplit` on a non-empty string always yields at least one element | |
| .expect("rsplit('/') on tool_name should always yield at least one segment"); |
Tests that rename_exe correctly renames executables inside extracted archives, both with and without bin_path. Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Include rename_exe in cache key since it modifies extracted content
- Add template expansion for bin_path in rename_exe handling
- Add clarifying comment for rsplit('/') behavior
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.
- Include bin_path in cache key when rename_exe is used, since the rename location depends on bin_path and affects cached content - Change unwrap_or_default() to unwrap() for rsplit - it's guaranteed to return at least one element (the full string if no delimiter) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Hyperfine Performance
|
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.1.8 x -- echo |
19.4 ± 0.7 | 18.7 | 28.6 | 1.00 |
mise x -- echo |
20.0 ± 0.6 | 19.0 | 23.5 | 1.03 ± 0.05 |
mise env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.1.8 env |
19.3 ± 0.8 | 18.1 | 25.2 | 1.00 |
mise env |
19.3 ± 0.6 | 18.5 | 23.4 | 1.00 ± 0.05 |
mise hook-env
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.1.8 hook-env |
19.1 ± 0.3 | 18.5 | 20.6 | 1.00 |
mise hook-env |
19.6 ± 0.4 | 18.8 | 21.3 | 1.03 ± 0.03 |
mise ls
| Command | Mean [ms] | Min [ms] | Max [ms] | Relative |
|---|---|---|---|---|
mise-2026.1.8 ls |
17.5 ± 0.4 | 16.5 | 18.9 | 1.00 |
mise ls |
18.4 ± 0.9 | 16.6 | 22.9 | 1.05 ± 0.06 |
xtasks/test/perf
| Command | mise-2026.1.8 | mise | Variance |
|---|---|---|---|
| install (cached) | 110ms | 112ms | -1% |
| ls (cached) | 67ms | 67ms | +0% |
| bin-paths (cached) | 70ms | 75ms | -6% |
| task-ls (cached) | 286ms | -87% |
### 🚀 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
Adds the
rename_exeoption to the HTTP backend, matching the functionality available in the GitHub backend. This option renames the first executable found in an extracted archive to the specified name.Use Cases
Example
Changes
rename_executable_in_dirpublic instatic_helpers.rs(already used by GitHub backend)rename_exehandling in HTTP backend'sextract_archivemethodrename_exetoinstall_time_option_keysTest plan
Closes #7689
🤖 Generated with Claude Code
Note
Adds archive-time binary renaming to the HTTP backend and documents it.
rename_exeduring archive extraction; searchesbin_path(templated) when set and renames the first executable to the requested namerename_exeand, when present,bin_pathto avoid collisionsToolVersionwhere needed;extract_*signatures adjustedrename_executable_in_dirfromstatic_helpersfor reuserename_exeto HTTPinstall_time_option_keysrename_exesection with examples indocs/dev-tools/backends/http.mde2e/backend/test_http_rename_execovering rename behaviorWritten by Cursor Bugbot for commit de7477c. This will update automatically on new commits. Configure here.