From b2b2667cf9995d4aea82ec771296e88d7cc2271a Mon Sep 17 00:00:00 2001 From: simplysabir Date: Mon, 1 Jan 2024 20:31:30 +0530 Subject: [PATCH 1/6] Added conditional to check with installed version --- cli/src/lib.rs | 51 +++++++++++++++++++++++++++++--------------------- 1 file changed, 30 insertions(+), 21 deletions(-) diff --git a/cli/src/lib.rs b/cli/src/lib.rs index f901b85081..214004f5d2 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -513,35 +513,44 @@ fn override_toolchain(cfg_override: &ConfigOverride) -> Result Result { + let output = std::process::Command::new("solana").arg("--version").output()?; + let output_version = std::str::from_utf8(&output.stdout)?; + Ok(output_version.contains(version)) + } + if let Some(solana_version) = &cfg.toolchain.solana_version { let current_version = get_current_version("solana")?; if solana_version != ¤t_version { // We are overriding with `solana-install` command instead of using the binaries // from `~/.local/share/solana/install/releases` because we use multiple Solana // binaries in various commands. - fn override_solana_version(version: String) -> std::io::Result { - std::process::Command::new("solana-install") - .arg("init") - .arg(&version) - .stderr(Stdio::null()) - .stdout(Stdio::null()) - .spawn()? - .wait() - .map(|status| status.success()) - } + if !is_solana_version_installed(solana_version)? { + // Set standard I/O stream to null only if the version is not installed + fn override_solana_version(version: String) -> std::io::Result { + std::process::Command::new("solana-install") + .arg("init") + .arg(&version) + .stderr(Stdio::null()) + .stdout(Stdio::null()) + .spawn()? + .wait() + .map(|status| status.success()) + } - match override_solana_version(solana_version.to_owned())? { - true => restore_cbs.push(Box::new(|| { - match override_solana_version(current_version)? { - true => Ok(()), - false => Err(anyhow!("Failed to restore `solana` version")), - } - })), - false => { - eprintln!( - "Failed to override `solana` version to {solana_version}, \ + match override_solana_version(solana_version.to_owned())? { + true => restore_cbs.push(Box::new(|| { + match override_solana_version(current_version)? { + true => Ok(()), + false => Err(anyhow!("Failed to restore `solana` version")), + } + })), + false => { + eprintln!( + "Failed to override `solana` version to {solana_version}, \ using {current_version} instead" - ); + ); + } } } } From 37dd9f4c4933a06c7e2245b95ecdff0d7c7e1cea Mon Sep 17 00:00:00 2001 From: simplysabir Date: Thu, 4 Jan 2024 16:12:27 +0530 Subject: [PATCH 2/6] Improved upon method --- cli/src/lib.rs | 75 ++++++++++++++++++++++++++++++++++---------------- 1 file changed, 52 insertions(+), 23 deletions(-) diff --git a/cli/src/lib.rs b/cli/src/lib.rs index 214004f5d2..b149e91979 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -512,12 +512,51 @@ fn override_toolchain(cfg_override: &ConfigOverride) -> Result Result { - let output = std::process::Command::new("solana").arg("--version").output()?; + let output = std::process::Command::new("solana") + .arg("--version") + .output()?; let output_version = std::str::from_utf8(&output.stdout)?; Ok(output_version.contains(version)) } + // Function to override the Solana version + fn override_solana_version(version: String) -> std::io::Result { + let is_installed = match is_solana_version_installed(&version) { + Ok(is_installed) => is_installed, + Err(err) => { + eprintln!("Error checking Solana version installation: {:?}", err); + return Err(std::io::Error::new( + std::io::ErrorKind::Other, + "Error checking installation", + )); + } + }; + + if is_installed { + // Solana version is already installed, set standard I/O streams to null + std::process::Command::new("solana-install") + .arg("init") + .arg(&version) + .stderr(Stdio::null()) + .stdout(Stdio::null()) + .spawn()? + .wait() + .map(|status| status.success()) + } else { + // Solana version is not installed, display installation progress + std::process::Command::new("solana-install") + .arg("init") + .arg(&version) + .spawn()? + .wait() + .map(|status| status.success()) + .map_err(|err| { + eprintln!("Error during Solana installation: {:?}", err); + std::io::Error::new(std::io::ErrorKind::Other, "Error during installation") + }) + } + } if let Some(solana_version) = &cfg.toolchain.solana_version { let current_version = get_current_version("solana")?; @@ -525,32 +564,22 @@ fn override_toolchain(cfg_override: &ConfigOverride) -> Result std::io::Result { - std::process::Command::new("solana-install") - .arg("init") - .arg(&version) - .stderr(Stdio::null()) - .stdout(Stdio::null()) - .spawn()? - .wait() - .map(|status| status.success()) - } - - match override_solana_version(solana_version.to_owned())? { - true => restore_cbs.push(Box::new(|| { + match override_solana_version(solana_version.to_owned())? { + true => { + // If successful, add a restore callback + restore_cbs.push(Box::new(|| { match override_solana_version(current_version)? { true => Ok(()), false => Err(anyhow!("Failed to restore `solana` version")), } - })), - false => { - eprintln!( - "Failed to override `solana` version to {solana_version}, \ + })); + } + false => { + // Print error message if override fails + eprintln!( + "Failed to override `solana` version to {solana_version}, \ using {current_version} instead" - ); - } + ); } } } From 4b74d6c6e7042334497e033df962282068fda599 Mon Sep 17 00:00:00 2001 From: simplysabir Date: Fri, 5 Jan 2024 23:29:58 +0530 Subject: [PATCH 3/6] removed comments and updated method --- cli/src/lib.rs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/cli/src/lib.rs b/cli/src/lib.rs index b149e91979..b57cf99ef1 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -512,15 +512,21 @@ fn override_toolchain(cfg_override: &ConfigOverride) -> Result Result { - let output = std::process::Command::new("solana") - .arg("--version") + let output = std::process::Command::new("ls") + .arg("-l") + .arg("~/.local/share/solana/install/releases") .output()?; - let output_version = std::str::from_utf8(&output.stdout)?; - Ok(output_version.contains(version)) + + if output.status.success() { + let output_versions = std::str::from_utf8(&output.stdout)?; + Ok(output_versions.lines().any(|line| line.contains(version))) + } else { + Err(anyhow!("Failed to list Solana installed versions")) + } } - // Function to override the Solana version + fn override_solana_version(version: String) -> std::io::Result { let is_installed = match is_solana_version_installed(&version) { Ok(is_installed) => is_installed, @@ -566,7 +572,6 @@ fn override_toolchain(cfg_override: &ConfigOverride) -> Result { - // If successful, add a restore callback restore_cbs.push(Box::new(|| { match override_solana_version(current_version)? { true => Ok(()), @@ -575,7 +580,6 @@ fn override_toolchain(cfg_override: &ConfigOverride) -> Result { - // Print error message if override fails eprintln!( "Failed to override `solana` version to {solana_version}, \ using {current_version} instead" From d29f5640928be337da101cc5635235e60c1c8581 Mon Sep 17 00:00:00 2001 From: simplysabir Date: Sat, 6 Jan 2024 15:53:41 +0530 Subject: [PATCH 4/6] fixed fucntion --- cli/src/lib.rs | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/cli/src/lib.rs b/cli/src/lib.rs index b57cf99ef1..fbc1e9d43a 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -512,21 +512,32 @@ fn override_toolchain(cfg_override: &ConfigOverride) -> Result Result { let output = std::process::Command::new("ls") .arg("-l") .arg("~/.local/share/solana/install/releases") .output()?; - + if output.status.success() { let output_versions = std::str::from_utf8(&output.stdout)?; - Ok(output_versions.lines().any(|line| line.contains(version))) + + let installed_versions: Vec = output_versions + .lines() + .filter_map(|line| { + Regex::new(r"(\d+\.\d+\.\S+)") + .ok() + .and_then(|re| re.captures(line)) + .map(|captures| captures[0].to_string()) + }) + .collect(); + + Ok(installed_versions.contains(&version.to_string())) } else { Err(anyhow!("Failed to list Solana installed versions")) } } - + fn override_solana_version(version: String) -> std::io::Result { let is_installed = match is_solana_version_installed(&version) { Ok(is_installed) => is_installed, From 003445e07f2ef4e8e6295bee81e12be8b6cf091b Mon Sep 17 00:00:00 2001 From: acheron Date: Sat, 6 Jan 2024 17:19:43 +0100 Subject: [PATCH 5/6] Use `solana-install list` to make it OS agnostic --- cli/src/lib.rs | 130 +++++++++++++++++++------------------------------ 1 file changed, 50 insertions(+), 80 deletions(-) diff --git a/cli/src/lib.rs b/cli/src/lib.rs index fbc1e9d43a..5da3c68f03 100644 --- a/cli/src/lib.rs +++ b/cli/src/lib.rs @@ -495,84 +495,29 @@ fn override_toolchain(cfg_override: &ConfigOverride) -> Result Result { - let output = std::process::Command::new(cmd_name) - .arg("--version") - .output()?; - let output_version = std::str::from_utf8(&output.stdout)?; - let version = Regex::new(r"(\d+\.\d+\.\S+)") + fn parse_version(text: &str) -> String { + Regex::new(r"(\d+\.\d+\.\S+)") .unwrap() - .captures_iter(output_version) + .captures_iter(text) .next() .unwrap() .get(0) .unwrap() .as_str() - .to_string(); - - Ok(version) + .to_string() } - fn is_solana_version_installed(version: &str) -> Result { - let output = std::process::Command::new("ls") - .arg("-l") - .arg("~/.local/share/solana/install/releases") + fn get_current_version(cmd_name: &str) -> Result { + let output = std::process::Command::new(cmd_name) + .arg("--version") .output()?; - - if output.status.success() { - let output_versions = std::str::from_utf8(&output.stdout)?; - - let installed_versions: Vec = output_versions - .lines() - .filter_map(|line| { - Regex::new(r"(\d+\.\d+\.\S+)") - .ok() - .and_then(|re| re.captures(line)) - .map(|captures| captures[0].to_string()) - }) - .collect(); - - Ok(installed_versions.contains(&version.to_string())) - } else { - Err(anyhow!("Failed to list Solana installed versions")) + if !output.status.success() { + return Err(anyhow!("Failed to run `{cmd_name} --version`")); } - } - fn override_solana_version(version: String) -> std::io::Result { - let is_installed = match is_solana_version_installed(&version) { - Ok(is_installed) => is_installed, - Err(err) => { - eprintln!("Error checking Solana version installation: {:?}", err); - return Err(std::io::Error::new( - std::io::ErrorKind::Other, - "Error checking installation", - )); - } - }; - - if is_installed { - // Solana version is already installed, set standard I/O streams to null - std::process::Command::new("solana-install") - .arg("init") - .arg(&version) - .stderr(Stdio::null()) - .stdout(Stdio::null()) - .spawn()? - .wait() - .map(|status| status.success()) - } else { - // Solana version is not installed, display installation progress - std::process::Command::new("solana-install") - .arg("init") - .arg(&version) - .spawn()? - .wait() - .map(|status| status.success()) - .map_err(|err| { - eprintln!("Error during Solana installation: {:?}", err); - std::io::Error::new(std::io::ErrorKind::Other, "Error during installation") - }) - } + let output_version = std::str::from_utf8(&output.stdout)?; + let version = parse_version(output_version); + Ok(version) } if let Some(solana_version) = &cfg.toolchain.solana_version { @@ -581,21 +526,46 @@ fn override_toolchain(cfg_override: &ConfigOverride) -> Result { - restore_cbs.push(Box::new(|| { - match override_solana_version(current_version)? { - true => Ok(()), - false => Err(anyhow!("Failed to restore `solana` version")), - } - })); + fn override_solana_version(version: String) -> Result { + let output = std::process::Command::new("solana-install") + .arg("list") + .output()?; + if !output.status.success() { + return Err(anyhow!("Failed to list installed `solana` versions")); } - false => { - eprintln!( - "Failed to override `solana` version to {solana_version}, \ + + // Hide the installation progress if the version is already installed + let is_installed = std::str::from_utf8(&output.stdout)? + .lines() + .any(|line| parse_version(line) == version); + let (stderr, stdout) = if is_installed { + (Stdio::null(), Stdio::null()) + } else { + (Stdio::inherit(), Stdio::inherit()) + }; + + std::process::Command::new("solana-install") + .arg("init") + .arg(&version) + .stderr(stderr) + .stdout(stdout) + .spawn()? + .wait() + .map(|status| status.success()) + .map_err(|err| anyhow!("Failed to run `solana-install` command: {err}")) + } + + match override_solana_version(solana_version.to_owned())? { + true => restore_cbs.push(Box::new(|| { + match override_solana_version(current_version)? { + true => Ok(()), + false => Err(anyhow!("Failed to restore `solana` version")), + } + })), + false => eprintln!( + "Failed to override `solana` version to {solana_version}, \ using {current_version} instead" - ); - } + ), } } } From 2aa269691655d93bd983804828a571d101f252b4 Mon Sep 17 00:00:00 2001 From: acheron Date: Sat, 6 Jan 2024 17:31:51 +0100 Subject: [PATCH 6/6] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index c21bf728b9..0374e5cec4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,7 @@ The minor version will be incremented upon a breaking change and the patch versi - lang: Eliminate temporary Vec allocations when serializing data with discriminant and set the default capacity to 256 bytes ([#2691](https://github.com/coral-xyz/anchor/pull/2691)). - lang: Allow custom lifetime in Accounts structure ([#2741](https://github.com/coral-xyz/anchor/pull/2741)). - lang: Remove `try_to_vec` usage while setting the return data in order to reduce heap memory usage ([#2744](https://github.com/coral-xyz/anchor/pull/2744)) +- cli: Show installation progress if Solana tools are not installed when using toolchain overrides ([#2757](https://github.com/coral-xyz/anchor/pull/2757)). ### Breaking