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.
This commit is contained in:
Adrian Malacoda 2019-02-18 02:14:09 -06:00
parent 637981960a
commit afbcde5fd3
3 changed files with 96 additions and 0 deletions

4
scouter/Cargo.lock generated Normal file
View File

@ -0,0 +1,4 @@
[[package]]
name = "scouter"
version = "0.1.0"

7
scouter/Cargo.toml Normal file
View File

@ -0,0 +1,7 @@
[package]
name = "scouter"
version = "0.1.0"
authors = ["Adrian Malacoda <adrian.malacoda@monarch-pass.net>"]
edition = "2018"
[dependencies]

85
scouter/src/lib.rs Normal file
View File

@ -0,0 +1,85 @@
use std::path::{Path, PathBuf};
#[derive(Debug, PartialEq)]
pub enum ProjectType {
Maven,
Npm,
Cargo
}
impl ProjectType {
fn detect<P: AsRef<Path>>(path: P) -> Option<ProjectType> {
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<P: AsRef<Path>>(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<Self::Item> {
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);
}
}