Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: `rad patch --help` opens man page
cloudhead committed 2 years ago
commit 8d5299fe85c8a88d0604b4b21885585a0b567187
parent b1213931de839587901ca482ece2e3aa2d0ae606
5 files changed +100 -19
modified rad-patch.1.adoc
@@ -12,7 +12,16 @@ rad-patch - Manage radicle patches.

== Synopsis

-
*rad patch* *
+
*rad patch* [<option>...] +
+
*rad patch* _list_ [--all|--merged|--open|--archived|--draft] [<option>...] +
+
*rad patch* _show_ <patch-id> [<option>...] +
+
*rad patch* _archive_ <patch-id> [<option>...] +
+
*rad patch* _update_ <patch-id> [<option>...] +
+
*rad patch* _checkout_ <patch-id> [<option>...] +
+
*rad patch* _delete_ <patch-id> [<option>...] +
+
*rad patch* _redact_ <revision-id> [<option>...] +
+
*rad patch* _ready_ <patch-id> [--undo] [<option>...] +
+
*rad patch* _edit_ <patch-id> [<option>...] +

== Description

@@ -20,13 +29,64 @@ The Radicle *patch* command is used for managing changesets inside of Radicle
repositories.

Though many actions can be performed using *rad patch*, certain patch-related
-
actions require using *git* directly. For example, opening a patch is typically
+
actions use *git* directly. For example, opening a patch is typically
done using *git push*, while merging a patch is done with a combination of
*git merge* and *git push*.

To make this possible, Radicle ships with a helper program, *git-remote-rad*
which is invoked by *git* on push and fetch to and from Radicle remotes.

+
== Commands
+

+
With no arguments, *rad patch* defaults to the _list_ command, showing the list of
+
open patches for the current repository.
+

+
=== show
+

+
Shows information on the given patch.
+

+
*<patch-id>*::                       The patch to show
+
*--patch*, *-p*::                    Show the patch changes in git patch format
+
*--verbose*, *-v*::                  Show additional information about the patch
+

+
=== edit
+

+
Edits a patch revision comment. To edit the patch title or description, pass
+
in the *<patch-id>*. To edit a revision comment, pass that revision's
+
*<revision-id>*.
+

+
*<revision-id>*::
+
The revision to edit.
+

+
*--message*, *-m [<string>]*::
+
Comment message to the patch or revision. If omitted, Radicle will prompt for
+
a comment string via *$EDITOR*.
+

+
=== list
+

+
List patches in the current repository. The default is *--open*.
+

+
*--all*::                  List all patches, including merged and archived patches
+
*--archived*::             List only archived patches
+
*--merged*::               List only merged patches
+
*--open*::                 List only open patches
+
*--draft*::                List only draft patches
+

+
=== ready
+

+
Mark a patch as ready to review. This changes the state of a patch from *draft*
+
to *open*.
+

+
*--undo*::                 Change a patch back to *draft*
+

+
=== update
+

+
Updates a patch to the current repository *HEAD*. This is a low-level command
+
that should only be used when using *git push rad* is not possible.
+

+
*--message*, *-m [<string>]*::   Provide a comment message to the revision
+
*--no-message*::                 Leave the revision comment message blank
+

== Opening a patch

To open a patch, we start by making changes to our working copy, typically on
@@ -148,7 +208,3 @@ our master branch. Then we pushed to our *rad* remote.
To list patches, run *rad patch*. By default, this will only show open patches.
To list all patches, including ones that have been merged or archived, add the
*--all* option.
-

-
== Other patch commands
-

-
For a full list of patch sub-commands, run *rad patch --help*.
modified radicle-cli/src/commands/patch.rs
@@ -242,7 +242,10 @@ impl Args for Options {
                Long("verbose") | Short('v') => {
                    verbose = true;
                }
-
                Long("help") | Short('h') => {
+
                Long("help") => {
+
                    return Err(Error::HelpManual.into());
+
                }
+
                Short('h') => {
                    return Err(Error::Help.into());
                }

modified radicle-cli/src/terminal.rs
@@ -76,28 +76,30 @@ where
            opts
        }
        Err(err) => {
-
            match err.downcast_ref::<Error>() {
+
            let hint = match err.downcast_ref::<Error>() {
                Some(Error::Help) => {
                    term::help(help.name, help.version, help.description, help.usage);
                    process::exit(0);
                }
+
                Some(Error::HelpManual) => {
+
                    let Ok(status) = term::manual(help.name) else {
+
                        perror(help.name, "failed to load manual page");
+
                        process::exit(1);
+
                    };
+
                    process::exit(status.code().unwrap_or(0));
+
                }
                Some(Error::Usage) => {
                    term::usage(help.name, help.usage);
                    process::exit(1);
                }
-
                _ => {}
+
                Some(Error::WithHint { hint, .. }) => Some(hint),
+
                None => None,
            };
-
            eprintln!(
-
                "{} {} rad {}: {err}",
-
                Paint::red(ERROR_PREFIX),
-
                Paint::red("Error:"),
-
                help.name,
-
            );
-

-
            if let Some(Error::WithHint { hint, .. }) = err.downcast_ref::<Error>() {
+
            perror(help.name, &err);
+

+
            if let Some(hint) = hint {
                eprintln!("{}", Paint::yellow(hint));
            }
-

            process::exit(1);
        }
    };
@@ -123,6 +125,15 @@ pub fn profile() -> Result<Profile, anyhow::Error> {
    }
}

+
pub fn perror(name: &str, err: impl std::fmt::Display) {
+
    eprintln!(
+
        "{} {} rad {}: {err}",
+
        Paint::red(ERROR_PREFIX),
+
        Paint::red("Error:"),
+
        name,
+
    );
+
}
+

pub fn fail(header: &str, error: &anyhow::Error) {
    let err = error.to_string();
    let err = err.trim_end();
modified radicle-cli/src/terminal/args.rs
@@ -15,6 +15,9 @@ pub enum Error {
    /// If this error is returned from argument parsing, help is displayed.
    #[error("help invoked")]
    Help,
+
    /// If this error is returned from argument parsing, the manual page is displayed.
+
    #[error("help manual invoked")]
+
    HelpManual,
    /// If this error is returned from argument parsing, usage is displayed.
    #[error("usage invoked")]
    Usage,
modified radicle-term/src/io.rs
@@ -1,5 +1,5 @@
use std::ffi::OsStr;
-
use std::{env, fmt};
+
use std::{env, fmt, io, process};

use inquire::ui::{ErrorMessageRenderConfig, StyleSheet, Styled};
use inquire::InquireError;
@@ -123,6 +123,14 @@ pub fn help(name: &str, version: &str, description: &str, usage: &str) {
    println!("rad-{name} {version}\n{description}\n{usage}");
}

+
pub fn manual(name: &str) -> io::Result<process::ExitStatus> {
+
    let mut child = process::Command::new("man")
+
        .arg(format!("rad-{name}"))
+
        .spawn()?;
+

+
    child.wait()
+
}
+

pub fn usage(name: &str, usage: &str) {
    println!(
        "{} {}\n{}",