feat: first commit (with new, default)
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -3,10 +3,6 @@
|
||||
# will have compiled files and executables
|
||||
/target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
|
||||
1305
Cargo.lock
generated
Normal file
1305
Cargo.lock
generated
Normal file
File diff suppressed because it is too large
Load Diff
18
Cargo.toml
Normal file
18
Cargo.toml
Normal file
@@ -0,0 +1,18 @@
|
||||
[package]
|
||||
name = "rust-script-tool"
|
||||
version = "0.1.0"
|
||||
authors = ["Hatter Jiang@Pixelbook <jht5945@gmail.com>"]
|
||||
edition = "2018"
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
log = "0.4.11"
|
||||
pretty_env_logger = "0.4.0"
|
||||
clap = "2.33.1"
|
||||
tokio = { version = "0.2.6", features = ["full"] }
|
||||
reqwest = { version = "0.10", features = ["blocking", "json"] }
|
||||
serde = { version = "1.0", features = ["derive"] }
|
||||
serde_json = "1.0"
|
||||
lazy_static = "1.4.0"
|
||||
|
||||
24
crs_template.txt
Normal file
24
crs_template.txt
Normal file
@@ -0,0 +1,24 @@
|
||||
#!/usr/bin/env run-cargo-script
|
||||
// cargo-deps: regex="1.3.9"
|
||||
|
||||
fn main() {
|
||||
unimplemented!("Script is NOT implemented!");
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------ //
|
||||
const RED: &str = "\x1B[91m";
|
||||
const GREEN: &str = "\x1B[92m";
|
||||
const YELLOW: &str = "\x1B[93m";
|
||||
const BOLD: &str = "\x1B[1m";
|
||||
const UNDER: &str = "\x1B[4m";
|
||||
const END: &str = "\x1B[0m";
|
||||
|
||||
fn is_verbose() -> bool { if let Ok(v) = std::env::var("VERBOSE") { v == "1" } else { false } }
|
||||
|
||||
fn exit_with_error() -> ! { std::process::exit(1) }
|
||||
fn exit_with_error_message(msg: &str) -> ! { print_error(msg); exit_with_error() }
|
||||
|
||||
fn print_info (msg: &str) { println!("{b}[INFO ]{e} {m}", b = BOLD, e = END, m = msg); }
|
||||
fn print_ok (msg: &str) { println!("{g}{b}[OK ]{e} {g}{m}{e}", g = GREEN, b = BOLD, e = END, m = msg); }
|
||||
fn print_warn (msg: &str) { println!("{y}{b}[WARN ]{e} {y}{m}{e}", y = YELLOW, b = BOLD, e = END, m = msg); }
|
||||
fn print_error(msg: &str) { println!("{r}{b}[ERROR]{e} {r}{m}{e}", r = RED, b = BOLD, e = END, m = msg); }
|
||||
12
src/cmd.rs
Normal file
12
src/cmd.rs
Normal file
@@ -0,0 +1,12 @@
|
||||
use clap::{ ArgMatches, App, };
|
||||
|
||||
pub type CommandError = Result<(), Box<dyn std::error::Error>>;
|
||||
|
||||
pub trait Command {
|
||||
|
||||
fn name(&self) -> &str;
|
||||
|
||||
fn subcommand<'a>(&self) -> App<'a, 'a>;
|
||||
|
||||
fn run(&self, arg_matches: &ArgMatches, _: &ArgMatches) -> CommandError;
|
||||
}
|
||||
19
src/cmd_default.rs
Normal file
19
src/cmd_default.rs
Normal file
@@ -0,0 +1,19 @@
|
||||
use clap::{ App, Arg, ArgMatches, };
|
||||
use crate::cmd::CommandError;
|
||||
|
||||
pub struct CommandDefault;
|
||||
|
||||
impl CommandDefault {
|
||||
|
||||
pub fn process_command<'a>(app: App<'a, 'a>) -> App<'a, 'a> {
|
||||
app.arg(Arg::with_name("verbose").long("verbose").short("v").multiple(true).help("Show verbose info"))
|
||||
}
|
||||
|
||||
pub fn run(arg_matches: &ArgMatches) -> CommandError {
|
||||
let verbose_count = arg_matches.occurrences_of("verbose");
|
||||
println!("Verbose count: {}", verbose_count);
|
||||
|
||||
error!("Default command is not implemented!");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
35
src/cmd_new.rs
Normal file
35
src/cmd_new.rs
Normal file
@@ -0,0 +1,35 @@
|
||||
use std::fs;
|
||||
use std::fs::File;
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use clap::{ Arg, ArgMatches, SubCommand, App };
|
||||
use crate::{ success, warning };
|
||||
use crate::cmd::{ Command, CommandError };
|
||||
|
||||
const CRS_TEMPLATE: &[u8] = include_bytes!("../crs_template.txt");
|
||||
|
||||
pub struct CommandNew;
|
||||
|
||||
impl Command for CommandNew {
|
||||
fn name(&self) -> &str { "new" }
|
||||
|
||||
fn subcommand<'a>(&self) -> App<'a, 'a> {
|
||||
SubCommand::with_name(self.name()).about("New script subcommand")
|
||||
.arg(Arg::with_name("FILE_NAME").required(true).help("Script file name"))
|
||||
}
|
||||
|
||||
fn run(&self, _arg_matches: &ArgMatches, sub_arg_matches: &ArgMatches) -> CommandError {
|
||||
let file_name = sub_arg_matches.value_of("FILE_NAME").unwrap();
|
||||
if File::open(&file_name).is_ok() {
|
||||
error!("File exists: {}", file_name);
|
||||
return Ok(());
|
||||
}
|
||||
if !file_name.ends_with(".crs") {
|
||||
warning!("File is not ends with .crs");
|
||||
}
|
||||
fs::write(&file_name, CRS_TEMPLATE)?;
|
||||
fs::set_permissions(&file_name, PermissionsExt::from_mode(0o755))?;
|
||||
|
||||
success!("Success, written file: {}", file_name);
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
54
src/main.rs
Normal file
54
src/main.rs
Normal file
@@ -0,0 +1,54 @@
|
||||
#[macro_use] extern crate log;
|
||||
//#[macro_use] extern crate lazy_static;
|
||||
use clap::App;
|
||||
|
||||
mod cmd;
|
||||
mod cmd_default;
|
||||
mod cmd_new;
|
||||
|
||||
use cmd::{ Command, CommandError };
|
||||
use cmd_default::CommandDefault;
|
||||
use cmd_new::CommandNew;
|
||||
|
||||
#[macro_export] macro_rules! success {
|
||||
($($arg:tt)+) => ( crate::print_ok(&format!($($arg)+)); )
|
||||
}
|
||||
#[macro_export] macro_rules! warning {
|
||||
($($arg:tt)+) => ( crate::print_wa(&format!($($arg)+)); )
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn print_ok (msg: &str) {
|
||||
println!("{g}{b}[ OK ]{e} {g}{m}{e}", g = "\x1B[92m", b = "\x1B[1m", e = "\x1B[0m", m = msg);
|
||||
}
|
||||
#[inline]
|
||||
fn print_wa (msg: &str) {
|
||||
println!("{g}{b}[WARN]{e} {g}{m}{e}", g = "\x1B[93m", b = "\x1B[1m", e = "\x1B[0m", m = msg);
|
||||
}
|
||||
|
||||
fn main() -> CommandError {
|
||||
pretty_env_logger::init();
|
||||
info!("rust-script-tool started");
|
||||
|
||||
let commands: Vec<Box<dyn Command>> = vec![
|
||||
Box::new(CommandNew{}),
|
||||
];
|
||||
let mut app = App::new(env!("CARGO_PKG_NAME"))
|
||||
.version(env!("CARGO_PKG_VERSION"))
|
||||
.about(env!("CARGO_PKG_DESCRIPTION"));
|
||||
app = CommandDefault::process_command(app);
|
||||
for command in &commands {
|
||||
app = app.subcommand(command.subcommand());
|
||||
}
|
||||
|
||||
let matches = app.get_matches();
|
||||
for command in &commands {
|
||||
if let Some(sub_cmd_matches) = matches.subcommand_matches(command.name()) {
|
||||
info!("matched subcommand: {}", command.name());
|
||||
return command.run(&matches, sub_cmd_matches);
|
||||
}
|
||||
}
|
||||
|
||||
info!("matched default subcommand");
|
||||
CommandDefault::run(&matches)
|
||||
}
|
||||
Reference in New Issue
Block a user