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 @@ pub fn crates<'a>(&'a self) -> impl Iterator<Item = SysrootCrate> + ExactSizeIte
} }
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 @@ pub fn discover(cargo_toml: &Path) -> Result<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,6 +90,7 @@ fn by_name(&self, name: &str) -> Option<SysrootCrate> {
} }
} }
fn get_or_install_rust_src(cargo_toml: &Path) -> Result<PathBuf> {
fn try_find_src_path(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,10 +103,13 @@ 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)?;
@ -136,6 +137,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 {
pub fn name(self, sysroot: &Sysroot) -> &str { pub fn name(self, sysroot: &Sysroot) -> &str {
&sysroot.crates[self].name &sysroot.crates[self].name