Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
cli/publish: Use clap
Merged lorenz opened 7 months ago

See issue/7fb03f234030b91c38cc4f5b48bd30cf5fd6a1de.

5 files changed +37 -67 8c1073b9 8c1073b9
modified crates/radicle-cli/examples/rad-help.md
@@ -22,6 +22,7 @@ Common `rad` commands used in various situations:
	node         Control and query the Radicle Node
	patch        Manage patches
	path         Display the Radicle home path
+
	publish      Publish a repository to the network
	clean        Remove all remotes from a repository
	self         Show information about your identity and device
	seed         Manage repository seeding policies
modified crates/radicle-cli/src/commands/help.rs
@@ -60,6 +60,10 @@ const COMMANDS: &[CommandItem] = &[
        about: crate::commands::path::ABOUT,
    },
    CommandItem::Clap {
+
        name: "publish",
+
        about: crate::commands::publish::ABOUT,
+
    },
+
    CommandItem::Clap {
        name: "clean",
        about: crate::commands::clean::ABOUT,
    },
modified crates/radicle-cli/src/commands/publish.rs
@@ -1,75 +1,20 @@
-
use std::ffi::OsString;
+
mod args;

use anyhow::{anyhow, Context as _};

use radicle::cob;
use radicle::identity::{Identity, Visibility};
use radicle::node::Handle as _;
-
use radicle::prelude::RepoId;
use radicle::storage::{SignRepository, ValidateRepository, WriteRepository, WriteStorage};

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

-
pub const HELP: Help = Help {
-
    name: "publish",
-
    description: "Publish a repository to the network",
-
    version: env!("RADICLE_VERSION"),
-
    usage: r#"
-
Usage
+
pub use args::Args;
+
pub(crate) use args::ABOUT;

-
    rad publish [<rid>] [<option>...]
-

-
    Publishing a private repository makes it public and discoverable
-
    on the network.
-

-
    By default, this command will publish the current repository.
-
    If an `<rid>` is specified, that repository will be published instead.
-

-
    Note that this command can only be run for repositories with a
-
    single delegate. The delegate must be the currently authenticated
-
    user. For repositories with more than one delegate, the `rad id`
-
    command must be used.
-

-
Options
-

-
    --help                    Print help
-
"#,
-
};
-

-
#[derive(Default, Debug)]
-
pub struct Options {
-
    pub rid: Option<RepoId>,
-
}
-

-
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 rid = None;
-

-
        while let Some(arg) = parser.next()? {
-
            match arg {
-
                Long("help") | Short('h') => {
-
                    return Err(Error::Help.into());
-
                }
-
                Value(val) if rid.is_none() => {
-
                    rid = Some(term::args::rid(&val)?);
-
                }
-
                arg => {
-
                    return Err(anyhow!(arg.unexpected()));
-
                }
-
            }
-
        }
-

-
        Ok((Options { rid }, vec![]))
-
    }
-
}
-

-
pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
+
pub fn run(args: Args, ctx: impl term::Context) -> anyhow::Result<()> {
    let profile = ctx.profile()?;
-
    let rid = match options.rid {
+
    let rid = match args.rid {
        Some(rid) => rid,
        None => radicle::rad::cwd()
            .map(|(_, rid)| rid)
@@ -81,7 +26,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
    let doc = identity.doc();

    if doc.is_public() {
-
        return Err(Error::WithHint {
+
        return Err(term::Error::WithHint {
            err: anyhow!("repository is already public"),
            hint: "to announce the repository to the network, run `rad sync --inventory`",
        }
@@ -91,7 +36,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
        return Err(anyhow!("only the repository delegate can publish it"));
    }
    if doc.delegates().len() > 1 {
-
        return Err(Error::WithHint {
+
        return Err(term::Error::WithHint {
            err: anyhow!(
                "only repositories with a single delegate can be published with this command"
            ),
added crates/radicle-cli/src/commands/publish/args.rs
@@ -0,0 +1,21 @@
+
pub(crate) const ABOUT: &str = "Publish a repository to the network";
+

+
const LONG_ABOUT: &str = r#"
+
Publishing a private repository makes it public and discoverable
+
on the network.
+

+
By default, this command will publish the current repository.
+
If an `<rid>` is specified, that repository will be published instead.
+

+
Note that this command can only be run for repositories with a
+
single delegate. The delegate must be the currently authenticated
+
user. For repositories with more than one delegate, the `rad id`
+
command must be used."#;
+

+
#[derive(Debug, clap::Parser)]
+
#[command(about = ABOUT, long_about = LONG_ABOUT, disable_version_flag = true)]
+
pub struct Args {
+
    /// The Repository ID of the repository to publish
+
    #[arg(value_name = "RID")]
+
    pub(super) rid: Option<radicle::identity::RepoId>,
+
}
modified crates/radicle-cli/src/main.rs
@@ -48,6 +48,7 @@ enum Commands {
    Clean(clean::Args),
    Issue(issue::Args),
    Path(path::Args),
+
    Publish(publish::Args),
    Stats(stats::Args),
    Unfollow(unfollow::Args),
    Unseed(unseed::Args),
@@ -247,11 +248,9 @@ pub(crate) fn run_other(exe: &str, args: &[OsString]) -> Result<(), Option<anyho
            }
        }
        "publish" => {
-
            term::run_command_args::<publish::Options, _>(
-
                publish::HELP,
-
                publish::run,
-
                args.to_vec(),
-
            );
+
            if let Some(Commands::Publish(args)) = CliArgs::parse().command {
+
                term::run_command_fn(publish::run, args);
+
            }
        }
        "clean" => {
            if let Some(Commands::Clean(args)) = CliArgs::parse().command {