Idempotent location and installation of rust src

This commit is contained in:
Kirill Bulatov 2020-02-18 00:03:57 +02:00
parent 50cf1e3d67
commit addb61df36

View file

@ -47,10 +47,8 @@ impl Sysroot {
} }
pub fn discover(cargo_toml: &Path) -> Result<Sysroot> { pub fn discover(cargo_toml: &Path) -> Result<Sysroot> {
let mut src = try_find_src_path(cargo_toml)?; let src = get_or_install_rust_src(cargo_toml)?;
if !src.exists() {
src = try_install_rust_src(cargo_toml)?;
if !src.exists() { if !src.exists() {
Err(anyhow!( Err(anyhow!(
"can't load standard library from sysroot\n\ "can't load standard library from sysroot\n\
@ -60,7 +58,6 @@ impl Sysroot {
src.display(), src.display(),
))?; ))?;
} }
}
let mut sysroot = Sysroot { crates: Arena::default() }; let mut sysroot = Sysroot { crates: Arena::default() };
for name in SYSROOT_CRATES.trim().lines() { for name in SYSROOT_CRATES.trim().lines() {
@ -93,7 +90,8 @@ impl Sysroot {
} }
} }
fn try_find_src_path(cargo_toml: &Path) -> Result<PathBuf> { fn get_or_install_rust_src(cargo_toml: &Path) -> Result<PathBuf> {
fn try_find_src_path(cargo_toml: &Path) -> Result<PathBuf> {
if let Ok(path) = env::var("RUST_SRC_PATH") { if let Ok(path) = env::var("RUST_SRC_PATH") {
return Ok(path.into()); return Ok(path.into());
} }
@ -105,18 +103,21 @@ fn try_find_src_path(cargo_toml: &Path) -> Result<PathBuf> {
.context("rustc --print sysroot failed")?; .context("rustc --print sysroot failed")?;
if !rustc_output.status.success() { if !rustc_output.status.success() {
match rustc_output.status.code() { match rustc_output.status.code() {
Some(code) => { Some(code) => bail!(
bail!("failed to locate sysroot: rustc --print sysroot exited with code {}", code) "failed to locate sysroot: rustc --print sysroot exited with code {}",
code
),
None => {
bail!("failed to locate sysroot: rustc --print sysroot terminated by signal")
} }
None => bail!("failed to locate sysroot: rustc --print sysroot terminated by signal"),
}; };
} }
let stdout = String::from_utf8(rustc_output.stdout)?; let stdout = String::from_utf8(rustc_output.stdout)?;
let sysroot_path = Path::new(stdout.trim()); let sysroot_path = Path::new(stdout.trim());
Ok(sysroot_path.join("lib/rustlib/src/rust/src")) Ok(sysroot_path.join("lib/rustlib/src/rust/src"))
} }
fn try_install_rust_src(cargo_toml: &Path) -> Result<PathBuf> { fn try_install_rust_src(cargo_toml: &Path) -> Result<PathBuf> {
let rustup_output = Command::new("rustup") let rustup_output = Command::new("rustup")
.current_dir(cargo_toml.parent().unwrap()) .current_dir(cargo_toml.parent().unwrap())
.args(&["component", "add", "rust-src"]) .args(&["component", "add", "rust-src"])
@ -134,6 +135,14 @@ fn try_install_rust_src(cargo_toml: &Path) -> Result<PathBuf> {
}; };
} }
try_find_src_path(cargo_toml) try_find_src_path(cargo_toml)
}
let src = try_find_src_path(cargo_toml)?;
if !src.exists() {
try_install_rust_src(cargo_toml)
} else {
Ok(src)
}
} }
impl SysrootCrate { impl SysrootCrate {