From de3c59661abe7f38e99ac414bbbf33745434dd31 Mon Sep 17 00:00:00 2001 From: Justin Wernick Date: Sun, 12 Mar 2023 11:11:41 +0200 Subject: Added an batch mode --- src/main.rs | 89 ++++++++++++++++++++++++++++++++++++++++------------------- src/parser.rs | 1 + 2 files changed, 62 insertions(+), 28 deletions(-) (limited to 'src') diff --git a/src/main.rs b/src/main.rs index ebbf23a..ba29032 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,10 +1,19 @@ -use std::{io, io::Write, process}; -use thiserror::Error; - mod git; mod parser; +use clap::Parser; use parser::Command; +use std::{io, io::Write, ops::ControlFlow, process}; +use thiserror::Error; + +/// Shackle Shell - A replacement for git-shell with repo management commands built in. +#[derive(Parser, Debug)] +#[command(author, version, about, long_about = None)] +struct Args { + /// Run a single shell command and exit + #[arg(short, long)] + command: Option, +} fn prompt() -> Result<(), ShackleError> { print!("> "); @@ -19,39 +28,63 @@ fn read_stdin() -> Result { } fn main() -> Result<(), ShackleError> { + let args = Args::parse(); + match args.command { + Some(user_input) => { + run_command(user_input)?; + } + None => { + run_interactive_loop()?; + } + } + + Ok(()) +} + +fn run_command(user_input: String) -> Result, ShackleError> { + match user_input.parse::() { + Err(unknown_input) => { + println!("Unknown input \"{}\"", unknown_input); + } + Ok(Command::Whitespace) => {} + Ok(Command::Exit) => { + return Ok(ControlFlow::Break(())); + } + Ok(Command::GitInit(repo_name)) => { + git::init(&repo_name)?; // TODO should report this error differently + println!("Successfully created {}.git", repo_name); + } + Ok(Command::GitUploadPack(git_dir)) => { + process::Command::new("git") + .args(["upload-pack", &git_dir]) + .spawn()? + .wait()?; + } + Ok(Command::GitReceivePack(git_dir)) => { + process::Command::new("git") + .args(["receive-pack", &git_dir]) + .spawn()? + .wait()?; + } + } + Ok(ControlFlow::Continue(())) +} + +fn run_interactive_loop() -> Result<(), ShackleError> { loop { prompt()?; let user_input = read_stdin()?; - - match user_input.parse::() { - Err(unknown_input) => { - println!("Unknown input \"{}\"", unknown_input); - } - Ok(Command::Whitespace) => {} - Ok(Command::Exit) => { - break; - } - Ok(Command::GitInit(repo_name)) => { - git::init(&repo_name)?; // TODO should report this error differently - println!("Successfully created {}.git", repo_name); - } - Ok(Command::GitUploadPack(git_dir)) => { - process::Command::new("git") - .args(["upload-pack", &git_dir]) - .spawn()? - .wait()?; - } - Ok(Command::GitReceivePack(git_dir)) => { - process::Command::new("git") - .args(["receive-pack", &git_dir]) - .spawn()? - .wait()?; - } + // TODO: should this report errors differently? Most of the errors are from user actions. + let control_flow = run_command(user_input)?; + if control_flow.is_break() { + break; } } Ok(()) } +pub enum FlowControl {} + #[derive(Error, Debug)] pub enum ShackleError { #[error(transparent)] diff --git a/src/parser.rs b/src/parser.rs index 64ebf5b..75ac333 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -10,6 +10,7 @@ use nom::{ }; use std::str::FromStr; +// TODO: It might work well to use clap and parse_from for this particular case #[derive(Clone)] pub enum Command { Whitespace, -- cgit v1.2.3