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

Mark .cargo/git and .cargo/registry as cache dirs #10553

Merged
merged 9 commits into from
Apr 27, 2022
10 changes: 9 additions & 1 deletion crates/cargo-util/src/paths.rs
Original file line number Diff line number Diff line change
Expand Up @@ -632,7 +632,7 @@ pub fn create_dir_all_excluded_from_backups_atomic(p: impl AsRef<Path>) -> Resul
let parent = path.parent().unwrap();
let base = path.file_name().unwrap();
create_dir_all(parent)?;
// We do this in two steps (first create a temporary directory and exlucde
// We do this in two steps (first create a temporary directory and exclude
// it from backups, then rename it to the desired name. If we created the
// directory directly where it should be and then excluded it from backups
// we would risk a situation where cargo is interrupted right after the directory
Expand Down Expand Up @@ -660,6 +660,14 @@ pub fn create_dir_all_excluded_from_backups_atomic(p: impl AsRef<Path>) -> Resul
Ok(())
}

/// Mark an existing directory as excluded from backups and indexing.
pub fn exclude_from_backups_and_indexing(p: impl AsRef<Path>) -> Result<()> {
let path = p.as_ref();
exclude_from_backups(path);
exclude_from_content_indexing(path);
Ok(())
}

/// Marks the directory as excluded from archives/backups.
///
/// This is recommended to prevent derived/temporary files from bloating backups. There are two
Expand Down
17 changes: 15 additions & 2 deletions src/cargo/sources/git/source.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ use crate::util::errors::CargoResult;
use crate::util::hex::short_hash;
use crate::util::Config;
use anyhow::Context;
use cargo_util::paths::exclude_from_backups_and_indexing;
use log::trace;
use std::fmt::{self, Debug, Formatter};
use std::task::Poll;
Expand Down Expand Up @@ -122,8 +123,20 @@ impl<'cfg> Source for GitSource<'cfg> {
return Ok(());
}

let git_path = self.config.git_path();
let git_path = self.config.assert_package_cache_locked(&git_path);
let git_fs = self.config.git_path();
git_fs.create_dir()?;
let git_path = self.config.assert_package_cache_locked(&git_fs);

// Before getting a checkout, make sure that `<cargo_home>/git` is
// marked as excluded from indexing and backups. Older versions of Cargo
// didn't do this, so we do it here regardless of whether `<cargo_home>`
// exists.
//
// This does not use `create_dir_all_excluded_from_backups_atomic` for
// the same reason: we want to exclude it even if the directory already
// exists.
exclude_from_backups_and_indexing(&git_path)?;

let db_path = git_path.join("db").join(&self.ident);

let db = self.remote.db_at(&db_path).ok();
Expand Down
14 changes: 14 additions & 0 deletions src/cargo/sources/registry/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -167,6 +167,7 @@ use std::path::{Path, PathBuf};
use std::task::Poll;

use anyhow::Context as _;
use cargo_util::paths::exclude_from_backups_and_indexing;
use flate2::read::GzDecoder;
use log::debug;
use semver::Version;
Expand Down Expand Up @@ -552,6 +553,7 @@ impl<'cfg> RegistrySource<'cfg> {
} else {
Box::new(remote::RemoteRegistry::new(source_id, config, &name)) as Box<_>
};

Ok(RegistrySource::new(
source_id,
config,
Expand Down Expand Up @@ -812,6 +814,18 @@ impl<'cfg> Source for RegistrySource<'cfg> {
}

fn block_until_ready(&mut self) -> CargoResult<()> {
// Before starting to work on the registry, make sure that
// `<cargo_home>/registry` is marked as excluded from indexing and
// backups. Older versions of Cargo didn't do this, so we do it here
// regardless of whether `<cargo_home>` exists.
//
// This does not use `create_dir_all_excluded_from_backups_atomic` for
// the same reason: we want to exclude it even if the directory already
// exists.
let registry_base = self.config.registry_base_path();
registry_base.create_dir()?;
exclude_from_backups_and_indexing(&registry_base.into_path_unlocked())?;

self.ops.block_until_ready()
}
}
Expand Down
11 changes: 8 additions & 3 deletions src/cargo/util/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -315,19 +315,24 @@ impl Config {
self.home_path.join("git")
}

/// Gets the Cargo base directory for all registry information (`<cargo_home>/registry`).
pub fn registry_base_path(&self) -> Filesystem {
self.home_path.join("registry")
}

/// Gets the Cargo registry index directory (`<cargo_home>/registry/index`).
pub fn registry_index_path(&self) -> Filesystem {
self.home_path.join("registry").join("index")
self.registry_base_path().join("index")
}

/// Gets the Cargo registry cache directory (`<cargo_home>/registry/path`).
pub fn registry_cache_path(&self) -> Filesystem {
self.home_path.join("registry").join("cache")
self.registry_base_path().join("cache")
}

/// Gets the Cargo registry source directory (`<cargo_home>/registry/src`).
pub fn registry_source_path(&self) -> Filesystem {
self.home_path.join("registry").join("src")
self.registry_base_path().join("src")
}

/// Gets the default Cargo registry.
Expand Down
3 changes: 3 additions & 0 deletions tests/testsuite/git.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2247,6 +2247,8 @@ fn add_a_git_dep() {

p.cargo("build").run();

assert!(paths::home().join(".cargo/git/CACHEDIR.TAG").is_file());

p.change_file(
"a/Cargo.toml",
&format!(
Expand Down Expand Up @@ -2580,6 +2582,7 @@ fn use_the_cli() {
";

project.cargo("build -v").with_stderr(stderr).run();
assert!(paths::home().join(".cargo/git/CACHEDIR.TAG").is_file());
}

#[cargo_test]
Expand Down
16 changes: 16 additions & 0 deletions tests/testsuite/registry.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,8 @@ fn simple(cargo: fn(&Project, &str) -> Execs) {

cargo(&p, "clean").run();

assert!(paths::home().join(".cargo/registry/CACHEDIR.TAG").is_file());

// Don't download a second time
cargo(&p, "build")
.with_stderr(
Expand Down Expand Up @@ -150,6 +152,8 @@ fn deps(cargo: fn(&Project, &str) -> Execs) {
",
)
.run();

assert!(paths::home().join(".cargo/registry/CACHEDIR.TAG").is_file());
}

#[cargo_test]
Expand Down Expand Up @@ -1231,6 +1235,13 @@ fn updating_a_dep(cargo: fn(&Project, &str) -> Execs) {
",
)
.run();
assert!(paths::home().join(".cargo/registry/CACHEDIR.TAG").is_file());

// Now delete the CACHEDIR.TAG file: this is the situation we'll be in after
// upgrading from a version of Cargo that doesn't mark this directory, to one that
// does. It should be recreated.
fs::remove_file(paths::home().join(".cargo/registry/CACHEDIR.TAG"))
.expect("remove CACHEDIR.TAG");

p.change_file(
"a/Cargo.toml",
Expand Down Expand Up @@ -1260,6 +1271,11 @@ fn updating_a_dep(cargo: fn(&Project, &str) -> Execs) {
",
)
.run();

assert!(
paths::home().join(".cargo/registry/CACHEDIR.TAG").is_file(),
"CACHEDIR.TAG recreated in existing registry"
);
}

#[cargo_test]
Expand Down