2 use ops
::{self, ExecEngine}
;
3 use util
::{CargoResult, human, process, ProcessError, ChainError}
;
4 use core
::manifest
::TargetKind
;
5 use core
::source
::Source
;
6 use sources
::PathSource
;
8 pub fn run(manifest_path
: &Path
,
9 target_kind
: TargetKind
,
11 options
: &ops
::CompileOptions
,
12 args
: &[String
]) -> CargoResult
<Option
<ProcessError
>> {
13 let config
= options
.config
;
14 let mut src
= try
!(PathSource
::for_path(&manifest_path
.dir_path(), config
));
16 let root
= try
!(src
.root_package());
17 let env
= options
.env
;
18 let mut bins
= root
.manifest().targets().iter().filter(|a
| {
19 let matches_kind
= match target_kind
{
20 TargetKind
::Bin
=> a
.is_bin(),
21 TargetKind
::Example
=> a
.is_example(),
22 TargetKind
::Lib(_
) => false,
24 let matches_name
= name
.as_ref().map_or(true, |n
| *n
== a
.name());
25 matches_kind
&& matches_name
&& a
.profile().env() == env
&&
26 !a
.profile().is_custom_build()
28 let bin
= try
!(bins
.next().chain_error(|| {
29 human("a bin target must be available for `cargo run`")
32 Some(..) => return Err(
33 human("`cargo run` requires that a project only have one executable. \
34 Use the `--bin` option to specify which one to run")),
38 let compile
= try
!(ops
::compile(manifest_path
, options
));
39 let dst
= manifest_path
.dir_path().join("target");
40 let dst
= match options
.target
{
41 Some(target
) => dst
.join(target
),
44 let exe
= match (bin
.profile().dest(), bin
.is_example()) {
45 (Some(s
), true) => dst
.join(s
).join("examples").join(bin
.name()),
46 (Some(s
), false) => dst
.join(s
).join(bin
.name()),
47 (None
, true) => dst
.join("examples").join(bin
.name()),
48 (None
, false) => dst
.join(bin
.name()),
50 let exe
= match exe
.path_relative_from(config
.cwd()) {
54 let process
= try
!(try
!(compile
.target_process(exe
, &root
))
55 .into_process_builder())
57 .cwd(config
.cwd().clone());
59 try
!(config
.shell().status("Running", process
.to_string()));
60 Ok(process
.exec().err())