Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli/follow: Use clap
✗ CI failure Erik Kundt committed 6 months ago
commit 9cec1370d0f1af67f4701fa56155a3cd15fe49ae
parent cb6a0c17d3f407b58ba4e250ae75c24d67a8ca35
2 failed (2 total) View logs
4 files changed +116 -95
modified crates/radicle-cli/src/commands/follow.rs
@@ -1,106 +1,94 @@
-
use std::ffi::OsString;
-

-
use anyhow::anyhow;
+
mod args;

use radicle::node::{policy, Alias, AliasStore, Handle, NodeId};
use radicle::{prelude::*, Node};
use radicle_term::{Element as _, Paint, Table};

use crate::terminal as term;
-
use crate::terminal::args::{Args, Error, Help};
-

-
pub const HELP: Help = Help {
-
    name: "follow",
-
    description: "Manage node follow policies",
-
    version: env!("RADICLE_VERSION"),
-
    usage: r#"
-
Usage
-

-
    rad follow [<nid>] [--alias <name>] [<option>...]
-

-
    The `follow` command will print all nodes being followed, optionally filtered by alias, if no
-
    Node ID is provided.
-
    Otherwise, it takes a Node ID, optionally in DID format, and updates the follow policy
-
    for that peer, optionally giving the peer the alias provided.
-

-
Options
-

-
    --alias <name>         Associate an alias to a followed peer
-
    --verbose, -v          Verbose output
-
    --help                 Print help
-
"#,
-
};
-

-
#[derive(Debug)]
-
pub enum Operation {
-
    Follow { nid: NodeId, alias: Option<Alias> },
-
    List { alias: Option<Alias> },
-
}
-

-
#[derive(Debug, Default)]
-
pub enum OperationName {
-
    Follow,
-
    #[default]
-
    List,
-
}
-

-
#[derive(Debug)]
-
pub struct Options {
-
    pub op: Operation,
-
    pub verbose: bool,
-
}
-

-
impl Args for Options {
-
    fn from_args(args: Vec<OsString>) -> anyhow::Result<(Self, Vec<OsString>)> {
-
        use lexopt::prelude::*;
-

-
        let mut parser = lexopt::Parser::from_args(args);
-
        let mut verbose = false;
-
        let mut nid: Option<NodeId> = None;
-
        let mut alias: Option<Alias> = None;
-

-
        while let Some(arg) = parser.next()? {
-
            match &arg {
-
                Value(val) if nid.is_none() => {
-
                    if let Ok(did) = term::args::did(val) {
-
                        nid = Some(did.into());
-
                    } else if let Ok(val) = term::args::nid(val) {
-
                        nid = Some(val);
-
                    } else {
-
                        anyhow::bail!("invalid Node ID `{}` specified", val.to_string_lossy());
-
                    }
-
                }
-
                Long("alias") if alias.is_none() => {
-
                    let name = parser.value()?;
-
                    let name = term::args::alias(&name)?;
-

-
                    alias = Some(name.to_owned());
-
                }
-
                Long("verbose") | Short('v') => verbose = true,
-
                Long("help") | Short('h') => {
-
                    return Err(Error::Help.into());
-
                }
-
                _ => {
-
                    return Err(anyhow!(arg.unexpected()));
-
                }
-
            }
-
        }
-

-
        let op = match nid {
-
            Some(nid) => Operation::Follow { nid, alias },
-
            None => Operation::List { alias },
-
        };
-
        Ok((Options { op, verbose }, vec![]))
-
    }
-
}

-
pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
+
pub use args::Args;
+
pub(crate) use args::ABOUT;
+

+
// pub const HELP: Help = Help {
+
//     name: "follow",
+
//     description: "Manage node follow policies",
+
//     version: env!("RADICLE_VERSION"),
+
//     usage: r#"
+
// Usage
+

+
//     rad follow [<nid>] [--alias <name>] [<option>...]
+

+
//     The `follow` command will print all nodes being followed, optionally filtered by alias, if no
+
//     Node ID is provided.
+
//     Otherwise, it takes a Node ID, optionally in DID format, and updates the follow policy
+
//     for that peer, optionally giving the peer the alias provided.
+

+
// Options
+

+
//     --alias <name>         Associate an alias to a followed peer
+
//     --verbose, -v          Verbose output
+
//     --help                 Print help
+
// "#,
+
// };
+

+
// #[derive(Debug, Default)]
+
// pub enum OperationName {
+
//     Follow,
+
//     #[default]
+
//     List,
+
// }
+

