1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
use std::default::Default;
use std::fs;
use std::path::Path;
use core::{Package, Profiles};
use core::source::Source;
use util::{CargoResult, human, ChainError, Config};
use ops::{self, Layout, Context, BuildConfig, Kind, Unit};
pub struct CleanOptions<'a> {
pub spec: &'a [String],
pub target: Option<&'a str>,
pub config: &'a Config,
pub release: bool,
}
pub fn clean(manifest_path: &Path, opts: &CleanOptions) -> CargoResult<()> {
let root = try!(Package::for_path(manifest_path, opts.config));
let target_dir = opts.config.target_dir(&root);
if opts.spec.is_empty() {
return rm_rf(&target_dir);
}
let (resolve, packages) = try!(ops::fetch(manifest_path, opts.config));
let dest = if opts.release {"release"} else {"debug"};
let host_layout = Layout::new(opts.config, &root, None, dest);
let target_layout = opts.target.map(|target| {
Layout::new(opts.config, &root, Some(target), dest)
});
let cx = try!(Context::new(&resolve, &packages, opts.config,
host_layout, target_layout,
BuildConfig::default(),
root.manifest().profiles()));
for spec in opts.spec {
let pkgid = try!(resolve.query(spec));
let pkg = try!(packages.get(&pkgid));
for target in pkg.targets() {
for kind in [Kind::Host, Kind::Target].iter() {
let layout = cx.layout(&pkg, *kind);
try!(rm_rf(&layout.proxy().fingerprint(&pkg)));
try!(rm_rf(&layout.build(&pkg)));
let Profiles {
ref release, ref dev, ref test, ref bench, ref doc,
ref custom_build,
} = *root.manifest().profiles();
for profile in [release, dev, test, bench, doc, custom_build].iter() {
let unit = Unit {
pkg: &pkg,
target: target,
profile: profile,
kind: *kind,
};
let root = cx.out_dir(&unit);
for filename in try!(cx.target_filenames(&unit)).iter() {
try!(rm_rf(&root.join(&filename)));
}
}
}
}
}
Ok(())
}
fn rm_rf(path: &Path) -> CargoResult<()> {
let m = fs::metadata(path);
if m.as_ref().map(|s| s.is_dir()).unwrap_or(false) {
try!(fs::remove_dir_all(path).chain_error(|| {
human("could not remove build directory")
}));
} else if m.is_ok() {
try!(fs::remove_file(path).chain_error(|| {
human("failed to remove build artifact")
}));
}
Ok(())
}