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
use std::path::Path;
use ops::{self, CompileFilter, Packages};
use util::{self, human, CargoResult, ProcessError};
use core::Workspace;
pub fn run(ws: &Workspace,
options: &ops::CompileOptions,
args: &[String]) -> CargoResult<Option<ProcessError>> {
let config = ws.config();
let pkg = match options.spec {
Packages::All => unreachable!("cargo run supports single package only"),
Packages::Packages(xs) => match xs.len() {
0 => ws.current()?,
1 => ws.members()
.find(|pkg| pkg.name() == xs[0])
.ok_or_else(|| human(
format!("package `{}` is not a member of the workspace", xs[0])
))?,
_ => unreachable!("cargo run supports single package only"),
}
};
let mut bins = pkg.manifest().targets().iter().filter(|a| {
!a.is_lib() && !a.is_custom_build() && match options.filter {
CompileFilter::Everything { .. } => a.is_bin(),
CompileFilter::Only { .. } => options.filter.matches(a),
}
});
if bins.next().is_none() {
match options.filter {
CompileFilter::Everything { .. } => {
bail!("a bin target must be available for `cargo run`")
}
CompileFilter::Only { .. } => {
}
}
}
if bins.next().is_some() {
match options.filter {
CompileFilter::Everything { .. } => {
bail!("`cargo run` requires that a project only have one \
executable; use the `--bin` option to specify which one \
to run")
}
CompileFilter::Only { .. } => {
bail!("`cargo run` can run at most one executable, but \
multiple were specified")
}
}
}
let compile = ops::compile(ws, options)?;
assert_eq!(compile.binaries.len(), 1);
let exe = &compile.binaries[0];
let exe = match util::without_prefix(&exe, config.cwd()) {
Some(path) if path.file_name() == Some(path.as_os_str())
=> Path::new(".").join(path).to_path_buf(),
Some(path) => path.to_path_buf(),
None => exe.to_path_buf(),
};
let mut process = compile.target_process(exe, &pkg)?;
process.args(args).cwd(config.cwd());
config.shell().status("Running", process.to_string())?;
Ok(process.exec_replace().err())
}