Jelajahi Sumber

cli: set I/O stream to `Stdio:null` if the given `solana_version` is already installed (#2757)

Co-authored-by: acheron <acheroncrypto@gmail.com>
Sabir Khan 1 tahun lalu
induk
melakukan
7cbdff657d
2 mengubah file dengan 40 tambahan dan 16 penghapusan
  1. 1 0
      CHANGELOG.md
  2. 39 16
      cli/src/lib.rs

+ 1 - 0
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
 

+ 39 - 16
cli/src/lib.rs

@@ -495,21 +495,28 @@ fn override_toolchain(cfg_override: &ConfigOverride) -> Result<RestoreToolchainC
 
     let cfg = Config::discover(cfg_override)?;
     if let Some(cfg) = cfg {
-        fn get_current_version(cmd_name: &str) -> Result<String> {
-            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();
+                .to_string()
+        }
 
+        fn get_current_version(cmd_name: &str) -> Result<String> {
+            let output = std::process::Command::new(cmd_name)
+                .arg("--version")
+                .output()?;
+            if !output.status.success() {
+                return Err(anyhow!("Failed to run `{cmd_name} --version`"));
+            }
+
+            let output_version = std::str::from_utf8(&output.stdout)?;
+            let version = parse_version(output_version);
             Ok(version)
         }
 
@@ -519,15 +526,33 @@ fn override_toolchain(cfg_override: &ConfigOverride) -> Result<RestoreToolchainC
                 // 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<bool> {
+                fn override_solana_version(version: String) -> Result<bool> {
+                    let output = std::process::Command::new("solana-install")
+                        .arg("list")
+                        .output()?;
+                    if !output.status.success() {
+                        return Err(anyhow!("Failed to list installed `solana` versions"));
+                    }
+
+                    // 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(Stdio::null())
-                        .stdout(Stdio::null())
+                        .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())? {
@@ -537,12 +562,10 @@ fn override_toolchain(cfg_override: &ConfigOverride) -> Result<RestoreToolchainC
                             false => Err(anyhow!("Failed to restore `solana` version")),
                         }
                     })),
-                    false => {
-                        eprintln!(
-                            "Failed to override `solana` version to {solana_version}, \
+                    false => eprintln!(
+                        "Failed to override `solana` version to {solana_version}, \
                         using {current_version} instead"
-                        );
-                    }
+                    ),
                 }
             }
         }