cli: `rad patch --help` opens man page
This is the same behavior as `git`. We also update the man page to have the full list of commands and flags.
This commit is contained in:
parent
b1213931de
commit
8d5299fe85
|
|
@ -12,7 +12,16 @@ rad-patch - Manage radicle patches.
|
||||||
|
|
||||||
== Synopsis
|
== 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
|
== Description
|
||||||
|
|
||||||
|
|
@ -20,13 +29,64 @@ The Radicle *patch* command is used for managing changesets inside of Radicle
|
||||||
repositories.
|
repositories.
|
||||||
|
|
||||||
Though many actions can be performed using *rad patch*, certain patch-related
|
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
|
done using *git push*, while merging a patch is done with a combination of
|
||||||
*git merge* and *git push*.
|
*git merge* and *git push*.
|
||||||
|
|
||||||
To make this possible, Radicle ships with a helper program, *git-remote-rad*
|
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.
|
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
|
== Opening a patch
|
||||||
|
|
||||||
To open a patch, we start by making changes to our working copy, typically on
|
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 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
|
To list all patches, including ones that have been merged or archived, add the
|
||||||
*--all* option.
|
*--all* option.
|
||||||
|
|
||||||
== Other patch commands
|
|
||||||
|
|
||||||
For a full list of patch sub-commands, run *rad patch --help*.
|
|
||||||
|
|
|
||||||
|
|
@ -242,7 +242,10 @@ impl Args for Options {
|
||||||
Long("verbose") | Short('v') => {
|
Long("verbose") | Short('v') => {
|
||||||
verbose = true;
|
verbose = true;
|
||||||
}
|
}
|
||||||
Long("help") | Short('h') => {
|
Long("help") => {
|
||||||
|
return Err(Error::HelpManual.into());
|
||||||
|
}
|
||||||
|
Short('h') => {
|
||||||
return Err(Error::Help.into());
|
return Err(Error::Help.into());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -76,28 +76,30 @@ where
|
||||||
opts
|
opts
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
match err.downcast_ref::<Error>() {
|
let hint = match err.downcast_ref::<Error>() {
|
||||||
Some(Error::Help) => {
|
Some(Error::Help) => {
|
||||||
term::help(help.name, help.version, help.description, help.usage);
|
term::help(help.name, help.version, help.description, help.usage);
|
||||||
process::exit(0);
|
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) => {
|
Some(Error::Usage) => {
|
||||||
term::usage(help.name, help.usage);
|
term::usage(help.name, help.usage);
|
||||||
process::exit(1);
|
process::exit(1);
|
||||||
}
|
}
|
||||||
_ => {}
|
Some(Error::WithHint { hint, .. }) => Some(hint),
|
||||||
|
None => None,
|
||||||
};
|
};
|
||||||
eprintln!(
|
perror(help.name, &err);
|
||||||
"{} {} rad {}: {err}",
|
|
||||||
Paint::red(ERROR_PREFIX),
|
|
||||||
Paint::red("Error:"),
|
|
||||||
help.name,
|
|
||||||
);
|
|
||||||
|
|
||||||
if let Some(Error::WithHint { hint, .. }) = err.downcast_ref::<Error>() {
|
if let Some(hint) = hint {
|
||||||
eprintln!("{}", Paint::yellow(hint));
|
eprintln!("{}", Paint::yellow(hint));
|
||||||
}
|
}
|
||||||
|
|
||||||
process::exit(1);
|
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) {
|
pub fn fail(header: &str, error: &anyhow::Error) {
|
||||||
let err = error.to_string();
|
let err = error.to_string();
|
||||||
let err = err.trim_end();
|
let err = err.trim_end();
|
||||||
|
|
|
||||||
|
|
@ -15,6 +15,9 @@ pub enum Error {
|
||||||
/// If this error is returned from argument parsing, help is displayed.
|
/// If this error is returned from argument parsing, help is displayed.
|
||||||
#[error("help invoked")]
|
#[error("help invoked")]
|
||||||
Help,
|
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.
|
/// If this error is returned from argument parsing, usage is displayed.
|
||||||
#[error("usage invoked")]
|
#[error("usage invoked")]
|
||||||
Usage,
|
Usage,
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use std::ffi::OsStr;
|
use std::ffi::OsStr;
|
||||||
use std::{env, fmt};
|
use std::{env, fmt, io, process};
|
||||||
|
|
||||||
use inquire::ui::{ErrorMessageRenderConfig, StyleSheet, Styled};
|
use inquire::ui::{ErrorMessageRenderConfig, StyleSheet, Styled};
|
||||||
use inquire::InquireError;
|
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}");
|
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) {
|
pub fn usage(name: &str, usage: &str) {
|
||||||
println!(
|
println!(
|
||||||
"{} {}\n{}",
|
"{} {}\n{}",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue