Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
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
9 changes: 7 additions & 2 deletions src-tauri/release-runtime.test.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -228,8 +228,13 @@ test("native updater cleanup stops the sidecar before Windows exits", async () =
);
assert.match(
launcher,
/installer_args\(\[[\s\S]*OsString::from\("\/L\*V"\)/,
"updater-driven MSI installs must retain a verbose per-run diagnostic log",
/fn msi_verbose_log_installer_args\([\s\S]*quoted_log_path\.push\(log_path\.as_os_str\(\)\)[\s\S]*OsString::from\("\/L\*V"\)/,
"the extracted updater helper must retain a verbose MSI log argument while preserving the native path",
);
assert.match(
launcher,
/updater_builder\.installer_args\(msi_verbose_log_installer_args\(&log_path\)\)/,
"updater-driven MSI installs must use the verbose per-run diagnostic log helper",
);
});

Expand Down
78 changes: 74 additions & 4 deletions src-tauri/src/tauri_setup.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,78 @@
use super::*;

/// Builds the verbose MSI log arguments as command-line segments.
///
/// `tauri-plugin-updater` joins `installer_args` into the raw parameter
/// string supplied to `ShellExecuteW`, rather than passing them through a
/// process argument API. Keep exactly one pair of quotes around the log path
/// so msiexec receives a single `/L*V` path even when the app log directory
/// contains spaces.
#[cfg(any(target_os = "windows", test))]
fn msi_verbose_log_installer_args(log_path: &std::path::Path) -> [std::ffi::OsString; 2] {
let mut quoted_log_path = std::ffi::OsString::from("\"");
quoted_log_path.push(log_path.as_os_str());
quoted_log_path.push("\"");

[std::ffi::OsString::from("/L*V"), quoted_log_path]
}

#[cfg(test)]
mod updater_argument_tests {
use super::msi_verbose_log_installer_args;
use std::{ffi::OsStr, path::Path};

const UPDATER_JOIN_CONTRACT_VERSION: &str = "2.10.1";

fn locked_updater_package_entry() -> &'static str {
let mut entries = include_str!("../Cargo.lock")
.split("[[package]]")
.filter(|entry| entry.contains("name = \"tauri-plugin-updater\""));
let entry = entries
.next()
.expect("Cargo.lock must contain tauri-plugin-updater");
assert!(
entries.next().is_none(),
"the updater join-contract test must be revisited when multiple updater versions are locked"
);
entry
}

#[test]
fn msi_verbose_log_path_is_quoted_once_in_shell_execute_parameters() {
assert!(
locked_updater_package_entry().contains(&format!(
"version = \"{UPDATER_JOIN_CONTRACT_VERSION}\""
)),
"tauri-plugin-updater changed; revalidate its MSI ShellExecuteW argument construction before updating this contract"
);

let log_path = Path::new(
r"C:\Users\A Coven\AppData\Local\Coven Cave\logs\msi-upgrade-from-0.1.6-123.log",
);

let installer_args = msi_verbose_log_installer_args(log_path);
assert_eq!(installer_args[0], OsStr::new("/L*V"));
assert_eq!(
installer_args[1],
OsStr::new(
r#""C:\Users\A Coven\AppData\Local\Coven Cave\logs\msi-upgrade-from-0.1.6-123.log""#
)
);

// This mirrors tauri-plugin-updater 2.10.1's `ShellExecuteW`
// parameter construction. No quotes would split this spaced path, and
// a second pair would end quote mode and split it as well.
let parameters = installer_args.join(OsStr::new(" "));
assert_eq!(
parameters,
OsStr::new(
r#"/L*V "C:\Users\A Coven\AppData\Local\Coven Cave\logs\msi-upgrade-from-0.1.6-123.log""#
)
);
assert_eq!(parameters.to_string_lossy().matches('"').count(), 2);
}
}

/// Show or hide the macOS traffic lights (close/minimize/zoom) on the
/// invoking window. The main window's title bar is an Overlay (see the main
/// window builder), so the buttons float over web content — when the app's
Expand Down Expand Up @@ -229,10 +302,7 @@ pub fn run() {
std::process::id()
));
log::info!("[cave] updater MSI log -> {}", log_path.display());
updater_builder.installer_args([
std::ffi::OsString::from("/L*V"),
std::ffi::OsString::from(format!("\"{}\"", log_path.display())),
])
updater_builder.installer_args(msi_verbose_log_installer_args(&log_path))
};
app.handle().plugin(updater_builder.build())?;
app.handle().plugin(tauri_plugin_process::init())?;
Expand Down
Loading