Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 47 additions & 2 deletions src/cli/self_update.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,13 @@ impl SelfUpdate {
let status = self.do_update()?;

if status.updated() {
let version = style(status.version()).bright().yellow();
miseprintln!("Updated mise to {version}");
let version = status.version().to_string();
let styled_version = style(&version).bright().yellow();
miseprintln!("Updated mise to {styled_version}");
#[cfg(windows)]
if let Err(e) = Self::update_mise_shim(&version) {
warn!("Failed to update mise-shim.exe: {e}");
}

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

To accommodate the suggested change of making update_mise_shim an async function, this call needs to be awaited.

Suggested change
if let Err(e) = Self::update_mise_shim(&version) {
warn!("Failed to update mise-shim.exe: {e}");
}
if let Err(e) = Self::update_mise_shim(&version).await {
warn!warn("Failed to update mise-shim.exe: {e}");
}

} else {
miseprintln!("mise is already up to date");
}
Expand Down Expand Up @@ -167,6 +172,46 @@ impl SelfUpdate {
Ok(status)
}

#[cfg(windows)]
fn update_mise_shim(version: &str) -> Result<()> {
use crate::http::HTTP;
use std::io::Read;

let url = format!(
"https://github.com/jdx/mise/releases/download/{version}/mise-{version}-{}-{}.zip",
*OS, *ARCH,
);
Comment thread
cursor[bot] marked this conversation as resolved.
Resolved
debug!("Downloading mise-shim.exe from {url}");

let temp_dir = tempfile::tempdir()?;
let zip_path = temp_dir.path().join("mise.zip");
tokio::task::block_in_place(|| {
tokio::runtime::Handle::current().block_on(HTTP.download_file(&url, &zip_path, None))
})?;

Copilot AI Feb 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

tokio::task::block_in_place and tokio::runtime::Handle::current() will panic if this code is executed outside a Tokio runtime (or inside a current-thread runtime where block_in_place is unsupported). Consider making update_mise_shim async and await the download from the existing async context, or use a runtime-agnostic approach (e.g., if a Tokio handle isn't available, create a dedicated runtime to block_on, or provide a synchronous download path).

Suggested change
tokio::task::block_in_place(|| {
tokio::runtime::Handle::current().block_on(HTTP.download_file(&url, &zip_path, None))
})?;
if let Ok(handle) = tokio::runtime::Handle::try_current() {
handle.block_on(HTTP.download_file(&url, &zip_path, None))?;
} else {
let rt = tokio::runtime::Runtime::new()?;
rt.block_on(HTTP.download_file(&url, &zip_path, None))?;
}

Copilot uses AI. Check for mistakes.

let file = fs::File::open(&zip_path)?;
let mut archive = zip::ZipArchive::new(file)?;

let mut shim_entry = match archive.by_name("mise/bin/mise-shim.exe") {
Ok(entry) => entry,
Err(_) => {
warn!("mise-shim.exe not found in release archive, skipping");
return Ok(());
}
};

let dest = env::MISE_BIN
.parent()
.expect("MISE_BIN should have a parent directory")
.join("mise-shim.exe");
let mut buf = Vec::new();
shim_entry.read_to_end(&mut buf)?;
xx::file::write(&dest, &buf)?;

Copilot AI Feb 9, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Writing the shim by buffering the entire file and then writing directly to the final destination increases the chance of leaving a partially-written mise-shim.exe if the process is interrupted mid-write. Prefer an atomic update pattern (write to a temporary file in the same directory, then rename/replace), and ideally stream from the ZIP entry into the temp file to avoid the extra buffering.

Copilot uses AI. Check for mistakes.

debug!("Updated mise-shim.exe at {}", dest.display());
Ok(())
}
Comment on lines +175 to +222

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

critical

This new function has a critical bug and a potential improvement:

  1. Incorrect URL (Critical): The URL for downloading the release archive is constructed incorrectly. Release tags and asset names on GitHub for mise are prefixed with a v (e.g., v2024.5.1), but the version variable here does not include it. This will cause downloads to fail with a 404 error.
  2. Blocking in async context (Improvement): The function is synchronous and uses tokio::task::block_in_place. Since it's called from an async context, it's better to make it async and await the download directly.

The suggestion below addresses both points. Note that you will also need to await the call to this function in run(), for which I've left a separate comment.

    #[cfg(windows)]
    async fn update_mise_shim(version: &str) -> Result<()> {
        use crate::http::HTTP;
        use std::io::Read;

        let url = format!(
            "https://github.com/jdx/mise/releases/download/v{version}/mise-v{version}-{}-{}.zip",
            *OS, *ARCH,
        );
        debug!("Downloading mise-shim.exe from {url}");

        let temp_dir = tempfile::tempdir()?;
        let zip_path = temp_dir.path().join("mise.zip");
        HTTP.download_file(&url, &zip_path, None).await?;

        let file = fs::File::open(&zip_path)?;
        let mut archive = zip::ZipArchive::new(file)?;

        let mut shim_entry = match archive.by_name("mise/bin/mise-shim.exe") {
            Ok(entry) => entry,
            Err(_) => {
                warn!("mise-shim.exe not found in release archive, skipping");
                return Ok(());
            }
        };

        let dest = env::MISE_BIN
            .parent()
            .expect("MISE_BIN should have a parent directory")
            .join("mise-shim.exe");
        let mut buf = Vec::new();
        shim_entry.read_to_end(&mut buf)?;
        xx::file::write(&dest, &buf)?;

        debug!("Updated mise-shim.exe at {}", dest.display());
        Ok(())
    }

Comment thread
cursor[bot] marked this conversation as resolved.
Resolved

pub fn is_available() -> bool {
if let Some(b) = *env::MISE_SELF_UPDATE_AVAILABLE {
return b;
Expand Down
Loading