summaryrefslogtreecommitdiff
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
parent6268956e826b477a2f6fecde7d1ab701fffb1f58 (diff)
Added an batch mode
-rw-r--r--Cargo.lock122
-rw-r--r--Cargo.toml1
-rw-r--r--src/main.rs89
-rw-r--r--src/parser.rs1
-rw-r--r--tests/cli.rs2
5 files changed, 186 insertions, 29 deletions
diff --git a/Cargo.lock b/Cargo.lock
index 7c5d618..4fa6c51 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -71,6 +71,43 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
[[package]]
+name = "clap"
+version = "4.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "c3d7ae14b20b94cb02149ed21a86c423859cbe18dc7ed69845cace50e52b40a5"
+dependencies = [
+ "bitflags",
+ "clap_derive",
+ "clap_lex",
+ "is-terminal",
+ "once_cell",
+ "strsim",
+ "termcolor",
+]
+
+[[package]]
+name = "clap_derive"
+version = "4.1.8"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "44bec8e5c9d09e439c4335b1af0abaab56dcf3b94999a936e1bb47b9134288f0"
+dependencies = [
+ "heck",
+ "proc-macro-error",
+ "proc-macro2",
+ "quote",
+ "syn",
+]
+
+[[package]]
+name = "clap_lex"
+version = "0.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "350b9cf31731f9957399229e9b2adc51eeabdfbe9d71d9a0552275fd12710d09"
+dependencies = [
+ "os_str_bytes",
+]
+
+[[package]]
name = "comma"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -153,6 +190,18 @@ dependencies = [
]
[[package]]
+name = "heck"
+version = "0.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8"
+
+[[package]]
+name = "hermit-abi"
+version = "0.3.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "fed44880c466736ef9a5c5b5facefb5ed0785676d0c02d612db14e54f0d84286"
+
+[[package]]
name = "idna"
version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -182,6 +231,18 @@ dependencies = [
]
[[package]]
+name = "is-terminal"
+version = "0.4.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "21b6b32576413a8e69b90e952e4a026476040d81017b80445deda5f2d3921857"
+dependencies = [
+ "hermit-abi",
+ "io-lifetimes",
+ "rustix",
+ "windows-sys 0.45.0",
+]
+
+[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -296,6 +357,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b7e5500299e16ebb147ae15a00a942af264cf3688f47923b8fc2cd5858f23ad3"
[[package]]
+name = "os_str_bytes"
+version = "6.4.1"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "9b7820b9daea5457c9f21c69448905d723fbd21136ccf521748f23fd49e723ee"
+
+[[package]]
name = "percent-encoding"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -341,6 +408,30 @@ dependencies = [
]
[[package]]
+name = "proc-macro-error"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "da25490ff9892aab3fcf7c36f08cfb902dd3e71ca0f9f9517bea02a73a5ce38c"
+dependencies = [
+ "proc-macro-error-attr",
+ "proc-macro2",
+ "quote",
+ "syn",
+ "version_check",
+]
+
+[[package]]
+name = "proc-macro-error-attr"
+version = "1.0.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "a1be40180e52ecc98ad80b184934baf3d0d29f979574e439af5a55274b35f869"
+dependencies = [
+ "proc-macro2",
+ "quote",
+ "version_check",
+]
+
+[[package]]
name = "proc-macro2"
version = "1.0.51"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -429,6 +520,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"assert_cmd",
+ "clap",
"get-port",
"git2",
"nom",
@@ -439,6 +531,12 @@ dependencies = [
]
[[package]]
+name = "strsim"
+version = "0.10.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623"
+
+[[package]]
name = "syn"
version = "1.0.107"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -463,6 +561,15 @@ dependencies = [
]
[[package]]
+name = "termcolor"
+version = "1.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6"
+dependencies = [
+ "winapi-util",
+]
+
+[[package]]
name = "termtree"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -542,6 +649,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "accd4ea62f7bb7a82fe23066fb0957d48ef677f6eeb8215f372f52e48bb32426"
[[package]]
+name = "version_check"
+version = "0.9.4"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f"
+
+[[package]]
name = "wait-timeout"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -567,6 +680,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
+name = "winapi-util"
+version = "0.1.5"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178"
+dependencies = [
+ "winapi",
+]
+
+[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/Cargo.toml b/Cargo.toml
index 75dec3a..81d8115 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -6,6 +6,7 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
+clap = { version = "4.1.8", features = ["derive"] }
git2 = { version = "0.16.1", default-features = false, features = ["vendored-libgit2"] }
nom = "7.1.3"
rexpect = "0.5.0"
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,
diff --git a/tests/cli.rs b/tests/cli.rs
index fcd1437..e642781 100644
--- a/tests/cli.rs
+++ b/tests/cli.rs
@@ -106,7 +106,7 @@ fn can_init_a_new_git_repo() -> Result<()> {
#[test]
fn runs_a_single_command_and_exit_with_cli_flag() -> Result<()> {
let mut c = run_batch_command("git-init another-new-repo")?;
- c.p.exp_string("Successfully created my-new-repo.git")?;
+ c.p.exp_string("Successfully created another-new-repo.git")?;
c.p.exp_eof()?;
Ok(())
}