2020-02-18 12:25:26 +01:00
|
|
|
//! See `CargoTargetSpec`
|
2019-09-30 11:58:53 +03:00
|
|
|
|
2020-02-15 01:06:14 +02:00
|
|
|
use ra_ide::{FileId, RunnableKind, TestId};
|
2019-08-31 14:47:37 +03:00
|
|
|
use ra_project_model::{self, ProjectWorkspace, TargetKind};
|
|
|
|
|
|
|
|
use crate::{world::WorldSnapshot, Result};
|
2019-01-12 13:00:58 -05:00
|
|
|
|
2020-02-18 12:25:26 +01:00
|
|
|
/// Abstract representation of Cargo target.
|
|
|
|
///
|
|
|
|
/// We use it to cook up the set of cli args we need to pass to Cargo to
|
|
|
|
/// build/test/run the target.
|
2020-02-18 12:16:40 +01:00
|
|
|
pub(crate) struct CargoTargetSpec {
|
|
|
|
pub(crate) package: String,
|
|
|
|
pub(crate) target: String,
|
|
|
|
pub(crate) target_kind: TargetKind,
|
2019-01-12 13:00:58 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl CargoTargetSpec {
|
2020-02-18 12:17:47 +01:00
|
|
|
pub(crate) fn runnable_args(
|
|
|
|
spec: Option<CargoTargetSpec>,
|
|
|
|
kind: &RunnableKind,
|
2020-03-09 22:06:45 +01:00
|
|
|
) -> Result<(Vec<String>, Vec<String>)> {
|
|
|
|
let mut args = Vec::new();
|
|
|
|
let mut extra_args = Vec::new();
|
2020-02-18 12:17:47 +01:00
|
|
|
match kind {
|
|
|
|
RunnableKind::Test { test_id } => {
|
2020-03-09 22:06:45 +01:00
|
|
|
args.push("test".to_string());
|
2020-02-18 12:17:47 +01:00
|
|
|
if let Some(spec) = spec {
|
2020-03-09 22:06:45 +01:00
|
|
|
spec.push_to(&mut args);
|
2020-02-18 12:17:47 +01:00
|
|
|
}
|
2020-03-09 22:06:45 +01:00
|
|
|
extra_args.push(test_id.to_string());
|
2020-02-18 12:17:47 +01:00
|
|
|
if let TestId::Path(_) = test_id {
|
2020-03-09 22:06:45 +01:00
|
|
|
extra_args.push("--exact".to_string());
|
2020-02-18 12:17:47 +01:00
|
|
|
}
|
2020-03-09 22:06:45 +01:00
|
|
|
extra_args.push("--nocapture".to_string());
|
2020-02-18 12:17:47 +01:00
|
|
|
}
|
|
|
|
RunnableKind::TestMod { path } => {
|
2020-03-09 22:06:45 +01:00
|
|
|
args.push("test".to_string());
|
2020-02-18 12:17:47 +01:00
|
|
|
if let Some(spec) = spec {
|
2020-03-09 22:06:45 +01:00
|
|
|
spec.push_to(&mut args);
|
2020-02-18 12:17:47 +01:00
|
|
|
}
|
2020-03-09 22:06:45 +01:00
|
|
|
extra_args.push(path.to_string());
|
|
|
|
extra_args.push("--nocapture".to_string());
|
2020-02-18 12:17:47 +01:00
|
|
|
}
|
|
|
|
RunnableKind::Bench { test_id } => {
|
2020-03-09 22:06:45 +01:00
|
|
|
args.push("bench".to_string());
|
2020-02-18 12:17:47 +01:00
|
|
|
if let Some(spec) = spec {
|
2020-03-09 22:06:45 +01:00
|
|
|
spec.push_to(&mut args);
|
2020-02-18 12:17:47 +01:00
|
|
|
}
|
2020-03-09 22:06:45 +01:00
|
|
|
extra_args.push(test_id.to_string());
|
2020-02-18 12:17:47 +01:00
|
|
|
if let TestId::Path(_) = test_id {
|
2020-03-09 22:06:45 +01:00
|
|
|
extra_args.push("--exact".to_string());
|
2020-02-18 12:17:47 +01:00
|
|
|
}
|
2020-03-09 22:06:45 +01:00
|
|
|
extra_args.push("--nocapture".to_string());
|
2020-02-18 12:17:47 +01:00
|
|
|
}
|
|
|
|
RunnableKind::Bin => {
|
2020-03-09 22:06:45 +01:00
|
|
|
args.push("run".to_string());
|
2020-02-18 12:17:47 +01:00
|
|
|
if let Some(spec) = spec {
|
2020-03-09 22:06:45 +01:00
|
|
|
spec.push_to(&mut args);
|
2020-02-18 12:17:47 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-03-09 22:06:45 +01:00
|
|
|
Ok((args, extra_args))
|
2020-02-18 12:17:47 +01:00
|
|
|
}
|
|
|
|
|
2020-02-18 12:16:40 +01:00
|
|
|
pub(crate) fn for_file(
|
|
|
|
world: &WorldSnapshot,
|
|
|
|
file_id: FileId,
|
|
|
|
) -> Result<Option<CargoTargetSpec>> {
|
2019-01-12 13:00:58 -05:00
|
|
|
let &crate_id = match world.analysis().crate_for(file_id)?.first() {
|
|
|
|
Some(crate_id) => crate_id,
|
|
|
|
None => return Ok(None),
|
|
|
|
};
|
|
|
|
let file_id = world.analysis().crate_root(crate_id)?;
|
2020-01-16 11:58:31 +01:00
|
|
|
let path = world.file_id_to_path(file_id);
|
2019-03-05 22:29:23 +01:00
|
|
|
let res = world.workspaces.iter().find_map(|ws| match ws {
|
2019-08-31 14:47:37 +03:00
|
|
|
ProjectWorkspace::Cargo { cargo, .. } => {
|
2019-03-05 22:29:23 +01:00
|
|
|
let tgt = cargo.target_by_root(&path)?;
|
|
|
|
Some(CargoTargetSpec {
|
2020-03-19 17:53:31 +01:00
|
|
|
package: cargo[cargo[tgt].package].name.clone(),
|
|
|
|
target: cargo[tgt].name.clone(),
|
|
|
|
target_kind: cargo[tgt].kind,
|
2019-03-05 22:29:23 +01:00
|
|
|
})
|
|
|
|
}
|
2019-08-31 14:47:37 +03:00
|
|
|
ProjectWorkspace::Json { .. } => None,
|
2019-01-12 13:00:58 -05:00
|
|
|
});
|
|
|
|
Ok(res)
|
|
|
|
}
|
|
|
|
|
2020-02-18 12:16:40 +01:00
|
|
|
pub(crate) fn push_to(self, buf: &mut Vec<String>) {
|
2019-01-12 13:00:58 -05:00
|
|
|
buf.push("--package".to_string());
|
|
|
|
buf.push(self.package);
|
|
|
|
match self.target_kind {
|
|
|
|
TargetKind::Bin => {
|
|
|
|
buf.push("--bin".to_string());
|
|
|
|
buf.push(self.target);
|
|
|
|
}
|
|
|
|
TargetKind::Test => {
|
|
|
|
buf.push("--test".to_string());
|
|
|
|
buf.push(self.target);
|
|
|
|
}
|
|
|
|
TargetKind::Bench => {
|
|
|
|
buf.push("--bench".to_string());
|
|
|
|
buf.push(self.target);
|
|
|
|
}
|
|
|
|
TargetKind::Example => {
|
|
|
|
buf.push("--example".to_string());
|
|
|
|
buf.push(self.target);
|
|
|
|
}
|
|
|
|
TargetKind::Lib => {
|
|
|
|
buf.push("--lib".to_string());
|
|
|
|
}
|
|
|
|
TargetKind::Other => (),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|