mirror of
https://github.com/rust-lang/cargo.git
synced 2025-09-25 11:14:46 +00:00
Add a --dry-run option to cargo clean
.
This adds a `--dry-run` option to have `cargo clean` display what it would delete without actually deleting it.
This commit is contained in:
parent
61e8ef30d9
commit
45c5394703
@ -14,6 +14,13 @@ pub fn cli() -> Command {
|
||||
.arg_target_triple("Target triple to clean output for")
|
||||
.arg_target_dir()
|
||||
.arg_manifest_path()
|
||||
.arg(
|
||||
flag(
|
||||
"dry-run",
|
||||
"Display what would be deleted without deleting anything",
|
||||
)
|
||||
.short('n'),
|
||||
)
|
||||
.after_help(color_print::cstr!(
|
||||
"Run `<cyan,bold>cargo help clean</>` for more detailed information.\n"
|
||||
))
|
||||
@ -33,6 +40,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
|
||||
requested_profile: args.get_profile_name(config, "dev", ProfileChecking::Custom)?,
|
||||
profile_specified: args.contains_id("profile") || args.flag("release"),
|
||||
doc: args.flag("doc"),
|
||||
dry_run: args.flag("dry-run"),
|
||||
};
|
||||
ops::clean(&ws, &opts)?;
|
||||
Ok(())
|
||||
|
@ -23,11 +23,14 @@ pub struct CleanOptions<'cfg> {
|
||||
pub requested_profile: InternedString,
|
||||
/// Whether to just clean the doc directory
|
||||
pub doc: bool,
|
||||
/// If set, doesn't delete anything.
|
||||
pub dry_run: bool,
|
||||
}
|
||||
|
||||
pub struct CleanContext<'cfg> {
|
||||
pub config: &'cfg Config,
|
||||
progress: Box<dyn CleaningProgressBar + 'cfg>,
|
||||
pub dry_run: bool,
|
||||
}
|
||||
|
||||
/// Cleans various caches.
|
||||
@ -35,6 +38,7 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> {
|
||||
let mut target_dir = ws.target_dir();
|
||||
let config = opts.config;
|
||||
let mut ctx = CleanContext::new(config);
|
||||
ctx.dry_run = opts.dry_run;
|
||||
|
||||
if opts.doc {
|
||||
if !opts.spec.is_empty() {
|
||||
@ -262,6 +266,7 @@ impl<'cfg> CleanContext<'cfg> {
|
||||
CleanContext {
|
||||
config,
|
||||
progress: Box::new(progress),
|
||||
dry_run: false,
|
||||
}
|
||||
}
|
||||
|
||||
@ -322,26 +327,48 @@ impl<'cfg> CleanContext<'cfg> {
|
||||
}
|
||||
};
|
||||
|
||||
self.config
|
||||
.shell()
|
||||
.verbose(|shell| shell.status("Removing", path.display()))?;
|
||||
if self.dry_run {
|
||||
// Concise because if in verbose mode, the path will be written in
|
||||
// the loop below.
|
||||
self.config
|
||||
.shell()
|
||||
.concise(|shell| Ok(writeln!(shell.out(), "{}", path.display())?))?;
|
||||
} else {
|
||||
self.config
|
||||
.shell()
|
||||
.verbose(|shell| shell.status("Removing", path.display()))?;
|
||||
}
|
||||
self.progress.display_now()?;
|
||||
|
||||
let rm_file = |path: &Path| {
|
||||
if !self.dry_run {
|
||||
paths::remove_file(path)?;
|
||||
}
|
||||
Ok(())
|
||||
};
|
||||
|
||||
if !meta.is_dir() {
|
||||
return paths::remove_file(path);
|
||||
return rm_file(path);
|
||||
}
|
||||
|
||||
for entry in walkdir::WalkDir::new(path).contents_first(true) {
|
||||
let entry = entry?;
|
||||
self.progress.on_clean()?;
|
||||
if self.dry_run {
|
||||
self.config
|
||||
.shell()
|
||||
.verbose(|shell| Ok(writeln!(shell.out(), "{}", entry.path().display())?))?;
|
||||
}
|
||||
if entry.file_type().is_dir() {
|
||||
// The contents should have been removed by now, but sometimes a race condition is hit
|
||||
// where other files have been added by the OS. `paths::remove_dir_all` also falls back
|
||||
// to `std::fs::remove_dir_all`, which may be more reliable than a simple walk in
|
||||
// platform-specific edge cases.
|
||||
paths::remove_dir_all(entry.path())?;
|
||||
if !self.dry_run {
|
||||
paths::remove_dir_all(entry.path())?;
|
||||
}
|
||||
} else {
|
||||
paths::remove_file(entry.path())?;
|
||||
rm_file(entry.path())?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,7 @@ Usage: cargo[EXE] clean [OPTIONS]
|
||||
Options:
|
||||
--doc Whether or not to clean just the documentation directory
|
||||
-q, --quiet Do not print cargo log messages
|
||||
-n, --dry-run Display what would be deleted without deleting anything
|
||||
-v, --verbose... Use verbose output (-vv very verbose/build.rs output)
|
||||
--color <WHEN> Coloring: auto, always, never
|
||||
--config <KEY=VALUE> Override a configuration value
|
||||
|
@ -782,6 +782,50 @@ fn clean_spec_reserved() {
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn clean_dry_run() {
|
||||
// Basic `clean --dry-run` test.
|
||||
Package::new("bar", "1.0.0").publish();
|
||||
let p = project()
|
||||
.file(
|
||||
"Cargo.toml",
|
||||
r#"
|
||||
[package]
|
||||
name = "foo"
|
||||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
bar = "1.0"
|
||||
"#,
|
||||
)
|
||||
.file("src/lib.rs", "")
|
||||
.build();
|
||||
|
||||
let ls_r = || -> Vec<_> {
|
||||
let mut file_list: Vec<_> = walkdir::WalkDir::new(p.build_dir())
|
||||
.into_iter()
|
||||
.filter_map(|e| e.map(|e| e.path().to_owned()).ok())
|
||||
.collect();
|
||||
file_list.sort();
|
||||
file_list
|
||||
};
|
||||
|
||||
// Start with no files.
|
||||
p.cargo("clean --dry-run").with_stdout("").run();
|
||||
p.cargo("check").run();
|
||||
let before = ls_r();
|
||||
p.cargo("clean --dry-run").with_stdout("[CWD]/target").run();
|
||||
// Verify it didn't delete anything.
|
||||
let after = ls_r();
|
||||
assert_eq!(before, after);
|
||||
let expected = cargo::util::iter_join(before.iter().map(|p| p.to_str().unwrap()), "\n");
|
||||
eprintln!("{expected}");
|
||||
// Verify the verbose output.
|
||||
p.cargo("clean --dry-run -v")
|
||||
.with_stdout_unordered(expected)
|
||||
.run();
|
||||
}
|
||||
|
||||
#[cargo_test]
|
||||
fn doc_with_package_selection() {
|
||||
// --doc with -p
|
||||
|
Loading…
x
Reference in New Issue
Block a user