Skip to content

Commit

Permalink
implement some basic version mismatch detection
Browse files Browse the repository at this point in the history
  • Loading branch information
teh-cmc committed Oct 26, 2023
1 parent effe576 commit 849672f
Showing 1 changed file with 87 additions and 5 deletions.
92 changes: 87 additions & 5 deletions crates/re_sdk/src/spawn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -130,10 +130,11 @@ impl std::fmt::Debug for SpawnError {
pub fn spawn(opts: &SpawnOptions) -> Result<(), SpawnError> {
use std::{net::TcpStream, process::Command, time::Duration};

// NOTE: It's indented on purpose, it just looks better and reads easier.
const EXECUTABLE_NOT_FOUND: &str = //
// NOTE: These are indented on purpose, it just looks better and reads easier.

const MSG_INSTALL_HOW_TO: &str = //
"
You can install binary releases of the Rerun Viewer:
You can install an appropriate version of the Rerun Viewer via binary releases:
* Using `cargo`: `cargo binstall rerun-cli` (see https://github.com/cargo-bins/cargo-binstall)
* Via direct download from our release assets: https://github.com/rerun-io/rerun/releases/latest/
* Using `pip`: `pip3 install rerun-sdk` (warning: pip version has slower start times!)
Expand All @@ -142,6 +143,26 @@ pub fn spawn(opts: &SpawnOptions) -> Result<(), SpawnError> {
https://rerun.io/docs/getting-started/installing-viewer
";

const MSG_INSTALL_HOW_TO_VERSIONED: &str = //
"
You can install an appropriate version of the Rerun Viewer via binary releases:
* Using `cargo`: `cargo binstall --force rerun-cli@__VIEWER_VERSION__` (see https://github.com/cargo-bins/cargo-binstall)
* Via direct download from our release assets: https://github.com/rerun-io/rerun/releases/__VIEWER_VERSION__/
* Using `pip`: `pip3 install rerun-sdk==__VIEWER_VERSION__` (warning: pip version has slower start times!)
For more information, refer to our complete install documentation over at:
https://rerun.io/docs/getting-started/installing-viewer
";

const MSG_VERSION_MISMATCH: &str = //
"
⚠ The version of the Rerun Viewer available on your PATH does not match the version of your Rerun SDK ⚠
Rerun does not make any kind of backwards/forwards compatibility guarantee yet: this can lead to (subtle) bugs.
> Rerun Viewer: v__VIEWER_VERSION__ (executable: \"__VIEWER_PATH__\")
> Rerun SDK: v__SDK_VERSION__";

let port = opts.port;
let connect_addr = opts.connect_addr();
let memory_limit = &opts.memory_limit;
Expand All @@ -156,7 +177,68 @@ pub fn spawn(opts: &SpawnOptions) -> Result<(), SpawnError> {
return Ok(());
}

let res = Command::new(executable_path)
fn check<T>(opts: &SpawnOptions, res: Result<T, std::io::Error>) -> Result<T, SpawnError> {
match res {
output @ Ok(_) => output.map_err(Into::into),
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {
if let Some(executable_path) = opts.executable_path.as_ref() {
Err(SpawnError::ExecutableNotFound {
executable_path: executable_path.clone(),
})
} else {
Err(SpawnError::ExecutableNotFoundInPath {
message: MSG_INSTALL_HOW_TO.to_owned(),
executable_name: opts.executable_name.clone(),
search_path: std::env::var("PATH").unwrap_or_else(|_| String::new()),
})
}
}
Err(err) => Err(err.into()),
}
}

let viewer_version = {
let output = check(
opts,
Command::new(&executable_path).arg("--version").output(),
)?;

// <name> <semver> [<rust_info>] <target> <branch> <commit> <build_date>
let output = String::from_utf8_lossy(&output.stdout);
let output = output.split_whitespace().collect::<Vec<_>>();

(output.len() >= 2)
.then(|| re_build_info::CrateVersion::try_parse(output[1]).ok())
.flatten()
};

if let Some(viewer_version) = viewer_version {
let sdk_version = re_build_info::build_info!().version;

if !viewer_version.is_compatible_with(sdk_version) {
eprintln!(
"{}",
MSG_VERSION_MISMATCH
.replace("__VIEWER_VERSION__", &viewer_version.to_string())
.replace("__VIEWER_PATH__", &executable_path)
.replace("__SDK_VERSION__", &sdk_version.to_string())
);

// Don't recommend installing stuff through registries if the user is running some
// weird version.
if sdk_version.meta.is_none() {
eprintln!(
"{}",
MSG_INSTALL_HOW_TO_VERSIONED
.replace("__VIEWER_VERSION__", &sdk_version.to_string())
);
} else {
eprintln!();
}
}
}

let res = Command::new(&executable_path)
.arg(format!("--port={port}"))
.arg(format!("--memory-limit={memory_limit}"))
.arg("--skip-welcome-screen")
Expand All @@ -172,7 +254,7 @@ pub fn spawn(opts: &SpawnOptions) -> Result<(), SpawnError> {
})
} else {
Err(SpawnError::ExecutableNotFoundInPath {
message: EXECUTABLE_NOT_FOUND.to_owned(),
message: MSG_INSTALL_HOW_TO.to_owned(),
executable_name: opts.executable_name.clone(),
search_path: std::env::var("PATH").unwrap_or_else(|_| String::new()),
})
Expand Down

0 comments on commit 849672f

Please sign in to comment.