2019-02-18 02:14:09 -06:00
|
|
|
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 {
|
2019-02-18 03:05:29 -06:00
|
|
|
pub fn path(&self) -> &Path {
|
2019-02-18 02:14:09 -06:00
|
|
|
&self.path
|
|
|
|
}
|
2019-02-18 03:10:20 -06:00
|
|
|
|
|
|
|
pub fn info(&self) -> ProjectInfo {
|
2019-02-18 22:12:49 -06:00
|
|
|
match self.project_type {
|
2019-02-18 03:10:20 -06:00
|
|
|
ProjectType::Maven => ProjectInfo {
|
|
|
|
name: "placeholder".into(),
|
|
|
|
version: "placeholder".into()
|
|
|
|
},
|
|
|
|
ProjectType::Npm => ProjectInfo {
|
|
|
|
name: "placeholder".into(),
|
|
|
|
version: "placeholder".into()
|
|
|
|
},
|
2019-02-18 22:12:49 -06:00
|
|
|
ProjectType::Cargo => self.read_cargo_metadata().into()
|
2019-02-18 03:10:20 -06:00
|
|
|
}
|
|
|
|
}
|
2019-02-18 22:12:49 -06:00
|
|
|
|
|
|
|
fn read_cargo_metadata(&self) -> cargo_metadata::Metadata {
|
2019-02-18 22:41:38 -06:00
|
|
|
cargo_metadata::MetadataCommand::new()
|
|
|
|
.current_dir(&self.path)
|
|
|
|
.exec()
|
|
|
|
.expect("metadata call failed")
|
2019-02-18 22:12:49 -06:00
|
|
|
}
|
2019-02-18 03:10:20 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub struct ProjectInfo {
|
2019-02-18 22:12:49 -06:00
|
|
|
pub name: String,
|
2019-02-18 03:10:20 -06:00
|
|
|
pub version: String
|
2019-02-18 02:14:09 -06:00
|
|
|
}
|
|
|
|
|
2019-02-18 22:12:49 -06:00
|
|
|
impl From<cargo_metadata::Metadata> for ProjectInfo {
|
|
|
|
fn from(metadata: cargo_metadata::Metadata) -> Self {
|
|
|
|
let root_package_id = metadata.resolve
|
|
|
|
.expect("non-existent resolve field")
|
|
|
|
.root
|
|
|
|
.expect("non-existent root package id");
|
|
|
|
let package = metadata.packages.into_iter()
|
|
|
|
.find(|package| package.id == root_package_id)
|
|
|
|
.expect("failed to find package in metadata");
|
|
|
|
ProjectInfo {
|
|
|
|
name: package.name.into(),
|
|
|
|
version: format!("{}", package.version)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-18 02:14:09 -06:00
|
|
|
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!());
|
2019-02-18 22:12:49 -06:00
|
|
|
let project = scouter.next().unwrap();
|
|
|
|
let project_info = project.info();
|
|
|
|
assert_eq!(ProjectType::Cargo, project.project_type);
|
|
|
|
assert_eq!(env!("CARGO_PKG_NAME"), project_info.name);
|
|
|
|
assert_eq!(env!("CARGO_PKG_VERSION"), project_info.version);
|
2019-02-18 02:14:09 -06:00
|
|
|
}
|
|
|
|
}
|