From e1821bf21fdd4895b5fafccfe4d11b3d61cfdf57 Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 9 Sep 2020 19:38:11 +0200 Subject: [PATCH 1/2] add listing of binaries in the project --- src/lib.rs | 40 ++++++++++++++++++++++++++++++++++++---- src/manifest.rs | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 4 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e2571da..4001cf7 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -33,6 +33,8 @@ use toml::de; use config::Config; use manifest::Manifest; +pub use manifest::Binary; + /// Information about a Cargo project pub struct Project { name: String, @@ -42,6 +44,8 @@ pub struct Project { target_dir: PathBuf, toml: PathBuf, + + binaries: Vec, } /// Errors @@ -58,8 +62,8 @@ impl Project { /// `path` doesn't need to be the directory that contains the `Cargo.toml` file; it can be any /// point within the Cargo project. pub fn query

(path: P) -> Result - where - P: AsRef, + where + P: AsRef, { let path = path.as_ref().canonicalize()?; let root = search(&path, "Cargo.toml").ok_or(Error::NotACargoProject)?; @@ -127,11 +131,24 @@ impl Project { target_dir = target_dir.or_else(|| workspace.map(|path| path.join("target"))); + let mut binaries = manifest.bin; + + if binaries.is_empty() { + // see if src/main.rs exists, and if so add to automatically generated bin + if root.join("src/main.rs").exists() { + binaries.push(Binary { + name: manifest.package.name.clone(), + path: String::from("src/main.rs"), + }); + } + } + Ok(Project { name: manifest.package.name, target, target_dir: target_dir.unwrap_or(root.join("target")), toml, + binaries, }) } @@ -226,6 +243,13 @@ impl Project { pub fn target_dir(&self) -> &Path { &self.target_dir } + + /// Get the binaries defined in the project. + /// + /// If no binary is explicitly defined, the default binary is returned + pub fn binaries(&self) -> impl Iterator { + self.binaries.iter() + } } /// Build artifact @@ -265,8 +289,8 @@ fn search<'p, P: AsRef>(path: &'p Path, file: P) -> Option<&'p Path> { } fn parse(path: &Path) -> Result -where - T: for<'de> Deserialize<'de>, + where + T: for<'de> Deserialize<'de>, { let mut s = String::new(); File::open(path)?.read_to_string(&mut s)?; @@ -324,4 +348,12 @@ mod tests { assert!(p.ends_with(&format!("target/{}/debug/examples/bar.wasm", wasm))); } + + #[test] + fn binaries() { + let project = Project::query(env::current_dir().unwrap()).unwrap(); + + // being a library project there is no automatically inferred binary + assert_eq!(project.binaries().count(), 0); + } } diff --git a/src/manifest.rs b/src/manifest.rs index e1fea3d..3469a57 100644 --- a/src/manifest.rs +++ b/src/manifest.rs @@ -3,6 +3,8 @@ #[derive(Deserialize)] pub struct Manifest { pub package: Package, + #[serde(default)] + pub bin: Vec, } #[derive(Deserialize)] @@ -12,6 +14,15 @@ pub struct Package { pub description: Option } +#[derive(Deserialize)] +/// A binary target in the project +pub struct Binary { + /// The name of the binary target + pub name: String, + /// The source path of the target + pub path: String, +} + #[cfg(test)] mod tests { use toml; @@ -58,4 +69,31 @@ description = "Test description" assert_eq!(manifest.package.description.unwrap(), "Test description"); } + + #[test] + fn binaries() { + let manifest: Manifest = toml::from_str( + r#" +[package] +name = "foo" +version = "0.1" + +[[bin]] +name = "foobar" +path = "src/foo.rs" + +[[bin]] +name = "barfoo" +path = "src/bar.rs" +"#, + ).unwrap(); + + assert_eq!(manifest.bin.len(), 2); + + assert_eq!(manifest.bin[0].name, "foobar"); + assert_eq!(manifest.bin[0].path, "src/foo.rs"); + + assert_eq!(manifest.bin[1].name, "barfoo"); + assert_eq!(manifest.bin[1].path, "src/bar.rs"); + } } From 1ae46b351f6305e7d43b6253d6e64b1ebf18994d Mon Sep 17 00:00:00 2001 From: Robin Appelman Date: Wed, 9 Sep 2020 19:44:41 +0200 Subject: [PATCH 2/2] add test projects for testing the default inferred binary --- test-projects/default-binary/Cargo.toml | 3 +++ test-projects/default-binary/src/main.rs | 3 +++ test-projects/no-default-binary/Cargo.toml | 3 +++ test-projects/no-default-binary/src/lib.rs | 3 +++ tests/test.rs | 21 +++++++++++++++++++++ 5 files changed, 33 insertions(+) create mode 100644 test-projects/default-binary/Cargo.toml create mode 100644 test-projects/default-binary/src/main.rs create mode 100644 test-projects/no-default-binary/Cargo.toml create mode 100644 test-projects/no-default-binary/src/lib.rs create mode 100644 tests/test.rs diff --git a/test-projects/default-binary/Cargo.toml b/test-projects/default-binary/Cargo.toml new file mode 100644 index 0000000..1981874 --- /dev/null +++ b/test-projects/default-binary/Cargo.toml @@ -0,0 +1,3 @@ +[package] +name = "foo" +version = "0.1" \ No newline at end of file diff --git a/test-projects/default-binary/src/main.rs b/test-projects/default-binary/src/main.rs new file mode 100644 index 0000000..cf74f49 --- /dev/null +++ b/test-projects/default-binary/src/main.rs @@ -0,0 +1,3 @@ +fn main() { + +} \ No newline at end of file diff --git a/test-projects/no-default-binary/Cargo.toml b/test-projects/no-default-binary/Cargo.toml new file mode 100644 index 0000000..1981874 --- /dev/null +++ b/test-projects/no-default-binary/Cargo.toml @@ -0,0 +1,3 @@ +[package] +name = "foo" +version = "0.1" \ No newline at end of file diff --git a/test-projects/no-default-binary/src/lib.rs b/test-projects/no-default-binary/src/lib.rs new file mode 100644 index 0000000..cf74f49 --- /dev/null +++ b/test-projects/no-default-binary/src/lib.rs @@ -0,0 +1,3 @@ +fn main() { + +} \ No newline at end of file diff --git a/tests/test.rs b/tests/test.rs new file mode 100644 index 0000000..cbdbf67 --- /dev/null +++ b/tests/test.rs @@ -0,0 +1,21 @@ +extern crate cargo_project; + +use cargo_project::Project; + +#[test] +fn test_inferred_binary() { + let project = Project::query("./test-projects/default-binary").unwrap(); + + let binaries = project.binaries().collect::>(); + assert_eq!(binaries.len(), 1); + assert_eq!(binaries[0].name, "foo"); + assert_eq!(binaries[0].path, "src/main.rs"); +} + +#[test] +fn test_no_inferred_binary() { + let project = Project::query("./test-projects/no-default-binary").unwrap(); + + let binaries = project.binaries().collect::>(); + assert_eq!(binaries.len(), 0); +} \ No newline at end of file