Skip to content

Commit

Permalink
Support new cmdline option --roots (rust-lang#389)
Browse files Browse the repository at this point in the history
* Add new field `Args::roots`
* Use `env::var_os` to fetch `CARGO_INSTALL_ROOTS`
   Previously, it uses `env::var`, which might reject valid path just
   because it is not utf-8 string.
* Update manifest if `CARGO_INSTALL_ROOT` is specified
* Add new fn `install_path::get_cargo_roots_path`
* Fix updating manifest: Use `cargo_roots` instead of default path
* Rm `helpers::statics::cargo_home`

Signed-off-by: Jiahao XU <Jiahao_XU@outlook.com>
  • Loading branch information
NobodyXu authored Sep 17, 2022
1 parent a611b82 commit 934ccc2
Show file tree
Hide file tree
Showing 7 changed files with 67 additions and 38 deletions.
13 changes: 13 additions & 0 deletions crates/bin/src/args.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,19 @@ pub struct Args {
#[clap(help_heading = "Options", long)]
pub install_path: Option<PathBuf>,

/// Install binaries with a custom cargo root.
///
/// By default, we use `$CARGO_INSTALL_ROOT` or `$CARGO_HOME` as the
/// cargo root and global metadata files are updated with the
/// package information.
///
/// Specifying another path here would install the binaries and update
/// the metadata files inside the path you specified.
///
/// NOTE that `--install-path` takes precedence over this option.
#[clap(help_heading = "Options", long)]
pub roots: Option<PathBuf>,

/// Deprecated, here for back-compat only. Secure is now on by default.
#[clap(hide(true), long)]
pub secure: bool,
Expand Down
28 changes: 19 additions & 9 deletions crates/bin/src/entry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,10 +41,17 @@ pub async fn install_crates(mut args: Args, jobserver_client: LazyJobserverClien
// Initialize UI thread
let mut uithread = UIThread::new(!args.no_confirm);

let (install_path, metadata, temp_dir) = block_in_place(|| -> Result<_> {
let (install_path, cargo_roots, metadata, temp_dir) = block_in_place(|| -> Result<_> {
// Compute cargo_roots
let cargo_roots =
install_path::get_cargo_roots_path(args.roots.take()).ok_or_else(|| {
error!("No viable cargo roots path found of specified, try `--roots`");
miette!("No cargo roots path found or specified")
})?;

// Compute install directory
let (install_path, custom_install_path) =
install_path::get_install_path(args.install_path.as_deref());
install_path::get_install_path(args.install_path.as_deref(), Some(&cargo_roots));
let install_path = install_path.ok_or_else(|| {
error!("No viable install path found of specified, try `--install-path`");
miette!("No install path found or specified")
Expand All @@ -54,8 +61,12 @@ pub async fn install_crates(mut args: Args, jobserver_client: LazyJobserverClien

// Load metadata
let metadata = if !custom_install_path {
debug!("Reading binstall/crates-v1.json");
Some(Records::load()?)
let metadata_dir = cargo_roots.join("binstall");
fs::create_dir_all(&metadata_dir).map_err(BinstallError::Io)?;
let manifest_path = metadata_dir.join("crates-v1.json");

debug!("Reading {}", manifest_path.display());
Some(Records::load_from_path(&manifest_path)?)
} else {
None
};
Expand All @@ -71,7 +82,7 @@ pub async fn install_crates(mut args: Args, jobserver_client: LazyJobserverClien
.map_err(BinstallError::from)
.wrap_err("Creating a temporary directory failed.")?;

Ok((install_path, metadata, temp_dir))
Ok((install_path, cargo_roots, metadata, temp_dir))
})?;

// Remove installed crates
Expand Down Expand Up @@ -206,12 +217,11 @@ pub async fn install_crates(mut args: Args, jobserver_client: LazyJobserverClien

block_in_place(|| {
if let Some(mut records) = metadata {
// If using standardised install path,
// then create_dir_all(&install_path) would also
// create .cargo.
// The cargo manifest path is already created when loading
// metadata.

debug!("Writing .crates.toml");
CratesToml::append(metadata_vec.iter())?;
CratesToml::append_to_path(cargo_roots.join(".crates.toml"), metadata_vec.iter())?;

debug!("Writing binstall/crates-v1.json");
for metadata in metadata_vec {
Expand Down
41 changes: 29 additions & 12 deletions crates/bin/src/install_path.rs
Original file line number Diff line number Diff line change
@@ -1,31 +1,48 @@
use std::{
env::var_os,
path::{Path, PathBuf},
sync::Arc,
};

use binstalk::helpers::statics::cargo_home;
use binstalk::home::cargo_home;
use log::debug;

pub fn get_cargo_roots_path(cargo_roots: Option<PathBuf>) -> Option<PathBuf> {
if let Some(p) = cargo_roots {
return Some(p);
}

// Environmental variables
if let Some(p) = var_os("CARGO_INSTALL_ROOT") {
let p = PathBuf::from(p);
debug!("using CARGO_INSTALL_ROOT ({})", p.display());
return Some(p);
}

if let Ok(p) = cargo_home() {
debug!("using ({}) as cargo home", p.display());
Some(p)
} else {
None
}
}

/// Fetch install path from environment
/// roughly follows <https://doc.rust-lang.org/cargo/commands/cargo-install.html#description>
///
/// Return (install_path, is_custom_install_path)
pub fn get_install_path<P: AsRef<Path>>(install_path: Option<P>) -> (Option<Arc<Path>>, bool) {
pub fn get_install_path<P: AsRef<Path>>(
install_path: Option<P>,
cargo_roots: Option<P>,
) -> (Option<Arc<Path>>, bool) {
// Command line override first first
if let Some(p) = install_path {
return (Some(Arc::from(p.as_ref())), true);
}

// Environmental variables
if let Ok(p) = std::env::var("CARGO_INSTALL_ROOT") {
debug!("using CARGO_INSTALL_ROOT ({p})");
let b = PathBuf::from(p);
return (Some(Arc::from(b.join("bin"))), true);
}

if let Ok(p) = cargo_home() {
debug!("using ({}) as cargo home", p.display());
return (Some(p.join("bin").into()), false);
// Then cargo_roots
if let Some(p) = cargo_roots {
return (Some(Arc::from(p.as_ref().join("bin"))), false);
}

// Local executable dir if no cargo is found
Expand Down
16 changes: 1 addition & 15 deletions crates/binstalk/src/helpers/statics.rs
Original file line number Diff line number Diff line change
@@ -1,20 +1,6 @@
use std::{
io::Error,
ops::Deref,
path::{Path, PathBuf},
};

use once_cell::sync::{Lazy, OnceCell};
use once_cell::sync::Lazy;
use url::Url;

pub fn cargo_home() -> Result<&'static Path, Error> {
static CARGO_HOME: OnceCell<PathBuf> = OnceCell::new();

CARGO_HOME
.get_or_try_init(home::cargo_home)
.map(Deref::deref)
}

pub fn cratesio_url() -> &'static Url {
static CRATESIO: Lazy<Url, fn() -> Url> =
Lazy::new(|| Url::parse("https://github.com/rust-lang/crates.io-index").unwrap());
Expand Down
1 change: 1 addition & 0 deletions crates/binstalk/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,3 +8,4 @@ pub mod manifests;
pub mod ops;

pub use detect_targets::{get_desired_targets, DesiredTargets};
pub use home;
3 changes: 2 additions & 1 deletion crates/binstalk/src/manifests/binstall_crates_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,12 @@ use std::{
};

use fs_lock::FileLock;
use home::cargo_home;
use miette::Diagnostic;
use serde::Serialize;
use thiserror::Error;

use crate::{fs::create_if_not_exist, helpers::statics::cargo_home};
use crate::fs::create_if_not_exist;

use super::crate_info::CrateInfo;

Expand Down
3 changes: 2 additions & 1 deletion crates/binstalk/src/manifests/cargo_crates_v1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,12 @@ use std::{

use compact_str::CompactString;
use fs_lock::FileLock;
use home::cargo_home;
use miette::Diagnostic;
use serde::{Deserialize, Serialize};
use thiserror::Error;

use crate::{fs::create_if_not_exist, helpers::statics::cargo_home};
use crate::fs::create_if_not_exist;

use super::crate_info::CrateInfo;

Expand Down

0 comments on commit 934ccc2

Please sign in to comment.