Skip to content

Commit 9f9a25a

Browse files
committed
add new repl to cli when no command is given
Signed-off-by: Michael Lodder <[email protected]>
1 parent 9b7acb3 commit 9f9a25a

File tree

43 files changed

+880
-204
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

43 files changed

+880
-204
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,3 +12,4 @@ Cargo.lock
1212

1313
# MSVC Windows builds of rustc generate these, which store debugging information
1414
*.pdb
15+
.idea/

cli/Cargo.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ async-trait = "0.1"
2121
best-practices.workspace = true
2222
bs.workspace = true
2323
clap = { version = "4.5.36", features = ["cargo"] }
24+
colored = "3.0.0"
25+
csv = "1.3.1"
2426
directories = "6.0.0"
2527
ed25519-dalek = "2.1.1"
2628
elliptic-curve.workspace = true
@@ -36,6 +38,7 @@ provenance-log.workspace = true
3638
rand.workspace = true
3739
rand_core_6.workspace = true
3840
rng.workspace = true
41+
rustyline = { version = "15.0.0", features = ["derive"] }
3942
serde = { workspace = true, optional = true }
4043
serde_cbor.workspace = true
4144
serde_json.workspace = true

cli/src/bin/bs.rs

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -54,34 +54,7 @@ struct Opt {
5454

5555
/// Subcommand
5656
#[structopt(subcommand)]
57-
cmd: Command,
58-
}
59-
60-
#[derive(Debug, StructOpt)]
61-
enum Command {
62-
/// Config commands
63-
#[structopt(name = "config")]
64-
Config {
65-
/// Config sub-command
66-
#[structopt(subcommand)]
67-
cmd: Option<subcmds::config::Command>,
68-
},
69-
/*
70-
/// Key operations
71-
#[structopt(name = "key")]
72-
Key {
73-
/// Key subcommand
74-
#[structopt(subcommand)]
75-
cmd: KeyCommand,
76-
},
77-
*/
78-
/// Provenance log operations
79-
#[structopt(name = "plog")]
80-
Plog {
81-
/// Provenance log subcommand
82-
#[structopt(subcommand)]
83-
cmd: Box<subcmds::plog::Command>,
84-
},
57+
cmd: Option<Command>,
8558
}
8659

8760
/*
@@ -114,10 +87,13 @@ async fn main() -> Result<(), Error> {
11487
let config = Config::from_path(opt.config, opt.keyfile, opt.sshagent, opt.sshagentenv)?;
11588

11689
let ret = match opt.cmd {
117-
// process a config command
118-
Command::Config { cmd } => subcmds::config::go(cmd, &config).await,
119-
// process a plog command
120-
Command::Plog { cmd } => subcmds::plog::go(*cmd, &config).await,
90+
Some(cmd) => match cmd {
91+
// process a config command
92+
Command::Config { cmd } => subcmds::config::go(cmd, &config).await,
93+
// process a plog command
94+
Command::Plog { cmd } => subcmds::plog::go(*cmd, &config).await,
95+
},
96+
None => repl::ReplHelper::run().await,
12197
};
12298

12399
if let Err(ref e) = ret {

cli/src/cmds.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
use crate::subcmds;
2+
use structopt::StructOpt;
3+
4+
/// CLI commands for BetterSign
5+
#[derive(Debug, StructOpt)]
6+
pub enum Command {
7+
/// Config commands
8+
#[structopt(name = "config")]
9+
Config {
10+
/// Config sub-command
11+
#[structopt(subcommand)]
12+
cmd: Option<subcmds::config::Command>,
13+
},
14+
/*
15+
/// Key operations
16+
#[structopt(name = "key")]
17+
Key {
18+
/// Key subcommand
19+
#[structopt(subcommand)]
20+
cmd: KeyCommand,
21+
},
22+
*/
23+
/// Provenance log operations
24+
#[structopt(name = "plog")]
25+
Plog {
26+
/// Provenance log subcommand
27+
#[structopt(subcommand)]
28+
cmd: Box<subcmds::plog::Command>,
29+
},
30+
}

cli/src/error.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,10 @@ pub enum Error {
6767
#[error("Deserialization error: {0}")]
6868
Deserialization(String),
6969

70+
/// Rustyline error
71+
#[error(transparent)]
72+
RustylineReadLineError(#[from] rustyline::error::ReadlineError),
73+
7074
/// No valid application config path found
7175
#[error("No valid config path found")]
7276
NoHome,

cli/src/keychain.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -39,16 +39,28 @@ impl fmt::Display for KeyEntry {
3939
msg.push_str(&format!("╭──── pubkey {}\n", kh));
4040
msg.push_str(&format!("├───── codec {}\n", self.pubkey.codec()));
4141
msg.push_str(&format!("├─── comment {}\n", self.pubkey.comment));
42-
msg.push_str(&format!("├─ threshold {} of {}\n", self.threshold, self.secret_keys.len()));
42+
msg.push_str(&format!(
43+
"├─ threshold {} of {}\n",
44+
self.threshold,
45+
self.secret_keys.len()
46+
));
4347
msg.push_str("╰─┬── shares\n");
4448
for i in (0..self.secret_keys.len()).rev() {
4549
let skh = {
4650
let cv = self.secret_keys[i].conv_view().unwrap();
4751
let pk = cv.to_public_key().unwrap();
4852
let fv = pk.fingerprint_view().unwrap();
49-
EncodedMultihash::new(Base::Base32Lower, fv.fingerprint(Codec::Sha3256).unwrap())
53+
EncodedMultihash::new(
54+
Base::Base32Lower,
55+
fv.fingerprint(Codec::Sha3256).unwrap(),
56+
)
5057
};
51-
let key = format!("{} / {} {}", (self.secret_keys.len() - i), self.secret_keys.len(), skh);
58+
let key = format!(
59+
"{} / {} {}",
60+
(self.secret_keys.len() - i),
61+
self.secret_keys.len(),
62+
skh
63+
);
5264
if i == 0 {
5365
msg.push_str(&format!(" ╰─── {}\n", key));
5466
} else {

cli/src/lib.rs

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,14 @@ pub use ssh_agent::SshAgent;
3636

3737
/// cli subcommands
3838
pub mod subcmds;
39+
40+
/// cli commands
41+
pub mod cmds;
42+
pub use cmds::Command;
43+
44+
/// cli repl
45+
pub mod repl;
46+
3947
pub use subcmds::prelude::*;
4048

4149
/// ...and in the darkness bind them

0 commit comments

Comments
 (0)