Improve Windows update parity
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s
ci / test (push) Canceled after 0s
ci / fuzz-smoke (push) Canceled after 0s
ci / windows-client (push) Canceled after 0s
ci / package-release (linux-x86_64, ubuntu-latest, , , ) (push) Canceled after 0s
ci / package-release (macos-aarch64, macos-14, , , ) (push) Canceled after 0s
ci / package-release (macos-x86_64, macos-13, , , ) (push) Canceled after 0s
ci / package-release (windows-aarch64, windows-latest, aarch64, windows, aarch64-pc-windows-msvc) (push) Canceled after 0s
ci / package-release (windows-x86_64, windows-latest, , , ) (push) Canceled after 0s
ci / remote-bench (push) Canceled after 0s
ci / publish-gitea-release (push) Canceled after 0s
This commit is contained in:
+19
-1
@@ -24,6 +24,24 @@ function Require-Command($Name) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function Ensure-Cargo {
|
||||||
|
if (Get-Command cargo -ErrorAction SilentlyContinue) {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if (-not (Get-Command winget -ErrorAction SilentlyContinue)) {
|
||||||
|
throw "cargo not found and winget is unavailable; install Rust from https://rustup.rs or set DOSH_USE_PREBUILT=1"
|
||||||
|
}
|
||||||
|
Write-Host "cargo not found; installing Rust toolchain with winget/rustup"
|
||||||
|
winget install --id Rustlang.Rustup -e --accept-package-agreements --accept-source-agreements
|
||||||
|
$cargoBin = Join-Path $HOME ".cargo\bin"
|
||||||
|
if (Test-Path $cargoBin) {
|
||||||
|
$env:Path = "$cargoBin;$env:Path"
|
||||||
|
}
|
||||||
|
if (-not (Get-Command cargo -ErrorAction SilentlyContinue)) {
|
||||||
|
throw "cargo was installed but is not available in this terminal yet; open a new terminal and rerun dosh update"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function Normalize-Arch {
|
function Normalize-Arch {
|
||||||
$arch = if ($env:PROCESSOR_ARCHITEW6432) { $env:PROCESSOR_ARCHITEW6432 } else { $env:PROCESSOR_ARCHITECTURE }
|
$arch = if ($env:PROCESSOR_ARCHITEW6432) { $env:PROCESSOR_ARCHITEW6432 } else { $env:PROCESSOR_ARCHITECTURE }
|
||||||
switch ($arch) {
|
switch ($arch) {
|
||||||
@@ -367,7 +385,7 @@ function Install-Prebuilt {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function Install-FromSource {
|
function Install-FromSource {
|
||||||
Require-Command cargo
|
Ensure-Cargo
|
||||||
if (Test-Path "Cargo.toml") {
|
if (Test-Path "Cargo.toml") {
|
||||||
$src = (Get-Location).Path
|
$src = (Get-Location).Path
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
+52
-11
@@ -4428,7 +4428,7 @@ fn run_update(config: &dosh::config::ClientConfig, options: UpdateOptions) -> Re
|
|||||||
env!("CARGO_PKG_VERSION"),
|
env!("CARGO_PKG_VERSION"),
|
||||||
latest_release_tag(&repo)?.as_deref(),
|
latest_release_tag(&repo)?.as_deref(),
|
||||||
);
|
);
|
||||||
let status = run_update_installer(
|
run_update_installer(
|
||||||
config,
|
config,
|
||||||
&repo,
|
&repo,
|
||||||
&installer,
|
&installer,
|
||||||
@@ -4437,9 +4437,6 @@ fn run_update(config: &dosh::config::ClientConfig, options: UpdateOptions) -> Re
|
|||||||
&use_prebuilt,
|
&use_prebuilt,
|
||||||
binary_version.as_deref(),
|
binary_version.as_deref(),
|
||||||
)?;
|
)?;
|
||||||
if !status.success() {
|
|
||||||
return Err(anyhow!("dosh update failed with status {status}"));
|
|
||||||
}
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -4451,7 +4448,7 @@ fn run_update_installer(
|
|||||||
update_cache: &str,
|
update_cache: &str,
|
||||||
use_prebuilt: &str,
|
use_prebuilt: &str,
|
||||||
binary_version: Option<&str>,
|
binary_version: Option<&str>,
|
||||||
) -> Result<std::process::ExitStatus> {
|
) -> Result<()> {
|
||||||
if cfg!(windows) {
|
if cfg!(windows) {
|
||||||
let script = windows_update_script(
|
let script = windows_update_script(
|
||||||
config,
|
config,
|
||||||
@@ -4462,15 +4459,18 @@ fn run_update_installer(
|
|||||||
use_prebuilt,
|
use_prebuilt,
|
||||||
binary_version,
|
binary_version,
|
||||||
);
|
);
|
||||||
return Command::new("powershell.exe")
|
let script = windows_deferred_update_script(std::process::id(), &script);
|
||||||
|
Command::new("powershell.exe")
|
||||||
.arg("-NoProfile")
|
.arg("-NoProfile")
|
||||||
.arg("-ExecutionPolicy")
|
.arg("-ExecutionPolicy")
|
||||||
.arg("Bypass")
|
.arg("Bypass")
|
||||||
.arg("-Command")
|
.arg("-Command")
|
||||||
.arg(script)
|
.arg(script)
|
||||||
.stdin(Stdio::null())
|
.stdin(Stdio::null())
|
||||||
.status()
|
.spawn()
|
||||||
.context("run dosh update installer");
|
.context("start deferred dosh update installer")?;
|
||||||
|
println!("dosh update started; the installer will run after this process exits");
|
||||||
|
return Ok(());
|
||||||
}
|
}
|
||||||
let script = unix_update_script(
|
let script = unix_update_script(
|
||||||
config,
|
config,
|
||||||
@@ -4481,12 +4481,16 @@ fn run_update_installer(
|
|||||||
use_prebuilt,
|
use_prebuilt,
|
||||||
binary_version,
|
binary_version,
|
||||||
);
|
);
|
||||||
Command::new("sh")
|
let status = Command::new("sh")
|
||||||
.arg("-c")
|
.arg("-c")
|
||||||
.arg(script)
|
.arg(script)
|
||||||
.stdin(Stdio::null())
|
.stdin(Stdio::null())
|
||||||
.status()
|
.status()
|
||||||
.context("run dosh update installer")
|
.context("run dosh update installer")?;
|
||||||
|
if !status.success() {
|
||||||
|
return Err(anyhow!("dosh update failed with status {status}"));
|
||||||
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn unix_update_script(
|
fn unix_update_script(
|
||||||
@@ -4566,6 +4570,17 @@ fn windows_update_script(
|
|||||||
script
|
script
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn windows_deferred_update_script(parent_pid: u32, installer_script: &str) -> String {
|
||||||
|
format!(
|
||||||
|
"$ErrorActionPreference='Stop';\
|
||||||
|
$ProgressPreference='SilentlyContinue';\
|
||||||
|
while (Get-Process -Id {parent_pid} -ErrorAction SilentlyContinue) {{ \
|
||||||
|
Start-Sleep -Milliseconds 100 \
|
||||||
|
}};\
|
||||||
|
{installer_script}"
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn powershell_string(value: &str) -> String {
|
fn powershell_string(value: &str) -> String {
|
||||||
format!("'{}'", value.replace('\'', "''"))
|
format!("'{}'", value.replace('\'', "''"))
|
||||||
}
|
}
|
||||||
@@ -10175,7 +10190,8 @@ mod tests {
|
|||||||
trace_report_warnings, unix_update_script, update_binary_version_for_installer,
|
trace_report_warnings, unix_update_script, update_binary_version_for_installer,
|
||||||
update_installer_url, update_version_status, upsert_managed_block, valid_forward_host,
|
update_installer_url, update_version_status, upsert_managed_block, valid_forward_host,
|
||||||
vscode_safe_alias, wake_repaint_retry_deadline, windows_command_word,
|
vscode_safe_alias, wake_repaint_retry_deadline, windows_command_word,
|
||||||
windows_mode_from_readonly, windows_readonly_from_mode, windows_update_script,
|
windows_deferred_update_script, windows_mode_from_readonly, windows_readonly_from_mode,
|
||||||
|
windows_update_script,
|
||||||
};
|
};
|
||||||
use dosh::config::{ClientConfig, CommandExtension, HostConfig};
|
use dosh::config::{ClientConfig, CommandExtension, HostConfig};
|
||||||
use dosh::native::EnvVar;
|
use dosh::native::EnvVar;
|
||||||
@@ -12423,6 +12439,31 @@ mod tests {
|
|||||||
assert!(!windows.contains(" sh -s "));
|
assert!(!windows.contains(" sh -s "));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn windows_update_script_waits_for_parent_before_replacing_locked_exe() {
|
||||||
|
let installer = windows_update_script(
|
||||||
|
&ClientConfig::default(),
|
||||||
|
"https://git.palav.dev/Palav/dosh.git",
|
||||||
|
"https://git.palav.dev/Palav/dosh/raw/branch/main/install.ps1",
|
||||||
|
"client",
|
||||||
|
"C:\\Users\\palav\\AppData\\Local\\dosh\\source",
|
||||||
|
"1",
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
let deferred = windows_deferred_update_script(4242, &installer);
|
||||||
|
assert!(deferred.contains("Get-Process -Id 4242 -ErrorAction SilentlyContinue"));
|
||||||
|
assert!(deferred.contains("Start-Sleep -Milliseconds 100"));
|
||||||
|
assert!(
|
||||||
|
deferred.contains(
|
||||||
|
"irm 'https://git.palav.dev/Palav/dosh/raw/branch/main/install.ps1' | iex"
|
||||||
|
)
|
||||||
|
);
|
||||||
|
assert!(
|
||||||
|
deferred.find("Get-Process -Id 4242").unwrap()
|
||||||
|
< deferred.find("irm 'https://git.palav.dev").unwrap()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn update_uses_local_tag_when_release_latest_is_older() {
|
fn update_uses_local_tag_when_release_latest_is_older() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
@@ -145,6 +145,20 @@ fn windows_installer_reuses_persistent_source_update_cache() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn windows_installer_bootstraps_rust_for_source_fallback_like_unix() {
|
||||||
|
let install = include_str!("../install.sh");
|
||||||
|
let ps1 = include_str!("../install.ps1");
|
||||||
|
assert!(install.contains("ensure_cargo()"));
|
||||||
|
assert!(install.contains("cargo not found; installing Rust toolchain with rustup"));
|
||||||
|
assert!(ps1.contains("function Ensure-Cargo"));
|
||||||
|
assert!(ps1.contains("cargo not found; installing Rust toolchain with winget/rustup"));
|
||||||
|
assert!(ps1.contains("winget install --id Rustlang.Rustup"));
|
||||||
|
assert!(ps1.contains("--accept-package-agreements --accept-source-agreements"));
|
||||||
|
assert!(ps1.contains("Ensure-Cargo"));
|
||||||
|
assert!(!ps1.contains("Require-Command cargo"));
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn windows_installer_adds_user_path_idempotently() {
|
fn windows_installer_adds_user_path_idempotently() {
|
||||||
let ps1 = include_str!("../install.ps1");
|
let ps1 = include_str!("../install.ps1");
|
||||||
|
|||||||
Reference in New Issue
Block a user