Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
Add clap for parsing cli args
Christopher Fredén committed 2 years ago
commit 92cbaa6d97ed7be579fc2e1da7ddff71595f117b
parent 54aacc96197a48b79fcc260f94312d824f5e0a34
5 files changed +198 -5
modified Cargo.lock
@@ -527,6 +527,50 @@ dependencies = [
]

[[package]]
+
name = "clap"
+
version = "4.5.0"
+
dependencies = [
+
 "clap_builder",
+
 "clap_derive",
+
]
+

+
[[package]]
+
name = "clap_builder"
+
version = "4.5.0"
+
dependencies = [
+
 "anstream",
+
 "anstyle",
+
 "clap_lex",
+
 "strsim",
+
]
+

+
[[package]]
+
name = "clap_complete"
+
version = "4.5.0"
+
dependencies = [
+
 "clap",
+
 "clap_lex",
+
 "is_executable",
+
 "pathdiff",
+
 "shlex",
+
 "unicode-xid",
+
]
+

+
[[package]]
+
name = "clap_derive"
+
version = "4.5.0"
+
dependencies = [
+
 "heck",
+
 "proc-macro2",
+
 "quote",
+
 "syn 2.0.48",
+
]
+

+
[[package]]
+
name = "clap_lex"
+
version = "0.7.0"
+

+
[[package]]
name = "colorchoice"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1425,6 +1469,12 @@ 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.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1615,6 +1665,15 @@ dependencies = [
]

[[package]]
+
name = "is_executable"
+
version = "1.0.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "fa9acdc6d67b75e626ad644734e8bc6df893d9cd2a834129065d3dd6158ea9c8"
+
dependencies = [
+
 "winapi",
+
]
+

+
[[package]]
name = "itoa"
version = "1.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2063,6 +2122,12 @@ dependencies = [
]

[[package]]
+
name = "pathdiff"
+
version = "0.2.1"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "8835116a5c179084a830efb3adc117ab007512b535bc1a21c991d3b32a6b44dd"
+

