refact + add colorized

This commit is contained in:
a-Sansara 2020-10-12 01:04:40 +02:00
parent 035bb07c9a
commit 60f0d9e016
9 changed files with 178 additions and 79 deletions

View File

@ -1,9 +1,9 @@
[package] [package]
name = "ykre" name = "ykre"
version = "0.1.0" version = "0.2.0"
authors = ["a-Sansara <dev]at[pluie]dot[org>"] authors = ["a-Sansara <dev]at[pluie]dot[org>"]
edition = "2018" edition = "2018"
description = "Ykre is Yaml Kubernetes Resource Extractor" description = "Ykre stand for Yaml Kubernetes Resource Extractor"
license = "MIT" license = "MIT"
readme = "README.md" readme = "README.md"
keywords = ["cli", "yaml", "kubernetes", "kustomize"] keywords = ["cli", "yaml", "kubernetes", "kustomize"]
@ -13,3 +13,4 @@ categories = ["command-line-utilities"]
[dependencies] [dependencies]
yaml-rust = "0.4" yaml-rust = "0.4"
colored = "2"

View File

@ -3,15 +3,15 @@
**Ykre** is a small cli program written in rust wich purpose is to extract from a list **Ykre** is a small cli program written in rust wich purpose is to extract from a list
of yaml documents, documents matching a specified condition. **Ykre** goal is to find of yaml documents, documents matching a specified condition. **Ykre** goal is to find
specific Kubernetes Resource from the kustomize output. specific Kubernetes Resource from the kustomize output.
**Ykre** stands for **Y**aml **K**ubernetes **R**esources **E**ctractor. **Ykre** stands for **Y**aml **K**ubernetes **R**esources **E**xtractor.
## Install ## Install
from a debian package : from a debian package :
```  ``` 
wget -q https://github.com/pluie-org/ykre/raw/master/dist/ykre_0.1.0_amd64.deb wget -q https://github.com/pluie-org/ykre/raw/master/dist/ykre_0.2.0_amd64.deb
sudo apt install ./ykre_0.1.0_amd64.deb sudo apt install ./ykre_0.2.0_amd64.deb
``` ```
via Cargo via Cargo

Binary file not shown.

BIN
dist/ykre_0.2.0_amd64.deb vendored Normal file

Binary file not shown.

View File

@ -1,29 +1,8 @@
extern crate yaml_rust; extern crate yaml_rust;
extern crate colored;
pub mod ykre; pub mod ykre;
use std::io; fn main() -> std::io::Result<()> {
use std::panic; ykre::run()
const PANIC_BYPASS_FILE : &str = "src/ykre/pipin.rs";
const PANIC_BYPASS_LINE : u32 = 9;
fn main() -> io::Result<()> {
panic::set_hook(Box::new(|_info| {
let mut bypass :bool = false;
if let Some(location) = &_info.location() {
bypass = location.file() == PANIC_BYPASS_FILE && location.line() == PANIC_BYPASS_LINE;
}
if !bypass {
//~ println!("{:?}", &_info);
if let Some(s) = &_info.payload().downcast_ref::<&str>() {
if s.len() > 1 {
println!("{}", s);
}
}
}
}));
ykre::run();
Ok(())
} }

View File

