From ec55a274c32fb24f2ef88dce3d068b3ff40ca4c1 Mon Sep 17 00:00:00 2001 From: southerntofu Date: Thu, 30 Apr 2020 22:11:06 +0200 Subject: [PATCH] Flat-file DB --- .gitignore | 1 + src/.db.rs.swp | Bin 12288 -> 0 bytes src/.main.rs.swp | Bin 12288 -> 12288 bytes src/db.rs | 178 +++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 9 +++ 5 files changed, 188 insertions(+) create mode 100644 .gitignore delete mode 100644 src/.db.rs.swp create mode 100644 src/db.rs 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 1b9a1e207ba86532c92b076135003129b1e94f53..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 12288 zcmeI2&u`pB6vro#XdzIFS|P!S$+ivNu-Q%EQaPkjOA-;JYNJrvq5>nBQ+{P?lA9>$Y? zM=PKe&mKr5gX&Sl|kH8(an_!M}&$6Z{Ik1RYQZCO8F-f-&$9w7d^~0AGPy;B)XP_ymyFUjTh+ z1+)TMf&Z@pwfyDy+?5Sw$xWkFDl^t)92YExH}smxq+g;Z$MU3LRLU+9My{_sf6^$e z)cH~r1(C_OyQK;j<$0D_q23T>zHo+b@78rIyG1f9c0@IMJL__R{&POaj4l<$#jsq5 z8||Pa_!OTF=4NNn_d>5U@OG`nU)vD&Ca3S?xabI*hazgbQo4a(W{LOo#}kStJ{P!D zma0cgTapb3xrL)^tG;NK9>`zIT6$aNg z&W2o=*`>9$`r43*CF5a}OZ5X2oK!LT9lZATomq@-A&Un@$TAOu_ff&-?S=$iXlD7R zVdd_0ZC@LD&klU$`U6XMm_w=?IojM39QAH(8XKap4u!9xt#TDfL11svie#f+&gvgL z8JX1qqRC7T<}kDNt+p^Z{Z>`b2xLPlq@H!7xJfhXQTL`LMWf{+NlD>3)$Flqdx4ML zT+B(MoKXD**+45D|_YJBr%2m+`g{_Rzr3=fY z0|<>trwQ&SnJIEclb!EyuuMw@X0$fwo-B?*oBT5cOoj+JSyffaarwlUH>NTYWpDWv z4}`o~FLOpiB6X1TBJLvBp-VYn0MAKvE(ep>ejbj5)uQP)rV7)amn2E^u|i6f7|}&x zo2D`dRtjWwtOzyq1xhCh0Q3IFm7@re>#d~FN!ipx<@~+ z(vqSRGO_D#j(&;W&sMC-N#?|qsu#0p`g2=+FSLBu#wooVcrBcC+gmeN=RW_WYGb1$lo5^NPhMEhNq{@e$ zo?QJgrhPDSiv1qjYKVC+Gf34!D2{8Ib=m7J5oeFDO5Rzzi%(pEChk>XEQ)5lUVfM1 z+{GUR+>R_IOw$Y2=aWzJ5d%62aG=M&+d+3IollSUrH-1X&-QyZ4vyO02NKLQx6{E? J66Lz{>^}tRg_{5X diff --git a/src/.main.rs.swp b/src/.main.rs.swp index fe99a2dd841efbaebd22a0517dc4ba6e5ef29484..72cb92b45b85c20c65d1444d5dda77f463216fd2 100644 GIT binary patch delta 340 zcmZojXh={vI28KNbtK)WP9b)h=VqhpOPA!@^QDvjc8Gc5|&4L1- z`FW#w85nK>F-WQ8WI+XED?xq+hI@Pr4BLTt8xS`GaRw0k0I@d^n*gye5c2{t4-nsh znsAVJv!Z}AZ+$I;0uboy=cJY>jHODxh*^6__9($p)> zD=$hch|dQ)7-SMe8;DgHl zib|6esv-K3bwM-%C83%?ZUm{F9Ij`^sg{&joEo2!Su}aQp4Q~sdKQyK^vI28ILwSHeBh%fL`toLV$-qRK{>GyIIgn*{|v z^YfnOWneJogD4fAET~{C$Is8ea0e)|8HhIlaT*Z&0kJ6%8}n^e6u8K%Qp=zK1O-Kz zc_le{iW*AQR`#_@Its;_)?kU8)Dnf_$t8MblRfm6CU4f$V$#x|d{@tcNndNSsQzmJ D*la3G 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 }