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
89
90
91
92
93
use std::default::Default;
use std::fs;
use std::io::prelude::*;
use std::path::Path;
use core::{Package, PackageSet, Profiles, Profile};
use core::source::{Source, SourceMap};
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 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.len() == 0 {
return rm_rf(&target_dir);
}
let lockfile = root.root().join("Cargo.lock");
let source_id = root.package_id().source_id();
let resolve = match try!(ops::load_lockfile(&lockfile, source_id)) {
Some(resolve) => resolve,
None => return Err(human("A Cargo.lock must exist before cleaning"))
};
let srcs = SourceMap::new();
let pkgs = PackageSet::new(&[]);
let profiles = Profiles::default();
let cx = try!(Context::new(&resolve, &srcs, &pkgs, opts.config,
Layout::at(target_dir),
None, BuildConfig::default(),
&profiles));
for spec in opts.spec {
let pkgid = try!(resolve.query(spec));
let pkg = {
let mut source = pkgid.source_id().load(opts.config);
try!(source.update());
(try!(source.get(&[pkgid.clone()]))).into_iter().next().unwrap()
};
for target in pkg.targets().iter() {
let layout = Layout::new(opts.config, &root, opts.target, "debug");
try!(rm_rf(&layout.fingerprint(&pkg)));
let profiles = [Profile::default_dev(), Profile::default_test()];
for profile in profiles.iter() {
let unit = Unit {
pkg: &pkg,
target: target,
profile: profile,
kind: Kind::Target,
};
for filename in try!(cx.target_filenames(&unit)).iter() {
try!(rm_rf(&layout.dest().join(&filename)));
try!(rm_rf(&layout.deps().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(())
}