@ -1,56 +1,52 @@
mod yaml; mod yaml;
mod pipin; mod pipin;
mod app; mod app;
mod echo;
mod color;
pub use self::yaml::YamlDocument; pub use self::yaml::YamlDocument;
pub use self::pipin::{spawn_stdin, sleep}; pub use self::pipin::*;
pub use self::app::{run}; pub use self::echo::*;
pub use self::color::*;
pub use self::app::run;
const YKRE_LIMIT_ATTEMPT : u64 = 900; const BG : Rgb = Rgb { r: 30, g: 85, b:125 };
const CSEP : Rgb = Rgb { r: 30, g: 85, b:125 };
const CTITLE : Rgb = Rgb { r:255, g:220, b:190 };
const CTITLESEP : Rgb = Rgb { r:255, g:175, b: 35 };
const CKEY1 : Rgb = Rgb { r: 23, g:141, b: 84 };
const CVAL1 : Rgb = Rgb { r:149, g:197, b:157 };
const CKEY2 : Rgb = Rgb { r:237, g:214, b:140 };
const CVAL2 : Rgb = Rgb { r:238, g:194, b: 55 };
const CTEXT : Rgb = Rgb { r:190, g:162, b:216 };
const CPROG : Rgb = Rgb { r:255, g:255, b:255 };
const COPTSEP : Rgb = Rgb { r:255, g:151, b: 75 };
//~ const COPT : Rgb = Rgb { r: 23, g:141, b: 84 };
const CARG : Rgb = Rgb { r: 90, g:205, b:255 };
const CUSAGE : Rgb = Rgb { r:238, g:194, b: 55 };
const CSTR : Rgb = Rgb { r: 66, g:135, b: 99 };
const CCOM : Rgb = Rgb { r:105, g:103, b:149 };
const CERR : Rgb = Rgb { r:175, g: 37, b: 21 };
const CERRMSG : Rgb = Rgb { r:210, g: 99, b: 86 };
const WIDTH : usize = 82;
const PANIC_BYPASS_LINE : u32 = 9;
const PANIC_BYPASS_FILE : &str = "src/ykre/pipin.rs";
const YKRE_AUTHOR : &str = "a-Sansara";
const YKRE_VERSION : &str = "0.2";
const YKRE_LICENSE : &str = "MIT";
const YKRE_NAME : &str = "Ykre";
const YKRE_DEFAULT_DEF : &str = "metadata.name";
const YKRE_LIMIT_ATTEMPT : u64 = 1500;
const YKRE_SLEEP_START : u64 = 50; const YKRE_SLEEP_START : u64 = 50;
const YKRE_SLEEP_DATA : u64 = 1; const YKRE_SLEEP_DATA : u64 = 1;
const YKRE_SLEEP_NODATA : u64 = 1; const YKRE_SLEEP_NODATA : u64 = 1;
const YKRE_DEFAULT_DEF : &str = "metadata.name"; const YKRE_ERROR_NOTFOUND : &str = "no match found for specified pattern";
const YKRE_ERROR_NOTFOUND : &str = r" const YKRE_ERROR_INVALID : &str = "invalid parameter. Type ykre for help";
:: Ykre :: const YKRE_ERROR_NOPIPE : &str = "you must send data using pipe. Type ykre for help";
const YKRE_DESCRIPTION : &str = r"
error : no match found for specified pattern
";
const YKRE_ERROR_INVALID : &str = r"
:: Ykre ::
error : invalid parameter. type ykre for usage
";
const YKRE_ERROR_NOPIPE : &str = r"
:: Ykre ::
error : you must send data using pipe
";
const YKRE_HELP : &str = r"
-----------------------------------------------------------------------------------
:: Ykre :: v0.1 license : MIT - author : a-Sansara
-----------------------------------------------------------------------------------
Ykre is a small program written in `rust` wich purpose is to extract from a list Ykre is a small program written in `rust` wich purpose is to extract from a list
of yaml documents, documents matching a specified condition. Ykre goal is to find of yaml documents, documents matching a specified condition. Ykre goal is to find
specific Kubernetes Resource from the kustomize output. specific Kubernetes Resource from the kustomize output.
Ykre stands for Yaml Kubernetes Resources Ectractor. Ykre stands for Yaml Kubernetes Resources Extractor.
Usage :
ykre SEARCH [DEF]
you MUST use pipe with ykre command
SEARCH - value of kubernetes resource name
DEF - the yaml node to look for
(default : 'metadata.name', dot is the separator for embed nodes)
ex :
# display content of the kubernetes resource 'myResourceName'
cat kubresources.yaml | ykre 'myResourceName'
# write content of the kubernetes resource 'pv-dump' into a file
kustomize build ./config/volumes/local | ykre 'pv-dump' > ./tmp.yaml
# retriew kubernetes pv resources matching 2Gi disk capacity
kustomize build ./config/volumes/dev | ykre 2Gi spec.capacity.storage
"; ";

View File

@ -1,5 +1,6 @@
use std::panic; use std::panic;
use std::env; use std::env;
use std::io;
use std::sync::mpsc::TryRecvError; use std::sync::mpsc::TryRecvError;
use crate::ykre::*; use crate::ykre::*;
@ -43,11 +44,15 @@ pub fn get_data(buf :&mut String, limit :u32) -> bool {
return has_data return has_data
} }
pub fn run() { pub fn run() -> io::Result<()> {
set_panic();
let args: Vec<String> = env::args().collect(); let args: Vec<String> = env::args().collect();
if args.len() == 1 { if args.len() == 1 {
println!("{}", YKRE_HELP); title(YKRE_NAME, YKRE_VERSION, YKRE_LICENSE, YKRE_AUTHOR);
return description(YKRE_DESCRIPTION);
usage();
example();
return Ok(());
} }
else if args.len() > 1 && args.len() <= 3 { else if args.len() > 1 && args.len() <= 3 {
@ -59,9 +64,32 @@ pub fn run() {
}; };
let limit : u32 = env::var("YKRE_LIMIT_ATTEMPT").unwrap_or(format!("{}", YKRE_LIMIT_ATTEMPT).to_owned()).parse::<u32>().unwrap(); let limit : u32 = env::var("YKRE_LIMIT_ATTEMPT").unwrap_or(format!("{}", YKRE_LIMIT_ATTEMPT).to_owned()).parse::<u32>().unwrap();
if get_data(&mut buf, limit) { if get_data(&mut buf, limit) {
return find(search, def, buf); find(search, def, buf);
return Ok(());
} }
panic!(YKRE_ERROR_NOPIPE) panic!(YKRE_ERROR_NOPIPE)
} }
panic!(YKRE_ERROR_INVALID) panic!(YKRE_ERROR_INVALID)
} }
pub fn set_panic() {
panic::set_hook(Box::new(|_info| {
let mut bypass :bool = false;
if let Some(location) = &_info.location() {
bypass = location.file() == PANIC_BYPASS_FILE && location.line() == PANIC_BYPASS_LINE;
}
if !bypass {
//~ println!("{:?}", &_info);
if let Some(s) = &_info.payload().downcast_ref::<&str>() {
if s.len() > 1 {
title(YKRE_NAME, YKRE_VERSION, YKRE_LICENSE, YKRE_AUTHOR);
perror(s);
if *s != &YKRE_ERROR_NOTFOUND {
usage();
println!("");
}
}
}
}
}));
}