+
[[package]]
name = "pbkdf2"
version = "0.12.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -2317,6 +2382,8 @@ version = "0.8.0"
dependencies = [
 "anyhow",
 "chrono",
+
 "clap",
+
 "clap_complete",
 "git-ref-format",
 "lexopt",
 "localtime",
@@ -3104,6 +3171,12 @@ dependencies = [
]

[[package]]
+
name = "strsim"
+
version = "0.11.0"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "5ee073c9e4cd00e28217186dbe12796d692868f432bf2e97ee73bed0c56dfa01"
+

+
[[package]]
name = "subtle"
version = "2.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -3611,6 +3684,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e51733f11c9c4f72aa0c160008246859e340b00807569a0da0e7a1079b27ba85"

[[package]]
+
name = "unicode-xid"
+
version = "0.2.4"
+
source = "registry+https://github.com/rust-lang/crates.io-index"
+
checksum = "f962df74c8c05a667b5ee8bcf162993134c104e96440b663c8daa176dc772d8c"
+

+
[[package]]
name = "universal-hash"
version = "0.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
modified radicle-cli/Cargo.toml
@@ -45,6 +45,9 @@ tree-sitter-bash = { version = "0.20" }
tree-sitter-go = { version = "0.20.0" }
tree-sitter-md = { version = "0.1.5" }
zeroize = { version = "1.1" }
+
clap = { path = "/home/icetan/src/radicle/clap", features = ["derive"] }
+
clap_complete = { path = "/home/icetan/src/radicle/clap/clap_complete", features = ["unstable-dynamic"] }
+


[dependencies.radicle]
version = "0"
added radicle-cli/src/cli.rs
@@ -0,0 +1,109 @@
+
use std::ffi::OsString;
+

+
use anyhow::anyhow;
+
use clap::{CommandFactory, FromArgMatches, Parser, Subcommand, ValueHint};
+
use clap_complete::dynamic::shells::CompleteCommand;
+
use radicle::issue::Issues;
+
use radicle::storage::WriteStorage;
+

+
use crate::terminal as term;
+
use crate::commands::rad_issue;
+
use crate::git::Rev;
+

+
#[derive(Parser, Debug)]
+
#[command(name = "rad")]
+
#[command(about = "The rad CLI", long_about = None)]
+
struct CliArgs {
+
    #[command(subcommand)]
+
    command: Option<Commands>,
+
}
+

+
#[derive(Subcommand, Debug)]
+
enum Commands {
+
    Issue(IssueArgs),
+
}
+

+
#[derive(Parser, Debug)]
+
struct IssueArgs {
+
    #[command(subcommand)]
+
    command: Option<IssueCommands>,
+
}
+

+
#[derive(Subcommand, Debug)]
+
enum IssueCommands {
+
    List,
+
    Show {
+
        #[clap(value_hint = ISSUE_ID_HINT)]
+
        id: String,
+
    },
+
}
+

+
const ISSUE_ID_HINT: ValueHint = ValueHint::Dynamic(get_issue_ids);
+

+
fn get_issue_ids(input: &str) -> Option<Vec<String>> {
+
    let profile = term::profile().ok()?;
+

+
    let (_, rid) = radicle::rad::cwd().ok()?;
+
    let repo = profile.storage.repository_mut(rid).ok()?;
+
    let issues = Issues::open(&repo).ok()?;
+

+
    let completions = issues.all().ok()?
+
        .filter_map(|issue| {
+
            if let Ok((id, _)) = issue {
+
                let id = id.to_string();
+
                if id.starts_with(input) {
+
                    return Some(String::from(id.split_at(8).0));
+
                }
+
            }
+
            None
+
        })
+
        .collect::<Vec<_>>();
+

+
    Some(completions)
+
}
+

+
pub fn completer(args: Vec<OsString>) -> () {
+
    let cmd = CliArgs::command();
+
    let mut cmd = CompleteCommand::augment_subcommands(cmd);
+
    let matches = cmd.clone().get_matches();
+

+
    if let Ok(completions) = CompleteCommand::from_arg_matches(&matches) {
+
        completions.complete(&mut cmd);
+
    } else {
+
        dbg!("COMPLETER FAILED: args: {:?}, matches: {:?}", args, matches);
+
    }
+
}
+

+
pub fn to_issue_options() -> anyhow::Result<rad_issue::Options> {
+
    let args = CliArgs::parse();
+

+
    let options = match args {
+
        CliArgs { command } => match command {
+
            Some(Commands::Issue(IssueArgs {
+
                command: subcommand,
+
            })) => match subcommand {
+
                Some(IssueCommands::List) => Some(rad_issue::Options {
+
                    op: rad_issue::Operation::List {
+
                        assigned: None,
+
                        state: None,
+
                    },
+
                    announce: true,
+
                    quiet: false,
+
                }),
+
                Some(IssueCommands::Show { id }) => Some(rad_issue::Options {
+
                    op: rad_issue::Operation::Show {
+
                        id: Rev::from(id),
+
                        format: term::issue::Format::Full,
+
                        debug: false,
+
                    },
+
                    announce: true,
+
                    quiet: false,
+
                }),
+
                _ => None,
+
            },
+
            _ => None,
+
        },
+
    };
+

+
    options.ok_or(anyhow!("Command not implemented FIXME!"))
+
}
modified radicle-cli/src/lib.rs
@@ -7,3 +7,4 @@ pub mod node;
pub mod pager;
pub mod project;
pub mod terminal;
+
pub mod cli;
modified radicle-cli/src/main.rs
@@ -7,6 +7,7 @@ use anyhow::anyhow;
use radicle::version::Version;
use radicle_cli::commands::*;
use radicle_cli::terminal as term;
+
use radicle_cli::cli;

pub const NAME: &str = "rad";
pub const PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
@@ -225,11 +226,11 @@ fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option<anyhow::Error>>
            );
        }
        "issue" => {
-
            term::run_command_args::<rad_issue::Options, _>(
-
                rad_issue::HELP,
-
                rad_issue::run,
-
                args.to_vec(),
-
            );
+
            let options = cli::to_issue_options()?;
+
            rad_issue::run(options, term::profile()?)?;
+
        }
+
        "complete" => {
+
            cli::completer(args.to_vec());
        }
        "ls" => {
            term::run_command_args::<rad_ls::Options, _>(rad_ls::HELP, rad_ls::run, args.to_vec());