Stabilize automatic garbage collection.

This commit is contained in:
Eric Huss 2024-07-22 12:51:27 -07:00
parent 7220445a9d
commit 659e27413c
5 changed files with 218 additions and 183 deletions

View File

@ -49,9 +49,6 @@ const DEFAULT_AUTO_FREQUENCY: &str = "1 day";
/// It should be cheap to call this multiple times (subsequent calls are
/// ignored), but try not to abuse that.
pub fn auto_gc(gctx: &GlobalContext) {
if !gctx.cli_unstable().gc {
return;
}
if !gctx.network_allowed() {
// As a conservative choice, auto-gc is disabled when offline. If the
// user is indefinitely offline, we don't want to delete things they
@ -174,49 +171,74 @@ impl GcOpts {
let config = gctx
.get::<Option<GlobalCleanConfig>>("cache.global-clean")?
.unwrap_or_default();
self.update_for_auto_gc_config(&config)
self.update_for_auto_gc_config(&config, gctx.cli_unstable().gc)
}
fn update_for_auto_gc_config(&mut self, config: &GlobalCleanConfig) -> CargoResult<()> {
fn update_for_auto_gc_config(
&mut self,
config: &GlobalCleanConfig,
unstable_allowed: bool,
) -> CargoResult<()> {
macro_rules! config_default {
($config:expr, $field:ident, $default:expr, $unstable_allowed:expr) => {
if !unstable_allowed {
// These config options require -Zgc
$default
} else {
$config.$field.as_deref().unwrap_or($default)
}
};
}
self.max_src_age = newer_time_span_for_config(
self.max_src_age,
"cache.global-clean.max-src-age",
config
.max_src_age
.as_deref()
.unwrap_or(DEFAULT_MAX_AGE_EXTRACTED),
"gc.auto.max-src-age",
config_default!(
config,
max_src_age,
DEFAULT_MAX_AGE_EXTRACTED,
unstable_allowed
),
)?;
self.max_crate_age = newer_time_span_for_config(
self.max_crate_age,
"cache.global-clean.max-crate-age",
config
.max_crate_age
.as_deref()
.unwrap_or(DEFAULT_MAX_AGE_DOWNLOADED),
"gc.auto.max-crate-age",
config_default!(
config,
max_crate_age,
DEFAULT_MAX_AGE_DOWNLOADED,
unstable_allowed
),
)?;
self.max_index_age = newer_time_span_for_config(
self.max_index_age,
"cache.global-clean.max-index-age",
config
.max_index_age
.as_deref()
.unwrap_or(DEFAULT_MAX_AGE_DOWNLOADED),
"gc.auto.max-index-age",
config_default!(
config,
max_index_age,
DEFAULT_MAX_AGE_DOWNLOADED,
unstable_allowed
),
)?;
self.max_git_co_age = newer_time_span_for_config(
self.max_git_co_age,
"cache.global-clean.max-git-co-age",
config
.max_git_co_age
.as_deref()
.unwrap_or(DEFAULT_MAX_AGE_EXTRACTED),
"gc.auto.max-git-co-age",
config_default!(
config,
max_git_co_age,
DEFAULT_MAX_AGE_EXTRACTED,
unstable_allowed
),
)?;
self.max_git_db_age = newer_time_span_for_config(
self.max_git_db_age,
"cache.global-clean.max-git-db-age",
config
.max_git_db_age
.as_deref()
.unwrap_or(DEFAULT_MAX_AGE_DOWNLOADED),
"gc.auto.max-git-db-age",
config_default!(
config,
max_git_db_age,
DEFAULT_MAX_AGE_DOWNLOADED,
unstable_allowed
),
)?;
Ok(())
}
@ -255,9 +277,6 @@ impl<'a, 'gctx> Gc<'a, 'gctx> {
/// This returns immediately without doing work if garbage collection has
/// been performed recently (since `cache.auto-clean-frequency`).
fn auto(&mut self, clean_ctx: &mut CleanContext<'gctx>) -> CargoResult<()> {
if !self.gctx.cli_unstable().gc {
return Ok(());
}
let freq = self
.gctx
.get::<Option<String>>("cache.auto-clean-frequency")?;
@ -274,7 +293,7 @@ impl<'a, 'gctx> Gc<'a, 'gctx> {
.unwrap_or_default();
let mut gc_opts = GcOpts::default();
gc_opts.update_for_auto_gc_config(&config)?;
gc_opts.update_for_auto_gc_config(&config, self.gctx.cli_unstable().gc)?;
self.gc(clean_ctx, &gc_opts)?;
if !clean_ctx.dry_run {
self.global_cache_tracker.set_last_auto_gc()?;

View File

@ -95,6 +95,9 @@ ENV_VAR_NAME_3 = { value = "relative/path", relative = true }
[future-incompat-report]
frequency = 'always' # when to display a notification about a future incompat report
[cache]
auto-clean-frequency = "1 day" # How often to perform automatic cache cleaning
[cargo-new]
vcs = "none" # VCS to use ('git', 'hg', 'pijul', 'fossil', 'none')
@ -664,6 +667,41 @@ Controls how often we display a notification to the terminal when a future incom
* `always` (default): Always display a notification when a command (e.g. `cargo build`) produces a future incompat report
* `never`: Never display a notification
### `[cache]`
The `[cache]` table defines settings for cargo's caches.
#### Global caches
When running `cargo` commands, Cargo will automatically track which files you are using within the global cache.
Periodically, Cargo will delete files that have not been used for some period of time.
It will delete files that have to be downloaded from the network if they have not been used in 3 months. Files that can be generated without network access will be deleted if they have not been used in 1 month.
The automatic deletion of files only occurs when running commands that are already doing a significant amount of work, such as all of the build commands (`cargo build`, `cargo test`, `cargo check`, etc.), and `cargo fetch`.
Automatic deletion is disabled if cargo is offline such as with `--offline` or `--frozen` to avoid deleting artifacts that may need to be used if you are offline for a long period of time.
> **Note**: This tracking is currently only implemented for the global cache in Cargo's home directory.
> This includes registry indexes and source files downloaded from registries and git dependencies.
> Support for tracking build artifacts is not yet implemented, and tracked in [cargo#13136](https://github.com/rust-lang/cargo/issues/13136).
>
> Additionally, there is an unstable feature to support *manually* triggering cache cleaning, and to further customize the configuration options.
> See the [Unstable chapter](unstable.md#gc) for more information.
#### `cache.auto-clean-frequency`
* Type: string
* Default: `"1 day"`
* Environment: `CARGO_CACHE_AUTO_CLEAN_FREQUENCY`
This option defines how often Cargo will automatically delete unused files in the global cache.
This does *not* define how old the files must be, those thresholds are described [above](#global-caches).
It supports the following settings:
* `"never"` --- Never deletes old files.
* `"always"` --- Checks to delete old files every time Cargo runs.
* An integer followed by "seconds", "minutes", "hours", "days", "weeks", or "months" --- Checks to delete old files at most the given time frame.
### `[http]`
The `[http]` table defines settings for HTTP behavior. This includes fetching

View File

@ -99,6 +99,7 @@ In summary, the supported environment variables are:
* `CARGO_BUILD_RUSTDOCFLAGS` --- Extra `rustdoc` flags, see [`build.rustdocflags`].
* `CARGO_BUILD_INCREMENTAL` --- Incremental compilation, see [`build.incremental`].
* `CARGO_BUILD_DEP_INFO_BASEDIR` --- Dep-info relative directory, see [`build.dep-info-basedir`].
* `CARGO_CACHE_AUTO_CLEAN_FREQUENCY` --- Configures how often automatic cache cleaning runs, see [`cache.auto-clean-frequency`].
* `CARGO_CARGO_NEW_VCS` --- The default source control system with [`cargo new`], see [`cargo-new.vcs`].
* `CARGO_FUTURE_INCOMPAT_REPORT_FREQUENCY` --- How often we should generate a future incompat report notification, see [`future-incompat-report.frequency`].
* `CARGO_HTTP_DEBUG` --- Enables HTTP debugging, see [`http.debug`].
@ -163,6 +164,7 @@ In summary, the supported environment variables are:
[`build.incremental`]: config.md#buildincremental
[`build.dep-info-basedir`]: config.md#builddep-info-basedir
[`doc.browser`]: config.md#docbrowser
[`cache.auto-clean-frequency`]: config.md#cacheauto-clean-frequency
[`cargo-new.name`]: config.md#cargo-newname
[`cargo-new.email`]: config.md#cargo-newemail
[`cargo-new.vcs`]: config.md#cargo-newvcs

View File

@ -1588,37 +1588,16 @@ This will not affect any hard-coded paths in the source code, such as in strings
* Tracking Issue: [#12633](https://github.com/rust-lang/cargo/issues/12633)
The `-Zgc` flag enables garbage-collection within cargo's global cache within the cargo home directory.
This includes downloaded dependencies such as compressed `.crate` files, extracted `src` directories, registry index caches, and git dependencies.
When `-Zgc` is present, cargo will track the last time any index and dependency was used,
and then uses those timestamps to manually or automatically delete cache entries that have not been used for a while.
```sh
cargo build -Zgc
```
### Automatic garbage collection
Automatic deletion happens on commands that are already doing a significant amount of work,
such as all of the build commands (`cargo build`, `cargo test`, `cargo check`, etc.), and `cargo fetch`.
The deletion happens just after resolution and packages have been downloaded.
Automatic deletion is only done once per day (see `cache.auto-clean-frequency` to configure).
Automatic deletion is disabled if cargo is offline such as with `--offline` or `--frozen` to avoid deleting artifacts that may need to be used if you are offline for a long period of time.
The `-Zgc` flag is used to enable certain features related to garbage-collection of cargo's global cache within the cargo home directory.
#### Automatic gc configuration
The automatic gc behavior can be specified via a cargo configuration setting.
The `-Zgc` flag will enable Cargo to read extra configuration options related to garbage collection.
The settings available are:
```toml
# Example config.toml file.
# This table defines settings for cargo's caches.
[cache]
# The maximum frequency that automatic cleaning of the cache happens.
# Can be "never" to disable, or "always" to run on every command.
auto-clean-frequency = "1 day"
# Sub-table for defining specific settings for cleaning the global cache.
[cache.global-clean]
# Anything older than this duration will be deleted in the source cache.
@ -1633,9 +1612,13 @@ max-git-co-age = "1 month"
max-git-db-age = "3 months"
```
Note that the [`cache.auto-clean-frequency`] option was stabilized in Rust 1.88.
[`cache.auto-clean-frequency`]: config.md#cacheauto-clean-frequency
### Manual garbage collection with `cargo clean`
Manual deletion can be done with the `cargo clean gc` command.
Manual deletion can be done with the `cargo clean gc -Zgc` command.
Deletion of cache contents can be performed by passing one of the cache options:
- `--max-src-age=DURATION` --- Deletes source cache files that have not been used since the given age.
@ -1654,9 +1637,9 @@ A DURATION is specified in the form "N seconds/minutes/days/weeks/months" where
A SIZE is specified in the form "N *suffix*" where *suffix* is B, kB, MB, GB, kiB, MiB, or GiB, and N is an integer or floating point number. If no suffix is specified, the number is the number of bytes.
```sh
cargo clean gc
cargo clean gc --max-download-age=1week
cargo clean gc --max-git-size=0 --max-download-size=100MB
cargo clean gc -Zgc
cargo clean gc -Zgc --max-download-age=1week
cargo clean gc -Zgc --max-git-size=0 --max-download-size=100MB
```
## open-namespaces
@ -2166,3 +2149,7 @@ The 2024 edition has been stabilized in the 1.85 release.
See the [`edition` field](manifest.md#the-edition-field) for more information on setting the edition.
See [`cargo fix --edition`](../commands/cargo-fix.md) and [The Edition Guide](../../edition-guide/index.html) for more information on migrating existing projects.
## Automatic garbage collection
Support for automatically deleting old files was stabilized in Rust 1.88.
More information can be found in the [config chapter](config.md#cache).

View File

@ -187,25 +187,6 @@ fn rustup_cargo() -> Execs {
e
}
#[cargo_test]
fn auto_gc_gated() {
// Requires -Zgc to run auto-gc.
let p = basic_foo_bar_project();
p.cargo("check")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
// Check that it created a database.
let gctx = GlobalContextBuilder::new().build();
assert!(GlobalCacheTracker::db_path(&gctx)
.into_path_unlocked()
.exists());
assert_eq!(get_index_names().len(), 1);
// Again in the future, shouldn't auto-gc.
p.cargo("check").run();
assert_eq!(get_index_names().len(), 1);
}
#[cargo_test]
fn clean_gc_gated() {
cargo_process("clean gc")
@ -287,8 +268,7 @@ fn auto_gc_defaults() {
.file("src/lib.rs", "")
.build();
// Populate the last-use data.
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("check")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
assert_eq!(get_registry_names("src"), ["new-1.0.0", "old-1.0.0"]);
@ -311,8 +291,7 @@ fn auto_gc_defaults() {
new = "1.0"
"#,
);
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("check")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(2))
.run();
assert_eq!(get_registry_names("src"), ["new-1.0.0"]);
@ -322,13 +301,78 @@ fn auto_gc_defaults() {
);
// Run again after the .crate should have aged out.
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.run();
p.cargo("check").run();
assert_eq!(get_registry_names("src"), ["new-1.0.0"]);
assert_eq!(get_registry_names("cache"), ["new-1.0.0.crate"]);
}
#[cargo_test]
fn auto_gc_config_gated() {
// gc.auto config options should be ignored without -Zgc
Package::new("old", "1.0.0").publish();
Package::new("new", "1.0.0").publish();
let p = project()
.file(
".cargo/config.toml",
r#"
[gc.auto]
frequency = "always"
max-src-age = "1 day"
max-crate-age = "3 days"
max-index-age = "3 days"
max-git-co-age = "1 day"
max-git-db-age = "3 days"
"#,
)
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = "2015"
[dependencies]
old = "1.0"
new = "1.0"
"#,
)
.file("src/lib.rs", "")
.build();
// Populate the last-use data.
p.cargo("check")
.env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(4))
.run();
assert_eq!(get_registry_names("src"), ["new-1.0.0", "old-1.0.0"]);
assert_eq!(
get_registry_names("cache"),
["new-1.0.0.crate", "old-1.0.0.crate"]
);
// Run again with just one package. Without -Zgc, it should use the
// defaults and ignore the config. Nothing should get deleted since the
// defaults are much greater than 4 days.
p.change_file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.1.0"
edition = "2015"
[dependencies]
new = "1.0"
"#,
);
p.cargo("check").run();
assert_eq!(get_registry_names("src"), ["new-1.0.0", "old-1.0.0"]);
assert_eq!(
get_registry_names("cache"),
["new-1.0.0.crate", "old-1.0.0.crate"]
);
}
#[cargo_test]
fn auto_gc_config() {
// Can configure auto gc settings.
@ -364,8 +408,7 @@ fn auto_gc_config() {
.file("src/lib.rs", "")
.build();
// Populate the last-use data.
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("check")
.env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(4))
.run();
assert_eq!(get_registry_names("src"), ["new-1.0.0", "old-1.0.0"]);
@ -418,8 +461,7 @@ fn frequency() {
"#,
);
// Populate data in the past.
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("check")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
assert_eq!(get_index_names().len(), 1);
@ -429,17 +471,14 @@ fn frequency() {
p.change_file("Cargo.toml", &basic_manifest("foo", "0.2.0"));
// Try after the default expiration time, with "never" it shouldn't gc.
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.run();
p.cargo("check").run();
assert_eq!(get_index_names().len(), 1);
assert_eq!(get_registry_names("src"), ["bar-1.0.0"]);
assert_eq!(get_registry_names("cache"), ["bar-1.0.0.crate"]);
// Try again with a setting that allows it to run.
p.cargo("check -Zgc")
p.cargo("check")
.env("CARGO_CACHE_AUTO_CLEAN_FREQUENCY", "1 day")
.masquerade_as_nightly_cargo(&["gc"])
.run();
assert_eq!(get_index_names().len(), 0);
assert_eq!(get_registry_names("src").len(), 0);
@ -450,8 +489,7 @@ fn frequency() {
fn auto_gc_index() {
// Deletes the index if it hasn't been used in a while.
let p = basic_foo_bar_project();
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("check")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
assert_eq!(get_index_names().len(), 1);
@ -466,16 +504,13 @@ fn auto_gc_index() {
edition = "2015"
"#,
);
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("check")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(2))
.run();
assert_eq!(get_index_names().len(), 1);
// After it expires, it should be deleted.
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.run();
p.cargo("check").run();
assert_eq!(get_index_names().len(), 0);
}
@ -514,8 +549,7 @@ fn auto_gc_git() {
)
.file("src/lib.rs", "")
.build();
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("check")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(6))
.run();
let db_names = get_git_db_names();
@ -530,8 +564,7 @@ fn auto_gc_git() {
git_project.change_file("src/lib.rs", "// modified");
git::add(&git_repo);
git::commit(&git_repo);
p.cargo("update -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("update")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(6))
.run();
assert_eq!(get_git_db_names().len(), 1);
@ -541,8 +574,7 @@ fn auto_gc_git() {
assert_eq!(get_git_checkout_names(&db_names[0]), both);
// In the future, using the second checkout should delete the first.
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("check")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
assert_eq!(get_git_db_names().len(), 1);
@ -553,9 +585,7 @@ fn auto_gc_git() {
// After three months, the db should get deleted.
p.change_file("Cargo.toml", &basic_manifest("foo", "0.2.0"));
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.run();
p.cargo("check").run();
assert_eq!(get_git_db_names().len(), 0);
assert_eq!(get_git_checkout_names(&db_names[0]).len(), 0);
}
@ -588,8 +618,6 @@ fn auto_gc_various_commands() {
.build();
// Populate the last-use data.
p.cargo(cmd)
.arg("-Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
let gctx = GlobalContextBuilder::new().build();
@ -607,10 +635,7 @@ fn auto_gc_various_commands() {
// After everything is aged out, it should all be deleted.
p.change_file("Cargo.toml", &basic_manifest("foo", "0.2.0"));
p.cargo(cmd)
.arg("-Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.run();
p.cargo(cmd).run();
let lock = gctx
.acquire_package_cache_lock(CacheLockMode::MutateExclusive)
.unwrap();
@ -673,10 +698,7 @@ fn updates_last_use_various_commands() {
.file("src/lib.rs", "")
.build();
// Populate the last-use data.
p.cargo(cmd)
.arg("-Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.run();
p.cargo(cmd).run();
let gctx = GlobalContextBuilder::new().build();
let lock = gctx
.acquire_package_cache_lock(CacheLockMode::MutateExclusive)
@ -723,8 +745,7 @@ fn both_git_and_http_index_cleans() {
.file("src/lib.rs", "")
.build();
p.cargo("update -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("update")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
let gctx = GlobalContextBuilder::new().build();
@ -756,8 +777,7 @@ fn clean_gc_dry_run() {
// Basic `clean --gc --dry-run` test.
let p = basic_foo_bar_project();
// Populate the last-use data.
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("fetch")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
@ -810,8 +830,7 @@ fn clean_default_gc() {
// `clean gc` without options should also gc
let p = basic_foo_bar_project();
// Populate the last-use data.
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("fetch")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
p.cargo("clean gc -v -Zgc")
@ -855,9 +874,7 @@ fn tracks_sizes() {
)
.file("src/lib.rs", "")
.build();
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.run();
p.cargo("fetch").run();
// Check that the crate sizes are the same as on disk.
let gctx = GlobalContextBuilder::new().build();
@ -1085,9 +1102,7 @@ fn max_size_untracked_src_from_use() {
let (gctx, p) = max_size_untracked_prepare();
// Run a command that will update the db with an unknown src size.
p.cargo("tree -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.run();
p.cargo("tree").run();
// Check that it is None.
let lock = gctx
.acquire_package_cache_lock(CacheLockMode::MutateExclusive)
@ -1241,8 +1256,7 @@ fn package_cache_lock_during_build() {
// Start a build that will pause once the build starts.
let mut foo_child = p_foo
.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.cargo("check")
.build_command()
.stdout(Stdio::piped())
.stderr(Stdio::piped())
@ -1257,8 +1271,7 @@ fn package_cache_lock_during_build() {
//
// Also verify that auto-gc gets disabled.
p_foo2
.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.cargo("check")
.env("CARGO_CACHE_AUTO_CLEAN_FREQUENCY", "always")
.env("CARGO_LOG", "gc=debug")
.with_stderr_data(str![[r#"
@ -1311,9 +1324,7 @@ fn read_only_locking_auto_gc() {
// Tests the behavior for auto-gc on a read-only directory.
let p = basic_foo_bar_project();
// Populate cache.
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.run();
p.cargo("fetch").run();
let cargo_home = paths::home().join(".cargo");
let mut perms = std::fs::metadata(&cargo_home).unwrap().permissions();
// Test when it can't update auto-gc db.
@ -1353,8 +1364,7 @@ fn read_only_locking_auto_gc() {
fn delete_index_also_deletes_crates() {
// Checks that when an index is delete that src and cache directories also get deleted.
let p = basic_foo_bar_project();
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("fetch")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
@ -1397,9 +1407,7 @@ fn clean_syncs_missing_files() {
)
.file("src/lib.rs", "")
.build();
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.run();
p.cargo("fetch").run();
// Verify things are tracked.
let gctx = GlobalContextBuilder::new().build();
@ -1445,15 +1453,13 @@ fn clean_syncs_missing_files() {
fn offline_doesnt_auto_gc() {
// When running offline, auto-gc shouldn't run.
let p = basic_foo_bar_project();
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("fetch")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
// Remove the dependency.
p.change_file("Cargo.toml", &basic_manifest("foo", "0.1.0"));
// Run offline, make sure it doesn't delete anything
p.cargo("check --offline -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("check --offline")
.with_stderr_data(str![[r#"
[CHECKING] foo v0.1.0 ([ROOT]/foo)
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
@ -1463,8 +1469,7 @@ fn offline_doesnt_auto_gc() {
assert_eq!(get_registry_names("src"), ["bar-1.0.0"]);
assert_eq!(get_registry_names("cache"), ["bar-1.0.0.crate"]);
// Run online, make sure auto-gc runs.
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("check")
.with_stderr_data(str![[r#"
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s
@ -1479,8 +1484,7 @@ fn can_handle_future_schema() -> anyhow::Result<()> {
// It should work when a future version of cargo has made schema changes
// to the database.
let p = basic_foo_bar_project();
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("fetch")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
// Modify the schema to pretend this is done by a future version of cargo.
@ -1531,8 +1535,7 @@ fn clean_max_git_age() {
.file("src/lib.rs", "")
.build();
// Populate last-use tracking.
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("fetch")
.env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(4))
.run();
// Update git_a to create a separate checkout.
@ -1540,8 +1543,7 @@ fn clean_max_git_age() {
git::add(&git_a_repo);
git::commit(&git_a_repo);
// Update last-use tracking, where the first git checkout will stay "old".
p.cargo("update -p git_a -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("update -p git_a")
.env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(2))
.with_stderr_data(str![[r#"
[UPDATING] git repository `[ROOTURL]/git_a`
@ -1612,14 +1614,12 @@ fn clean_max_src_crate_age() {
// --max-src-age and --max-crate-age flags
let p = basic_foo_bar_project();
// Populate last-use tracking.
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("fetch")
.env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(4))
.run();
// Update bar to create a separate copy with a different timestamp.
Package::new("bar", "1.0.1").publish();
p.cargo("update -p bar -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("update -p bar")
.env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(2))
.with_stderr_data(str![[r#"
[UPDATING] `dummy-registry` index
@ -1628,8 +1628,7 @@ fn clean_max_src_crate_age() {
"#]])
.run();
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("fetch")
.env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(2))
.with_stderr_data(str![[r#"
[DOWNLOADING] crates ...
@ -1718,8 +1717,7 @@ fn clean_max_git_size() {
.file("src/lib.rs", "")
.build();
// Fetch and populate db.
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("fetch")
.env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(3))
.run();
@ -1736,8 +1734,7 @@ fn clean_max_git_size() {
git_project.change_file("src/lib.rs", "// modified");
git::add(&git_repo);
git::commit(&git_repo);
p.cargo("update -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("update")
// Use a different time so that the first checkout timestamp is less
// than the second.
.env("__CARGO_TEST_LAST_USE_NOW", days_ago_unix(2))
@ -1860,9 +1857,7 @@ fn clean_max_git_size_deletes_co_from_db() {
fn handles_missing_index() {
// Checks behavior when index is missing.
let p = basic_foo_bar_project();
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.run();
p.cargo("fetch").run();
paths::home().join(".cargo/registry/index").rm_rf();
cargo_process("clean gc -v --max-download-size=0 -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
@ -1903,9 +1898,7 @@ fn handles_missing_git_db() {
)
.file("src/lib.rs", "")
.build();
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.run();
p.cargo("fetch").run();
paths::home().join(".cargo/git/db").rm_rf();
cargo_process("clean gc -v --max-git-size=0 -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
@ -1922,8 +1915,7 @@ fn clean_gc_quiet_is_quiet() {
// Checks that --quiet works with `cargo clean gc`, since there was a
// subtle issue with how the flag is defined as a global flag.
let p = basic_foo_bar_project();
p.cargo("fetch -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("fetch")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
p.cargo("clean gc --quiet -Zgc --dry-run")
@ -1969,8 +1961,7 @@ fn compatible_with_older_cargo() {
.file("src/lib.rs", "")
.build();
// Populate the last-use data.
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
p.cargo("check")
.env("__CARGO_TEST_LAST_USE_NOW", months_ago_unix(4))
.run();
assert_eq!(
@ -1996,6 +1987,7 @@ fn compatible_with_older_cargo() {
middle = "1.0"
"#,
);
// TODO: Remove -Zgc after 1.82 is stabilized.
rustup_cargo()
.args(&["+stable", "check", "-Zgc"])
.cwd(p.root())
@ -2022,9 +2014,7 @@ fn compatible_with_older_cargo() {
new = "1.0"
"#,
);
p.cargo("check -Zgc")
.masquerade_as_nightly_cargo(&["gc"])
.run();
p.cargo("check").run();
assert_eq!(get_registry_names("src"), ["new-1.0.0"]);
assert_eq!(
get_registry_names("cache"),
@ -2060,9 +2050,8 @@ fn forward_compatible() {
.build();
rustup_cargo()
.args(&["+stable", "check", "-Zgc"])
.args(&["+stable", "check"])
.cwd(p.root())
.masquerade_as_nightly_cargo(&["gc"])
.run();
let config = GlobalContextBuilder::new().build();