fix: allow installing bun and others when downloads folder is on a different mount#9032
fix: allow installing bun and others when downloads folder is on a different mount#9032
Conversation
There was a problem hiding this comment.
Code Review
This pull request introduces a move_file utility to handle file moves across different filesystems, which previously caused failures in several plugins including Bun, Deno, Erlang, Java, and Ruby. It includes a new regression test and updates the core plugins to use this cross-device-safe method. Feedback indicates that the current move_file implementation fails when applied to directories—a common use case in the updated plugins—and suggests using the more idiomatic std::io::ErrorKind::CrossesDevices for cross-platform error handling.
Greptile SummaryThis PR fixes a cross-device install failure (e.g. when
Confidence Score: 5/5Safe to merge — all remaining findings are P2 style/robustness suggestions that don't block the fix. The core fix (move_file with EXDEV fallback) is correct and well-tested for both file and directory cases. The symlink concern and test fragilities are P2 and only affect the cross-device fallback path, which is already a non-standard configuration. Prior P1 concerns (aarch64 hardcoding, missing directory branch) have been addressed. src/file.rs — symlink handling in copy_dir_all fallback; e2e/backend/test_bun_cross_device_install — port and server-readiness robustness. Important Files Changed
Flowchart%%{init: {'theme': 'neutral'}}%%
flowchart TD
A["move_file(from, to)"] --> B["fs::rename(from, to)"]
B -->|"Ok(())"| C["✅ Done (atomic)"]
B -->|"Err(CrossesDevices)"| D{"from.is_dir()?"}
B -->|"Err(other)"| E["❌ Return error"]
D -->|"yes"| F["create_dir_all(to)"]
F --> G["copy_dir_all(from, to)\n⚠ follows symlinks, files only"]
G --> H["remove_all(from)"]
H --> I["✅ Done"]
D -->|"no"| J["copy(from, to)"]
J --> K["remove_file(from)"]
K --> I
Reviews (5): Last reviewed commit: "test(repro): use /tmp for bun install pa..." | Re-trigger Greptile |
|
Tip: Greploop — Automatically fix all review issues by running Use the Greptile plugin for Claude Code to query reviews, search comments, and manage custom context directly from your terminal. |
|
Дозволяю✌️
пт, 10 квіт. 2026 р., 22:28 користувач greptile-apps[bot] <
***@***.***> пише:
… ***@***.***[bot]* commented on this pull request.
------------------------------
In e2e/backend/test_bun_cross_device_install
<#9032 (comment)>:
> +python3 - "$FIXTURE_DIR/bun-linux-aarch64.zip" <<'PY'
+import os
+import sys
+import zipfile
+from zipfile import ZipInfo
+
+out_path = sys.argv[1]
+script = b"""#!/usr/bin/env bash
+if [[ ${1:-} == -v || ${1:-} == --version ]]; then
+ echo 1.3.10
+else
+ echo 'bun fixture' "$@"
+fi
+"""
+
+with zipfile.ZipFile(out_path, "w", compression=zipfile.ZIP_DEFLATED) as zf:
+ info = ZipInfo("bun-linux-aarch64/bun")
+ info.create_system = 3
+ info.external_attr = 0o755 << 16
+ zf.writestr(info, script)
+PY
+sha256sum "$FIXTURE_DIR/bun-linux-aarch64.zip" | awk '{print $1 " bun-linux-aarch64.zip"}' > "$FIXTURE_DIR/SHASUMS256.txt"
[image: P1] <#m_3477463513447195304_> *Test fixture is hardcoded to
aarch64*
The zip file and its internal path are both hardcoded to bun-linux-aarch64,
but arch() in bun.rs is resolved at runtime. On x86_64 Linux (the most
common CI runner architecture), bun requests bun-linux-x86_64.zip from
the mock server, which doesn't exist, causing a 404 and a download failure
rather than the cross-device regression this test intends to catch.
The fixture path should be generated dynamically using uname -m (and
mapped to bun's naming convention, e.g. x86_64→x64):
# detect runtime arch the way bun names itcase "$(uname -m)" in
x86_64) BUN_ARCH="x64" ;;
aarch64) BUN_ARCH="aarch64" ;;
*) echo "Unsupported arch"; exit 1 ;;esac
FIXTURE_BASENAME="bun-linux-$BUN_ARCH"
Then replace every bun-linux-aarch64 reference with $FIXTURE_BASENAME.
------------------------------
In src/file.rs
<#9032 (comment)>:
> + if is_cross_device {
+ copy(from, to)?;
+ remove_file(from)?;
+ Ok(())
[image: P1] <#m_3477463513447195304_> *move_file fallback silently fails
for directories*
When fs::rename fails with EXDEV, the fallback calls copy(from, to) which
wraps fs::copy. fs::copy only handles regular files and returns EISDIR /
ERROR_ACCESS_DENIED for directories. This means the erlang, java, and
ruby_windows backends — which iterate over directory entries (including
subdirectories like bin/, lib/, erts-X.X/) or move an entire extracted
directory tree — will fail in the cross-device scenario instead of
succeeding. The fix works correctly for bun/deno (single binary files) but
leaves the directory-move callers broken.
A minimal fix:
if is_cross_device {
if from.is_dir() {
copy_dir_all(from, to)?;
remove_all(from)?;
} else {
copy(from, to)?;
remove_file(from)?;
}
Ok(())}
------------------------------
In src/plugins/core/bun.rs
<#9032 (comment)>:
>
+
[image: P2] <#m_3477463513447195304_> *Extra blank line added*
A spurious blank line was introduced between bun_bin and test_bun.
⬇️ Suggested change
-
-
+ fn test_bun(&self, ctx: &InstallContext, tv: &ToolVersion) -> Result<()> {
Note: If this suggestion doesn't match your team's coding style, reply to
this and let me know. I'll remember it for next time!
—
Reply to this email directly, view it on GitHub
<#9032 (review)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/B3SYZBQSY6ERGI2JASHE3NT4VFDPHAVCNFSM6AAAAACXUKFTICVHI2DSMVQWIX3LMV43YUDVNRWFEZLROVSXG5CSMV3GSZLXHM2DAOJSGAZDQNBXGY>
.
You are receiving this because you are subscribed to this thread.Message
ID: ***@***.***>
|
|
|
|
Sweet, thanks! |
### 🐛 Bug Fixes - **(docs)** upgrade esbuild to 0.28.0 with es2022 build target by @jdx in [#9047](#9047) - **(env)** skip tools=true module hooks in dependency_env by @jdx in [#9011](#9011) - **(lockfile)** resolve SLSA provenance URLs deterministically for all platforms by @cameronbrill in [#8982](#8982) - **(registry)** test of docuum in registry by @jylenhof in [#8996](#8996) - **(release)** publish extracted mise.exe alongside Windows zip by @zeitlinger in [#8997](#8997) - **(schema)** add missing config fields by @risu729 in [#9044](#9044) - **(task)** support sandbox fields in task templates by @risu729 in [#9046](#9046) - **(tasks)** respect env precedence for task config by @risu729 in [#9039](#9039) - prevent implicit enabling of `self_update` when rustls features are enabled by @salim-b in [#9040](#9040) - allow installing bun and others when downloads folder is on a different mount by @bgeron in [#9032](#9032) ### 📚 Documentation - discourage direnv compatibility PRs and remove issue suggestions by @jdx in [ca78346](ca78346) - tighten direnv compatibility language by @jdx in [ab140c8](ab140c8) - add Tera tip for unsupported version files by @risu729 in [#9048](#9048) ### 📦️ Dependency Updates - update ghcr.io/jdx/mise:deb docker digest to 49fa8a4 by @renovate[bot] in [#8999](#8999) - update ghcr.io/jdx/mise:copr docker digest to 61ba7b6 by @renovate[bot] in [#8998](#8998) - update ghcr.io/jdx/mise:copr docker digest to fa351ff by @renovate[bot] in [#9002](#9002) - update ghcr.io/jdx/mise:alpine docker digest to f3bb475 by @renovate[bot] in [#9001](#9001) - update ghcr.io/jdx/mise:rpm docker digest to d45af2d by @renovate[bot] in [#9005](#9005) - update ghcr.io/jdx/mise:deb docker digest to d7463ac by @renovate[bot] in [#9004](#9004) - update jdx/mise-action digest to 5228313 by @renovate[bot] in [#9007](#9007) - update rust docker digest to e8e2bb5 by @renovate[bot] in [#9008](#9008) - update taiki-e/install-action digest to 97a5807 by @renovate[bot] in [#9010](#9010) - update autofix-ci/action action to v1.3.3 by @renovate[bot] in [#9015](#9015) - update ubuntu:24.04 docker digest to 84e77de by @renovate[bot] in [#9012](#9012) - update actions/checkout action to v4.3.1 by @renovate[bot] in [#9014](#9014) - update ubuntu:26.04 docker digest to cc925e5 by @renovate[bot] in [#9013](#9013) - update rust crate tokio to v1.51.1 by @renovate[bot] in [#9018](#9018) - update rust crate zip to v8.5.1 by @renovate[bot] in [#9019](#9019) - update rust crate ctor to 0.9 by @renovate[bot] in [#9024](#9024) - update ubuntu docker tag to resolute-20260404 by @renovate[bot] in [#9020](#9020) - update dependency vitepress-plugin-tabs to ^0.8.0 by @renovate[bot] in [#9023](#9023) - update rust crate indexmap to v2.14.0 by @renovate[bot] in [#9025](#9025) - update rust crate nix to 0.31 by @renovate[bot] in [#9030](#9030) - update taiki-e/install-action digest to 7a4939c by @renovate[bot] in [#9027](#9027) - update dependency esbuild to v0.28.0 by @renovate[bot] in [#9022](#9022) - update rust crate rand to 0.10 by @renovate[bot] in [#9031](#9031) - update rust crate digest to 0.11.0 by @renovate[bot] in [#9028](#9028) - update rust crate confique to 0.4 by @renovate[bot] in [#9026](#9026) - update rust crate rattler to 0.40 by @renovate[bot] in [#9034](#9034) - lock file maintenance by @renovate[bot] in [#8416](#8416) - disable renovate for aws-config/aws-sdk-* crates by @jdx in [#9052](#9052) - update swatinem/rust-cache digest to e18b497 by @renovate[bot] in [#9009](#9009) ### 📦 Registry - remove broken tool tests by @jdx in [#9017](#9017) - update granted aqua backend repo by @risu729 in [#9033](#9033) - fix atlas-community test expected output by @jdx in [#9054](#9054) ### Chore - use deprecated_at! macro for ubi backend deprecation by @jdx in [#9049](#9049) ### Security - **(ci)** run test-tool inside Docker container by @jdx in [#9055](#9055) - **(ci)** avoid exposing MISE_GH_TOKEN to test-tool scripts by @jdx in [#9053](#9053) ### New Contributors - @bgeron made their first contribution in [#9032](#9032) - @salim-b made their first contribution in [#9040](#9040) ## 📦 Aqua Registry Updates #### Updated Packages (2) - [`cloudnative-pg/cloudnative-pg/kubectl-cnpg`](https://github.com/cloudnative-pg/cloudnative-pg/kubectl-cnpg) - [`gleam-lang/gleam`](https://github.com/gleam-lang/gleam)
I encountered this as I develop in a devcontainer, and I wanted to cache downloads in a Docker cache mount. This worked for all dev tools I'm using, except bun.
Includes regression test which I checked. Regression test is only for bun, not for the other fixed core dev tools.
AI-assisted but hand-curated PR. I asked it to review which uses of
renameshould be replaced bymove_file, inspected the result, and agree.