diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..ea8c4bf --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +/target diff --git a/src/.db.rs.swp b/src/.db.rs.swp deleted file mode 100644 index 1b9a1e2..0000000 Binary files a/src/.db.rs.swp and /dev/null differ diff --git a/src/.main.rs.swp b/src/.main.rs.swp index fe99a2d..72cb92b 100644 Binary files a/src/.main.rs.swp and b/src/.main.rs.swp differ diff --git a/src/db.rs b/src/db.rs new file mode 100644 index 0000000..a5b2545 --- /dev/null +++ b/src/db.rs @@ -0,0 +1,178 @@ +use std::path::{PathBuf, Path}; +use std::fs; +use std::os::unix::fs::MetadataExt; +use std::ffi::OsString; +use std::collections::HashMap; + +//use crate::log; + +#[derive(Debug)] +pub struct Entry { + base_dir: PathBuf, + pub name: OsString +} + +#[derive(Debug)] +pub struct Task { + name: OsString, + bin: PathBuf, + source: Option, + dvcs: Option, + config: HashMap, + branch: Option, + host: Option +} + +impl Task { + pub fn new(base_dir: PathBuf, name: OsString) -> Task { + let t = Entry::new(base_dir, name.clone()); + Task { + name: name.clone(), + bin: PathBuf::from(name.clone()), + source: t.source(), + dvcs: t.dvcs(), + config: HashMap::new(), + branch: t.branch(), + host: t.host(), + } + } +} + +impl Entry { + pub fn new(base_dir: PathBuf, name: OsString) -> Entry { + Entry { + base_dir, + name + } + } + + fn read_setting(&self, setting: &str) -> Option { + let mut path = self.base_dir.clone(); + path.push(&self.name); + path.set_extension(setting); + read_or_none(&path) + } + + pub fn source(&self) -> Option { + self.read_setting("source") + } + + pub fn dvcs(&self) -> Option { + self.read_setting("dvcs") + } + + pub fn branch(&self) -> Option { + self.read_setting("branch") + } + + pub fn host(&self) -> Option { + self.read_setting("branch") + } +} + +pub struct Database { + base_dir: PathBuf +} + +impl Database { + pub fn from_folder(p: &str) -> Database { + let path = PathBuf::from(&p); + if !path.is_dir() { + panic!("Folder {} not found", &p); + } + Database { + base_dir: path + } + } + + pub fn tasks(&self) -> Vec { + // If database doesn't exist, simply return an empty vec + let mut res = Vec::new(); + for file in list_files(&self.base_dir) { + if is_executable(&file) { + res.push( + Task::new(self.base_dir.clone(), file.file_name().expect("WTF").to_os_string()) + ); + } + println!("{:?}", file); + } + + return res; + } + + pub fn task(&self, name: &str) -> Option { + let mut path = self.base_dir.clone(); + path.push(name); + if !path.is_file() { + return None; + } + + return Some( + Task::new(self.base_dir.clone(), path.file_name().expect("WTF").to_os_string()) + ); + } +} + +/// Reads the file and strips whitespace (newline including) +/// Useful for file-based key-value store +fn read_or_none(path: &Path) -> Option { + if !path.is_file() { + return None; + } + match fs::read_to_string(path) { + Ok(content) => { + // Remove trailing space/newlines + Some(content.trim().to_string()) + }, + Err(e) => { + eprintln!("IO ERROR: {}", e); + None + } + } + +} + +fn list_files(path: &Path) -> Vec { + let mut res = Vec::new(); + match fs::read_dir(path) { + Ok(files) => { + for r in files { + match r { + Ok(entry) => { + let file = entry.path(); + if file.is_file() { + res.push(file); + } + }, + Err(e) => { + eprintln!("IOERROR: {}", e) + } + } + } + }, + Err(e) => { + eprintln!("IOERROR: {}", e); + } + } + return res; +} + + +// If the file doesn't exist or fails, return false +fn is_executable(path: &Path) -> bool { + match fs::metadata(path) { + Ok(stat) => { + let mode = stat.mode(); + // Check user exec permission) + if (mode & 0o100) == 0o100 { + true + } else { + false + } + }, + Err(e) => { + eprintln!("IO Error: {}", e); + false + } + } +} diff --git a/src/main.rs b/src/main.rs index 56e8eba..daacb14 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use std::env; use std::collections::HashMap; mod log; +mod db; fn main() { @@ -12,5 +13,13 @@ fn main() { test.insert("$i18n_task".to_string(), "test"); log::info("process", Some(&test)); + let db = db::Database::from_folder(&base_dir); + let truc = db.tasks(); + println!("{:?}", truc); + + for task in truc { + println!("{:#?}", task); + } + //let log_level = env::var("LOG").unwrap_or }