From afbcde5fd3fc93949e0e0de0835cce1a9d622414 Mon Sep 17 00:00:00 2001 From: Adrian Malacoda Date: Mon, 18 Feb 2019 02:14:09 -0600 Subject: [PATCH] Add Scouter subproject. This takes a file and detects what project it might belong to, traversing up the hierarchy until it encounters a supported project type. Because projects can be nested, the Scouter is actually an iterator. For the purposes of Shenlong though generally only the first value will be used. --- scouter/Cargo.lock | 4 +++ scouter/Cargo.toml | 7 ++++ scouter/src/lib.rs | 85 ++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+) create mode 100644 scouter/Cargo.lock create mode 100644 scouter/Cargo.toml create mode 100644 scouter/src/lib.rs diff --git a/scouter/Cargo.lock b/scouter/Cargo.lock new file mode 100644 index 0000000..d97de48 --- /dev/null +++ b/scouter/Cargo.lock @@ -0,0 +1,4 @@ +[[package]] +name = "scouter" +version = "0.1.0" + diff --git a/scouter/Cargo.toml b/scouter/Cargo.toml new file mode 100644 index 0000000..b73459d --- /dev/null +++ b/scouter/Cargo.toml @@ -0,0 +1,7 @@ +[package] +name = "scouter" +version = "0.1.0" +authors = ["Adrian Malacoda "] +edition = "2018" + +[dependencies] diff --git a/scouter/src/lib.rs b/scouter/src/lib.rs new file mode 100644 index 0000000..320ccde --- /dev/null +++ b/scouter/src/lib.rs @@ -0,0 +1,85 @@ +use std::path::{Path, PathBuf}; + +#[derive(Debug, PartialEq)] +pub enum ProjectType { + Maven, + Npm, + Cargo +} + +impl ProjectType { + fn detect>(path: P) -> Option { + let project_path: PathBuf = path.as_ref().into(); + if project_path.join("pom.xml").is_file() { + return Some(ProjectType::Maven); + } else if project_path.join("package.json").is_file() { + return Some(ProjectType::Npm); + } else if project_path.join("Cargo.toml").is_file() { + return Some(ProjectType::Cargo); + } + + None + } +} + +#[derive(Debug)] +pub struct Project { + pub project_type: ProjectType, + path: PathBuf +} + +impl Project { + fn path(&self) -> &Path { + &self.path + } +} + +pub struct Scouter { + search_path: PathBuf +} + +impl Scouter { + pub fn new>(path: P) -> Scouter { + let mut search_path: PathBuf = path.as_ref().into(); + if !search_path.is_dir() { + search_path.pop(); + } + + Scouter { + search_path: search_path + } + } +} + +impl Iterator for Scouter { + type Item = Project; + + fn next(&mut self) -> Option { + loop { + let project_type = ProjectType::detect(&self.search_path); + if project_type.is_some() + { + return project_type.map(|project_type| Project { + project_type: project_type, + path: self.search_path.to_owned() + }); + } + + if !self.search_path.pop() + { + return None; + } + } + } +} + +#[cfg(test)] +mod test { + use super::{ProjectType, Scouter}; + + #[test] + fn test_scouter() { + let mut scouter = Scouter::new(file!()); + assert_eq!(ProjectType::Cargo, scouter.next().unwrap().project_type); + } +}