summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin Wernick <justin@worthe-it.co.za>2023-03-12 11:11:41 +0200
committerJustin Wernick <justin@worthe-it.co.za>2023-03-12 11:11:41 +0200
commitde3c59661abe7f38e99ac414bbbf33745434dd31 (patch)
tree980d73acee48fe25350b8f2a90d95c2521779466 /src
parent6268956e826b477a2f6fecde7d1ab701fffb1f58 (diff)
Added an batch mode
Diffstat (limited to 'src')
-rw-r--r--src/main.rs89
-rw-r--r--src/parser.rs1
2 files changed, 62 insertions, 28 deletions
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<String>,
+}
fn prompt() -> Result<(), ShackleError> {
print!("> ");
@@ -19,39 +28,63 @@ fn read_stdin() -> Result<String, ShackleError> {
}
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<ControlFlow<(), ()>, ShackleError> {
+ match user_input.parse::<Command>() {
+ 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::<Command>() {
- 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,