Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support platform-defined standard directories #5183

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ crates-io = { path = "src/crates-io", version = "0.16" }
crossbeam = "0.3"
crypto-hash = "0.3"
curl = "0.4.6"
directories = "0.8.5"
env_logger = "0.5"
failure = "0.1.1"
filetime = "0.1"
Expand Down
1 change: 1 addition & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,5 @@ clone_depth: 1
build: false

test_script:
- set RUST_BACKTRACE=1
- cargo test
2 changes: 1 addition & 1 deletion src/bin/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ fn is_executable<P: AsRef<Path>>(path: P) -> bool {
}

fn search_directories(config: &Config) -> Vec<PathBuf> {
let mut dirs = vec![config.home().clone().into_path_unlocked().join("bin")];
let mut dirs = vec![config.bin_path()];
if let Some(val) = env::var_os("PATH") {
dirs.extend(env::split_paths(&val));
}
Expand Down
16 changes: 16 additions & 0 deletions src/bin/commands/dirs.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
use command_prelude::*;

pub fn cli() -> App {
subcommand("dirs")
.about("Display directories (cache, config, ...) used by cargo")
.after_help("\
")
}

pub fn exec(config: &mut Config, _args: &ArgMatches) -> CliResult {
println!("CARGO_CACHE_DIR: {:?}", config.cache_path().into_path_unlocked());
println!("CARGO_CONFIG_DIR: {:?}", config.config_path().into_path_unlocked());
println!("CARGO_DATA_DIR: {:?}", config.data_path());
println!("CARGO_BIN_DIR: {:?}", config.bin_path());
Ok(())
}
3 changes: 3 additions & 0 deletions src/bin/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ pub fn builtin() -> Vec<App> {
build::cli(),
check::cli(),
clean::cli(),
dirs::cli(),
doc::cli(),
fetch::cli(),
generate_lockfile::cli(),
Expand Down Expand Up @@ -40,6 +41,7 @@ pub fn builtin_exec(cmd: &str) -> Option<fn(&mut Config, &ArgMatches) -> CliResu
"build" => build::exec,
"check" => check::exec,
"clean" => clean::exec,
"dirs" => dirs::exec,
"doc" => doc::exec,
"fetch" => fetch::exec,
"generate-lockfile" => generate_lockfile::exec,
Expand Down Expand Up @@ -74,6 +76,7 @@ pub mod bench;
pub mod build;
pub mod check;
pub mod clean;
pub mod dirs;
pub mod doc;
pub mod fetch;
pub mod generate_lockfile;
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/core/workspace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ impl<'cfg> Workspace<'cfg> {
// `CARGO_HOME` pointing inside of the workspace root or in the
// current project, but we don't want to mistakenly try to put
// crates.io crates into the workspace by accident.
if self.config.home() == path {
if &self.config.cache_path() == path {
break;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/cargo/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ extern crate core_foundation;
extern crate crates_io as registry;
extern crate crossbeam;
extern crate curl;
extern crate directories;
#[macro_use]
extern crate failure;
extern crate filetime;
Expand Down
64 changes: 46 additions & 18 deletions src/cargo/ops/cargo_install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,27 @@ impl Drop for Transaction {
}
}

#[derive(Clone)]
struct CargoInstallDirs {
config_dir: PathBuf,
bin_dir: PathBuf,
}

impl CargoInstallDirs {
fn from_root(root: PathBuf) -> CargoInstallDirs {
CargoInstallDirs {
bin_dir: root.join("bin"),
config_dir: root,
}
}
fn from_config(config: &Config) -> CargoInstallDirs {
CargoInstallDirs {
bin_dir: config.bin_path(),
config_dir: config.config_path().into_path_unlocked(),
}
}
}

pub fn install(
root: Option<&str>,
krates: Vec<&str>,
Expand All @@ -61,7 +82,7 @@ pub fn install(
opts: &ops::CompileOptions,
force: bool,
) -> CargoResult<()> {
let root = resolve_root(root, opts.config)?;
let root = resolve_install_dirs(root, opts.config)?;
let map = SourceConfigMap::new(opts.config)?;

let (installed_anything, scheduled_error) = if krates.len() <= 1 {
Expand Down Expand Up @@ -122,7 +143,7 @@ pub fn install(
if installed_anything {
// Print a warning that if this directory isn't in PATH that they won't be
// able to run these commands.
let dst = metadata(opts.config, &root)?.parent().join("bin");
let dst = root.bin_dir;
let path = env::var_os("PATH").unwrap_or_default();
for path in env::split_paths(&path) {
if path == dst {
Expand All @@ -145,7 +166,7 @@ pub fn install(
}

fn install_one(
root: &Filesystem,
dirs: &CargoInstallDirs,
map: &SourceConfigMap,
krate: Option<&str>,
source_id: &SourceId,
Expand Down Expand Up @@ -235,9 +256,9 @@ fn install_one(
// We have to check this again afterwards, but may as well avoid building
// anything if we're gonna throw it away anyway.
{
let metadata = metadata(config, root)?;
let metadata = metadata(config, &Filesystem::new(dirs.config_dir.clone()))?;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It feels like metadata could perhaps be a method of CargoInstallDirs?

let list = read_crate_list(&metadata)?;
let dst = metadata.parent().join("bin");
let dst = config.bin_path();
check_overwrites(&dst, pkg, &opts.filter, &list, force)?;
}

Expand Down Expand Up @@ -274,7 +295,7 @@ fn install_one(
);
}

let metadata = metadata(config, root)?;
let metadata = metadata(config, &Filesystem::new(dirs.config_dir.clone()))?;
let mut list = read_crate_list(&metadata)?;
let dst = metadata.parent().join("bin");
let duplicates = check_overwrites(&dst, pkg, &opts.filter, &list, force)?;
Expand Down Expand Up @@ -655,8 +676,8 @@ fn write_crate_list(file: &FileLock, listing: CrateListingV1) -> CargoResult<()>
}

pub fn install_list(dst: Option<&str>, config: &Config) -> CargoResult<()> {
let dst = resolve_root(dst, config)?;
let dst = metadata(config, &dst)?;
let dst = resolve_install_dirs(dst, config)?;
let dst = metadata(config, &Filesystem::new(dst.config_dir))?;
let list = read_crate_list(&dst)?;
for (k, v) in list.v1.iter() {
println!("{}:", k);
Expand All @@ -677,7 +698,7 @@ pub fn uninstall(
bail!("A binary can only be associated with a single installed package, specifying multiple specs with --bin is redundant.");
}

let root = resolve_root(root, config)?;
let root = resolve_install_dirs(root, config)?;
let scheduled_error = if specs.len() == 1 {
uninstall_one(&root, specs[0], bins, config)?;
false
Expand Down Expand Up @@ -723,13 +744,13 @@ pub fn uninstall(
Ok(())
}

pub fn uninstall_one(
root: &Filesystem,
fn uninstall_one(
dirs: &CargoInstallDirs,
spec: &str,
bins: &[String],
config: &Config,
) -> CargoResult<()> {
let crate_metadata = metadata(config, root)?;
let crate_metadata = metadata(config, &Filesystem::new(dirs.config_dir.clone()))?;
let mut metadata = read_crate_list(&crate_metadata)?;
let mut to_remove = Vec::new();
{
Expand All @@ -738,7 +759,7 @@ pub fn uninstall_one(
Entry::Occupied(e) => e,
Entry::Vacant(..) => panic!("entry not found: {}", result),
};
let dst = crate_metadata.parent().join("bin");
let dst = &dirs.bin_dir;
for bin in installed.get() {
let bin = dst.join(bin);
if fs::metadata(&bin).is_err() {
Expand Down Expand Up @@ -787,15 +808,22 @@ pub fn uninstall_one(
Ok(())
}

/// Return a file lock for the .crates.toml file at the given root.
/// The config argument is only used for logging to the shell.
fn metadata(config: &Config, root: &Filesystem) -> CargoResult<FileLock> {
root.open_rw(Path::new(".crates.toml"), config, "crate metadata")
}

fn resolve_root(flag: Option<&str>, config: &Config) -> CargoResult<Filesystem> {
// Determine cargo directories by first checking whether an argument was given
// on the command line, if not checking whether the environment variable
// CARGO_INSTALL_ROOT is set, and if not using the paths of the configuration.
fn resolve_install_dirs(
root: Option<&str>,
config: &Config,
) -> CargoResult<CargoInstallDirs> {
let config_root = config.get_path("install.root")?;
Ok(flag.map(PathBuf::from)
Ok(root.map(PathBuf::from)
.or_else(|| env::var_os("CARGO_INSTALL_ROOT").map(PathBuf::from))
.or_else(move || config_root.map(|v| v.val))
.map(Filesystem::new)
.unwrap_or_else(|| config.home().clone()))
.or_else(move || config_root.map(|v| v.val)).map(CargoInstallDirs::from_root)
.unwrap_or_else(|| CargoInstallDirs::from_config(config)))
}
Loading