LCOV - code coverage report
Current view: top level - internal/src/bin - preinstall-toolchains.rs (source / functions) Hit Total Coverage
Test: unnamed Lines: 0 78 0.0 %
Date: 2024-10-23 19:20:50 Functions: 0 18 0.0 %

          Line data    Source code
       1             : use anyhow::{anyhow, ensure, Context, Result};
       2             : use once_cell::sync::Lazy;
       3             : use regex::Regex;
       4             : use std::{
       5             :     fs::File,
       6             :     io::{BufRead, BufReader},
       7             :     path::Path,
       8             :     process::{Command, Stdio},
       9             :     thread,
      10             : };
      11             : 
      12           0 : fn main() -> Result<()> {
      13           0 :     let toolchains = collect_toolchains(&["cargo-dylint", "internal"])?;
      14             : 
      15           0 :     println!("{:#?}", &toolchains);
      16           0 : 
      17           0 :     let handles = std::iter::once("nightly".to_owned())
      18           0 :         .chain(toolchains)
      19           0 :         .map(|toolchain| (thread::spawn(move || install_toolchain(&toolchain))));
      20             : 
      21           0 :     for handle in handles {
      22           0 :         let () = handle
      23           0 :             .join()
      24           0 :             .map_err(|error| anyhow!("{error:?}"))
      25           0 :             .and_then(std::convert::identity)?;
      26             :     }
      27             : 
      28           0 :     Ok(())
      29           0 : }
      30             : 
      31           0 : fn collect_toolchains(dirs: &[&str]) -> Result<Vec<String>> {
      32           0 :     let mut toolchains = Vec::new();
      33             : 
      34           0 :     for dir in dirs {
      35           0 :         let toolchains_for_dir = collect_toolchains_for_dir(dir)?;
      36           0 :         toolchains.extend(toolchains_for_dir);
      37             :     }
      38             : 
      39           0 :     toolchains.sort();
      40           0 :     toolchains.dedup();
      41           0 : 
      42           0 :     Ok(toolchains)
      43           0 : }
      44             : 
      45           0 : fn collect_toolchains_for_dir(dir: &str) -> Result<Vec<String>> {
      46           0 :     let mut ls_files = Command::new("git")
      47           0 :         .args(["ls-files", dir])
      48           0 :         .stdout(Stdio::piped())
      49           0 :         .spawn()
      50           0 :         .with_context(|| "Could not spawn `git ls-files`")?;
      51             : 
      52           0 :     let stdout = ls_files.stdout.take().unwrap();
      53           0 :     BufReader::new(stdout)
      54           0 :         .lines()
      55           0 :         .try_fold(Vec::new(), |mut toolchains, result| -> Result<_> {
      56           0 :             let path = result.with_context(|| "Could not read from `git ls-files`")?;
      57           0 :             let toolchains_for_path = collect_toolchains_for_path(path)?;
      58           0 :             toolchains.extend(toolchains_for_path);
      59           0 :             Ok(toolchains)
      60           0 :         })
      61           0 : }
      62             : 
      63             : static RE: Lazy<Regex> =
      64           0 :     Lazy::new(|| Regex::new(r"\<nightly-[0-9]{4}-[0-9]{2}-[0-9]{2}\>").unwrap());
      65             : 
      66           0 : fn collect_toolchains_for_path(path: impl AsRef<Path>) -> Result<Vec<String>> {
      67           0 :     let file = File::open(&path).with_context(|| format!("Could not open {:?}", path.as_ref()))?;
      68           0 :     BufReader::new(file)
      69           0 :         .lines()
      70           0 :         .try_fold(Vec::new(), |mut toolchains, result| -> Result<_> {
      71           0 :             let line =
      72           0 :                 result.with_context(|| format!("Could not read from {:?}", path.as_ref()))?;
      73           0 :             let n = line.find("//").unwrap_or(line.len());
      74           0 :             toolchains.extend(RE.find_iter(&line[..n]).map(|m| m.as_str().to_owned()));
      75           0 :             Ok(toolchains)
      76           0 :         })
      77           0 : }
      78             : 
      79           0 : fn install_toolchain(toolchain: &str) -> Result<()> {
      80           0 :     let status = Command::new("rustup")
      81           0 :         .args([
      82           0 :             "install",
      83           0 :             toolchain,
      84           0 :             "--profile=minimal",
      85           0 :             "--no-self-update",
      86           0 :         ])
      87           0 :         .status()
      88           0 :         .with_context(|| format!("Could not install {toolchain} with `rustup`"))?;
      89           0 :     ensure!(status.success());
      90             : 
      91           0 :     let status = Command::new("rustup")
      92           0 :         .args([
      93           0 :             "component",
      94           0 :             "add",
      95           0 :             "llvm-tools-preview",
      96           0 :             "rustc-dev",
      97           0 :             "--toolchain",
      98           0 :             toolchain,
      99           0 :         ])
     100           0 :         .status()
     101           0 :         .with_context(|| format!("Could not add components to {toolchain} with `rustup`"))?;
     102           0 :     ensure!(status.success());
     103             : 
     104           0 :     Ok(())
     105           0 : }

Generated by: LCOV version 1.14