+
// impl Args for Options {
+
//     fn from_args(args: Vec<OsString>) -> anyhow::Result<(Self, Vec<OsString>)> {
+
//         use lexopt::prelude::*;
+

+
//         let mut parser = lexopt::Parser::from_args(args);
+
//         let mut verbose = false;
+
//         let mut nid: Option<NodeId> = None;
+
//         let mut alias: Option<Alias> = None;
+

+
//         while let Some(arg) = parser.next()? {
+
//             match &arg {
+
//                 Value(val) if nid.is_none() => {
+
//                     if let Ok(did) = term::args::did(val) {
+
//                         nid = Some(did.into());
+
//                     } else if let Ok(val) = term::args::nid(val) {
+
//                         nid = Some(val);
+
//                     } else {
+
//                         anyhow::bail!("invalid Node ID `{}` specified", val.to_string_lossy());
+
//                     }
+
//                 }
+
//                 Long("alias") if alias.is_none() => {
+
//                     let name = parser.value()?;
+
//                     let name = term::args::alias(&name)?;
+

+
//                     alias = Some(name.to_owned());
+
//                 }
+
//                 Long("verbose") | Short('v') => verbose = true,
+
//                 Long("help") | Short('h') => {
+
//                     return Err(Error::Help.into());
+
//                 }
+
//                 _ => {
+
//                     return Err(anyhow!(arg.unexpected()));
+
//                 }
+
//             }
+
//         }
+

+
//         let op = match nid {
+
//             Some(nid) => Operation::Follow { nid, alias },
+
//             None => Operation::List { alias },
+
//         };
+
//         Ok((Options { op, verbose }, vec![]))
+
//     }
+
// }
+

+
pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
    let profile = ctx.profile()?;
    let mut node = radicle::Node::new(profile.socket());

-
    match options.op {
-
        Operation::Follow { nid, alias } => follow(nid, alias, &mut node, &profile)?,
-
        Operation::List { alias } => following(&profile, alias)?,
+
    match args.nid {
+
        Some(nid) => follow(nid, args.alias, &mut node, &profile)?,
+
        None => following(&profile, args.alias)?,
    }

    Ok(())
added crates/radicle-cli/src/commands/follow/args.rs
@@ -0,0 +1,27 @@
+
use clap::Parser;
+

+
use radicle::node::{Alias, NodeId};
+

+
use crate::args;
+

+
pub(crate) const ABOUT: &str = "Manage node follow policies";
+

+
const LONG_ABOUT: &str = r#"
+
The `follow` command will print all nodes being followed, optionally filtered by alias, if no
+
Node ID is provided.
+
Otherwise, it takes a Node ID, optionally in DID format, and updates the follow policy
+
for that peer, optionally giving the peer the alias provided.
+
"#;
+

+
#[derive(Parser, Debug)]
+
#[command(about = ABOUT, long_about = LONG_ABOUT, disable_version_flag = true)]
+
pub struct Args {
+
    #[arg(global = true, value_parser = args::parse_nid)]
+
    pub(crate) nid: Option<NodeId>,
+

+
    #[arg(long, global = true)]
+
    pub(crate) alias: Option<Alias>,
+

+
    #[arg(long, global = true)]
+
    pub verbose: bool,
+
}
modified crates/radicle-cli/src/commands/help.rs
@@ -91,7 +91,10 @@ const COMMANDS: &[CommandItem] = &[
    },
    CommandItem::Lexopt(crate::commands::rad_self::HELP),
    CommandItem::Lexopt(crate::commands::seed::HELP),
-
    CommandItem::Lexopt(crate::commands::follow::HELP),
+
    CommandItem::Clap {
+
        name: "follow",
+
        about: crate::commands::follow::ABOUT,
+
    },
    CommandItem::Lexopt(crate::commands::unblock::HELP),
    CommandItem::Clap {
        name: "unfollow",
modified crates/radicle-cli/src/main.rs
@@ -50,6 +50,7 @@ enum Commands {
    Clean(clean::Args),
    Clone(clone::Args),
    Debug(debug::Args),
+
    Follow(follow::Args),
    Fork(fork::Args),
    Init(init::Args),
    Issue(issue::Args),
@@ -220,7 +221,9 @@ pub(crate) fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option<anyho
            }
        }
        "follow" => {
-
            term::run_command_args::<follow::Options, _>(follow::HELP, follow::run, args.to_vec());
+
            if let Some(Commands::Follow(args)) = CliArgs::parse().command {
+
                term::run_command_fn(follow::run, args);
+
            }
        }
        "fork" => {
            if let Some(Commands::Fork(args)) = CliArgs::parse().command {