From 5b497787198880d96999fba9aef3e73dacf7ab43 Mon Sep 17 00:00:00 2001 From: Patrik Svensson Date: Sat, 5 May 2018 10:39:51 +0200 Subject: [PATCH] Do not allow running library examples. Closes #5474 --- src/cargo/core/compiler/context/mod.rs | 2 +- src/cargo/ops/cargo_run.rs | 30 +++++++++++++++++++----- tests/testsuite/run.rs | 32 ++++++++++++++++++++++++++ 3 files changed, 57 insertions(+), 7 deletions(-) diff --git a/src/cargo/core/compiler/context/mod.rs b/src/cargo/core/compiler/context/mod.rs index a0e166860..7c039fcca 100644 --- a/src/cargo/core/compiler/context/mod.rs +++ b/src/cargo/core/compiler/context/mod.rs @@ -160,7 +160,7 @@ impl<'a, 'cfg> Context<'a, 'cfg> { unit.target.name().to_string(), output.path.clone(), )); - } else if unit.target.is_bin() || unit.target.is_example() { + } else if unit.target.is_bin() || unit.target.is_bin_example() { self.compilation.binaries.push(bindst.clone()); } else if unit.target.is_lib() { let pkgid = unit.pkg.package_id().clone(); diff --git a/src/cargo/ops/cargo_run.rs b/src/cargo/ops/cargo_run.rs index b609a0ea3..7309b394d 100644 --- a/src/cargo/ops/cargo_run.rs +++ b/src/cargo/ops/cargo_run.rs @@ -2,7 +2,7 @@ use std::path::Path; use ops::{self, Packages}; use util::{self, CargoResult, ProcessError}; -use core::Workspace; +use core::{TargetKind, Workspace}; pub fn run( ws: &Workspace, @@ -26,7 +26,7 @@ pub fn run( }, }; - let bins: Vec<_> = pkg.manifest() +let bins: Vec<_> = pkg.manifest() .targets() .iter() .filter(|a| { @@ -36,7 +36,7 @@ pub fn run( options.filter.target_run(a) } }) - .map(|bin| bin.name()) + .map(|bin| (bin.name(), bin.kind())) .collect(); if bins.is_empty() { @@ -46,13 +46,31 @@ pub fn run( // this will be verified in cargo_compile } } + + if bins.len() == 1 { + let bin = bins.first().unwrap(); + match *bin.1 { + TargetKind::ExampleLib(..) => { + bail!( + "example target `{}` is a library and cannot be executed.", + bin.0 + ) + }, + _ => { } + }; + } + if bins.len() > 1 { if !options.filter.is_specific() { + + let names : Vec<&str> = bins.into_iter().map(|bin| bin.0).collect(); + bail!( "`cargo run` requires that a project only have one \ executable; use the `--bin` option to specify which one \ - to run\navailable binaries: {}", - bins.join(", ") + to run\navailable binaries: {}", + names.join(", ") + ) } else { bail!( @@ -86,4 +104,4 @@ pub fn run( Ok(Some(err)) } } -} +} \ No newline at end of file diff --git a/tests/testsuite/run.rs b/tests/testsuite/run.rs index ac6c6e212..bf2e37fe2 100644 --- a/tests/testsuite/run.rs +++ b/tests/testsuite/run.rs @@ -387,6 +387,38 @@ fn run_example() { ); } +#[test] +fn run_library_example() { + let p = project("foo") + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + authors = [] + [[example]] + name = "bar" + crate_type = ["lib"] + "#, + ) + .file("src/lib.rs", "") + .file( + "examples/bar.rs", + r#" + fn foo() {} + "#, + ) + .build(); + + assert_that( + p.cargo("run").arg("--example").arg("bar"), + execs() + .with_status(101) + .with_stderr("[ERROR] example target `bar` is a library and cannot be executed."), + ); +} + fn autodiscover_examples_project(rust_edition: &str, autoexamples: Option) -> Project { let autoexamples = match autoexamples { None => "".to_string(), -- 2.30.2