-
-
Notifications
You must be signed in to change notification settings - Fork 1.5k
feat(cua-driver-rs): updater delegates to canonical install script (Windows + Unix) #1673
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,99 @@ | ||
| //! `cua-driver update --apply` implementation. | ||
| //! | ||
| //! Delegates the actual install work to the canonical installer scripts: | ||
| //! - Unix: `libs/cua-driver/scripts/install.sh` (delegates to | ||
| //! `_install-rust.sh` when `--backend=rust`) | ||
| //! - Windows: `libs/cua-driver/scripts/install.ps1` | ||
| //! | ||
| //! Why not reimplement the download / atomic-swap / GC in Rust? Those scripts | ||
| //! already solve the hard problems: | ||
| //! - target-triple → asset-name mapping (per-OS, per-arch) | ||
| //! - per-version dir layout (`packages/releases/<version>-<target>/`) | ||
| //! - atomic upgrade — symlink retarget on Unix, NTFS directory-junction | ||
| //! retarget on Windows. A running daemon survives the swap because the | ||
| //! kernel keeps the old inode alive (Unix) or the junction flip is a | ||
| //! reparse-point swap that doesn't touch the locked .exe (Windows). | ||
| //! - GC of stale per-version dirs (`CUA_DRIVER_RS_KEEP_VERSIONS`) | ||
| //! - PATH wiring | ||
| //! | ||
| //! Treating "update" as a pinned re-install with `CUA_DRIVER_RS_VERSION` set | ||
| //! keeps install + update reading from one source of truth. Improvements to | ||
| //! the on-disk layout ship in the scripts and benefit both code paths. | ||
|
|
||
| use std::process::{Command, ExitStatus}; | ||
|
|
||
| /// Canonical install-script URLs. Match what the docs print as the one-liner; | ||
| /// users who run `cua-driver update --apply` and re-run the printed manual | ||
| /// command land at the exact same script. Per-OS gating keeps the unused | ||
| /// constant from triggering `dead_code` on the platform that doesn't use it. | ||
| #[cfg(not(windows))] | ||
| const CANONICAL_INSTALL_SH: &str = | ||
| "https://raw.githubusercontent.com/trycua/cua/main/libs/cua-driver/scripts/install.sh"; | ||
| #[cfg(windows)] | ||
| const CANONICAL_INSTALL_PS1: &str = | ||
| "https://raw.githubusercontent.com/trycua/cua/main/libs/cua-driver/scripts/install.ps1"; | ||
|
|
||
| /// The env var both scripts honour to pin the target release tag. Set to a | ||
| /// bare version like `"0.2.18"` (no `cua-driver-rs-v` prefix). See | ||
| /// `libs/cua-driver/scripts/_install-rust.sh` + `install.ps1`. | ||
| const VERSION_PIN_ENV: &str = "CUA_DRIVER_RS_VERSION"; | ||
|
|
||
| /// Invoke the canonical installer pinned to `version`. Returns the | ||
| /// installer's exit status so the caller can produce the right | ||
| /// "succeeded / failed — re-run manually" message. | ||
| pub fn run_install_script(version: &str) -> std::io::Result<ExitStatus> { | ||
| #[cfg(windows)] | ||
| { | ||
| // Match the documented Windows one-liner: `irm <url> | iex`. | ||
| // -ExecutionPolicy Bypass lets the downloaded script run on | ||
| // machines with the default restricted policy without requiring | ||
| // the user to Set-ExecutionPolicy first. -NoProfile keeps any | ||
| // user profile script from racing the install. | ||
| let pwsh_cmd = format!("iwr -useb {CANONICAL_INSTALL_PS1} | iex"); | ||
| Command::new("powershell.exe") | ||
| .env(VERSION_PIN_ENV, version) | ||
| .args([ | ||
| "-NoProfile", | ||
| "-ExecutionPolicy", | ||
| "Bypass", | ||
| "-Command", | ||
| &pwsh_cmd, | ||
| ]) | ||
| .status() | ||
| } | ||
|
|
||
| #[cfg(not(windows))] | ||
| { | ||
| // Match the canonical curl-piped-to-bash invocation. `--backend=rust` | ||
| // is the explicit selector — without it the canonical install.sh | ||
| // auto-detects on macOS and would install the Swift driver instead. | ||
| let bash_cmd = format!( | ||
| "curl -fsSL {CANONICAL_INSTALL_SH} | bash -s -- install --backend=rust" | ||
| ); | ||
| Command::new("bash") | ||
| .env(VERSION_PIN_ENV, version) | ||
| .args(["-c", &bash_cmd]) | ||
| .status() | ||
|
Comment on lines
+70
to
+76
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -eu
printf 'without pipefail:\n'
bash -c 'missing_cmd | bash -s -- install --backend=rust; printf "exit=%s\n" "$?"'
printf '\nwith pipefail:\n'
bash -o pipefail -c 'missing_cmd | bash -s -- install --backend=rust; printf "exit=%s\n" "$?"'Repository: trycua/cua Length of output: 212 🏁 Script executed: #!/bin/bash
set -eu
printf 'without pipefail:\n'
bash -c 'missing_cmd | bash -s -- install --backend=rust; printf "exit=%s\n" "$?"'
printf '\nwith pipefail:\n'
bash -o pipefail -c 'missing_cmd | bash -s -- install --backend=rust; printf "exit=%s\n" "$?"'Repository: trycua/cua Length of output: 212 🏁 Script executed: #!/bin/bash
set -eu
printf 'without pipefail:\n'
bash -c 'missing_cmd | bash -s -- install --backend=rust; printf "exit=%s\n" "$?"'
printf '\nwith pipefail:\n'
bash -o pipefail -c 'missing_cmd | bash -s -- install --backend=rust; printf "exit=%s\n" "$?"'Repository: trycua/cua Length of output: 212 Propagate The Unix path uses Suggested fix- Command::new("bash")
- .env(VERSION_PIN_ENV, version)
- .args(["-c", &bash_cmd])
+ Command::new("bash")
+ .env(VERSION_PIN_ENV, version)
+ .args(["-o", "pipefail", "-c", &bash_cmd])
.status()🤖 Prompt for AI Agents |
||
| } | ||
| } | ||
|
|
||
| /// True if the local cua-driver daemon is currently accepting connections | ||
| /// on its default socket / named pipe. Used post-install to decide whether | ||
| /// to print the "restart the daemon to pick up the new binary" hint. | ||
| pub fn daemon_is_running() -> bool { | ||
| crate::serve::is_daemon_listening(&crate::serve::default_socket_path()) | ||
| } | ||
|
|
||
| /// The platform-appropriate manual re-install command, used in both the | ||
| /// "available, run --apply" preview and the "apply failed, retry manually" | ||
| /// error message. Kept here so both messages stay in sync. | ||
| pub fn manual_install_one_liner() -> String { | ||
| #[cfg(windows)] | ||
| { | ||
| format!("irm {CANONICAL_INSTALL_PS1} | iex") | ||
| } | ||
| #[cfg(not(windows))] | ||
| { | ||
| format!("curl -fsSL {CANONICAL_INSTALL_SH} | bash -s -- install --backend=rust") | ||
| } | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🧩 Analysis chain
🌐 Web query:
Does Windows PowerShell 5.1 support the&&command chaining operator, or is it only available in PowerShell 7+?💡 Result:
Windows PowerShell 5.1 does not support the
&&pipeline chaining operator. The&&(and||) pipeline chain operators were added beginning in PowerShell 7. [1] Microsoft’s documentation forabout_Pipeline_Chain_Operatorsstates: “Beginning in PowerShell 7, PowerShell implements the&&and||operators to conditionally chain pipelines.” [1] Therefore, Windows PowerShell 5.1 (the “Windows PowerShell” line) lacks&&support and you must use other constructs (for example,-andbetween expressions) or upgrade to PowerShell 7+ to use&&. [1] Practical implication: in PowerShell 5.1,command1 && command2is not valid pipeline chaining syntax; in PowerShell 7+, it conditionally runscommand2only if the left-hand pipeline succeeded. [1]Citations:
🏁 Script executed:
Repository: trycua/cua
Length of output: 2889
🏁 Script executed:
Repository: trycua/cua
Length of output: 1582
🏁 Script executed:
Repository: trycua/cua
Length of output: 5182
🏁 Script executed:
Repository: trycua/cua
Length of output: 773
Make the restart hint Windows PowerShell 5.1-compatible.
cua-driver stop && cua-driver serveuses&&, which isn’t supported by Windows PowerShell 5.1 (it was added in PowerShell 7). Print two separate commands on Windows instead.File:
libs/cua-driver-rs/crates/cua-driver/src/cli.rs(around the restart message)Suggested fix
if daemon_was_running { println!(); println!("A daemon was running before the install. Restart it to pick up the new binary:"); - println!(" cua-driver stop && cua-driver serve"); + #[cfg(windows)] + { + println!(" cua-driver stop"); + println!(" cua-driver serve"); + } + #[cfg(not(windows))] + { + println!(" cua-driver stop && cua-driver serve"); + } }📝 Committable suggestion
🤖 Prompt for AI Agents