19
src/ykre/color.rs Normal file
View File

@ -0,0 +1,19 @@
use colored::*;
pub struct Rgb {
pub r: u8,
pub g: u8,
pub b: u8,
}
impl Rgb {
pub fn new(r: u8, g: u8, b: u8) -> Self {
Self { r, g, b }
}
pub fn fg(self, label: &str) -> ColoredString {
label.truecolor(self.r, self.g, self.b)
}
pub fn bg(self, label: &str) -> ColoredString {
label.on_truecolor(self.r, self.g, self.b)
}
}

76
src/ykre/echo.rs Normal file
View File

@ -0,0 +1,76 @@
use crate::ykre::*;
use colored::*;
use std::borrow::Cow;
pub fn title(label :&str, version :&str, license: &str, author :&str) {
let space = 42+version.len()+label.len()+license.len()+author.len();
let sep = format!("{}", CSEP.fg(&"".repeat(WIDTH+1)));
let titlesep = CTITLESEP.fg(" :: ");
let ptitle = BG.bg(&format!("{}{}{}", titlesep, CTITLE.fg(label), titlesep)).bold();
println!("{}" , sep);
print! (" {} " , ptitle);
print! ("{}" , keyval("version", version, CKEY1, CVAL1).bold());
print! ("{}" , " ".repeat(WIDTH-space));
print! ("{} " , keyval("license", license, CKEY1, CVAL1).bold());
println!("{}" , keyval("author", author, CKEY2, CVAL2).bold());
println!("{}" , sep);
}
pub fn keyval (key :&str, val :&str, ck : Rgb, cv : Rgb) -> Cow<'static, str> {
format!("{} {}", ck.fg(&format!("{} :", key)), cv.fg(val)).into()
}
pub fn description(description :&str) {
println!(" {}", CTEXT.fg(description));
}
pub fn usage() {
let space_arg : usize = 11;
let arg1 : &str = "SEARCH";
let arg2 : &str = "DEF";
println!(" {} :", CUSAGE.fg("Usage").bold());
println!("");
println!(" {}", format!("{} {} {}{}{}",
CPROG.fg(&YKRE_NAME.to_lowercase()),
CARG.fg(&arg1),
COPTSEP.fg("["),
CARG.fg(&arg2),
COPTSEP.fg("]")
).bold());
println!("");
println!(" {}", CTEXT.fg("you MUST use pipe with ykre command"));
println!("");
print! ("{}{} : ", " ".repeat(space_arg-arg1.len()), CARG.fg(arg1).bold());
println!("{}" , CTEXT.fg("value of matching yaml node (kubernetes resource name)"));
println!("");
print! ("{}{} : ", " ".repeat(space_arg-arg2.len()), CARG.fg(arg2).bold());
println!("{}" , CTEXT.fg("the yaml node to look for"));
println!("{}{}" , " ".repeat(space_arg+3), CTEXT.fg("(default : 'metadata.name', dot is the separator for embed nodes)"));
}
pub fn example() {
println!("");
println!(" {} :" , CUSAGE.fg("Examples").bold());
println!("");
println!(" {}", CCOM.fg("# display content of the kubernetes resource 'myResourceName'"));
print! (" {}", format!("{} {} {}", CPROG.fg("cat"), CARG.fg("'./kubresources.yaml'"), COPTSEP.fg("|")).bold());
println!(" {}" , format!("{} {}" , CPROG.fg("ykre"), CARG.fg("'myResourceName'")).bold());
println!("");
println!(" {}", CCOM.fg("# write content of the kubernetes resource 'pv-dump' into a file"));
print! (" {}", format!("{} {} {} {}", CPROG.fg("kustomize"), CARG.fg("build"), CARG.fg("'./config/volumes/local'"), COPTSEP.fg("|")).bold());
println!(" {}" , format!("{} {} {} {}", CPROG.fg("ykre"), CARG.fg("'pv-dump'"), COPTSEP.fg(">"), CSTR.fg("./tmp.yaml")).bold());
println!("");
println!(" {}", CCOM.fg("# retriew kubernetes pv resources matching 2Gi disk capacity"));
print! (" {}", format!("{} {} {} {}", CPROG.fg("kustomize"), CARG.fg("build"), CARG.fg("'./config/volumes/dev'"), COPTSEP.fg("|")).bold());
println!(" {}" , format!("{} {} {}" , CPROG.fg("ykre"), CARG.fg("'2Gi'"), CARG.fg("'spec.capacity.storage'")).bold());
println!("");
}
pub fn perror(msg: &str) {
println!("");
println!(" {} : {}", format!("{}", CERR.fg("error")).bold(), CERRMSG.fg(msg));
println!("");
}