cli: add `rad patch show`
Show patch information with `rad patch show`. Signed-off-by: Slack Coder <slackcoder@server.ky>
This commit is contained in:
parent
f5cb86dabd
commit
2295bb4ea4
|
|
@ -62,4 +62,16 @@ define power requirements b9bb418c6f5 R0 9dad201 (flux-capacitor-power) ahead 1,
|
|||
|
||||
Nothing to show.
|
||||
|
||||
$ rad patch show b9bb418c6f504ee91e54c555bdc8fc37b4d9b28b
|
||||
|
||||
patch b9bb418c6f504ee91e54c555bdc8fc37b4d9b28b
|
||||
|
||||
╭─ define power requirements ───────
|
||||
|
||||
No description provided.
|
||||
|
||||
╰───────────────────────────────────
|
||||
|
||||
9dad201 Define power requirements
|
||||
|
||||
```
|
||||
|
|
|
|||
|
|
@ -4,6 +4,8 @@ mod common;
|
|||
mod create;
|
||||
#[path = "patch/list.rs"]
|
||||
mod list;
|
||||
#[path = "patch/show.rs"]
|
||||
mod show;
|
||||
|
||||
use std::ffi::OsString;
|
||||
use std::str::FromStr;
|
||||
|
|
@ -50,9 +52,19 @@ pub enum OptPatch {
|
|||
Patch(PatchId),
|
||||
}
|
||||
|
||||
impl From<OptPatch> for Option<PatchId> {
|
||||
fn from(opt: OptPatch) -> Self {
|
||||
match opt {
|
||||
OptPatch::Patch(patch_id) => Some(patch_id),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Default, PartialEq, Eq)]
|
||||
pub enum OperationName {
|
||||
Open,
|
||||
Show,
|
||||
Update,
|
||||
#[default]
|
||||
List,
|
||||
|
|
@ -63,6 +75,9 @@ pub enum Operation {
|
|||
Open {
|
||||
message: Comment,
|
||||
},
|
||||
Show {
|
||||
patch_id: PatchId,
|
||||
},
|
||||
Update {
|
||||
patch_id: OptPatch,
|
||||
message: Comment,
|
||||
|
|
@ -79,6 +94,14 @@ pub struct Options {
|
|||
pub verbose: bool,
|
||||
}
|
||||
|
||||
fn parse_patch_id(val: OsString) -> Result<OptPatch, anyhow::Error> {
|
||||
let val = val
|
||||
.to_str()
|
||||
.ok_or_else(|| anyhow!("patch id specified is not UTF-8"))?;
|
||||
let patch_id = PatchId::from_str(val).map_err(|_| anyhow!("invalid patch id '{}'", val))?;
|
||||
Ok(OptPatch::Patch(patch_id))
|
||||
}
|
||||
|
||||
impl Args for Options {
|
||||
fn from_args(args: Vec<OsString>) -> anyhow::Result<(Self, Vec<OsString>)> {
|
||||
use lexopt::prelude::*;
|
||||
|
|
@ -88,7 +111,7 @@ impl Args for Options {
|
|||
let mut op: Option<OperationName> = None;
|
||||
let mut verbose = false;
|
||||
let mut sync = true;
|
||||
let mut id = OptPatch::default();
|
||||
let mut patch_id = OptPatch::default();
|
||||
let mut message = Comment::default();
|
||||
let mut push = true;
|
||||
|
||||
|
|
@ -137,19 +160,16 @@ impl Args for Options {
|
|||
Value(val) if op.is_none() => match val.to_string_lossy().as_ref() {
|
||||
"l" | "list" => op = Some(OperationName::List),
|
||||
"o" | "open" => op = Some(OperationName::Open),
|
||||
"s" | "show" => op = Some(OperationName::Show),
|
||||
"u" | "update" => op = Some(OperationName::Update),
|
||||
|
||||
unknown => anyhow::bail!("unknown operation '{}'", unknown),
|
||||
},
|
||||
Value(val) if op == Some(OperationName::Update) && id == OptPatch::Any => {
|
||||
let val = val
|
||||
.to_str()
|
||||
.ok_or_else(|| anyhow!("patch id specified is not UTF-8"))?;
|
||||
|
||||
id = OptPatch::Patch(
|
||||
PatchId::from_str(val)
|
||||
.map_err(|_| anyhow!("invalid patch id '{}'", val))?,
|
||||
);
|
||||
Value(val) if op == Some(OperationName::Show) && patch_id == OptPatch::Any => {
|
||||
patch_id = parse_patch_id(val)?;
|
||||
}
|
||||
Value(val) if op == Some(OperationName::Update) && patch_id == OptPatch::Any => {
|
||||
patch_id = parse_patch_id(val)?;
|
||||
}
|
||||
_ => return Err(anyhow::anyhow!(arg.unexpected())),
|
||||
}
|
||||
|
|
@ -158,10 +178,11 @@ impl Args for Options {
|
|||
let op = match op.unwrap_or_default() {
|
||||
OperationName::Open => Operation::Open { message },
|
||||
OperationName::List => Operation::List,
|
||||
OperationName::Update => Operation::Update {
|
||||
patch_id: id,
|
||||
message,
|
||||
OperationName::Show => Operation::Show {
|
||||
patch_id: Option::from(patch_id)
|
||||
.ok_or_else(|| anyhow!("a patch id must be provided"))?,
|
||||
},
|
||||
OperationName::Update => Operation::Update { patch_id, message },
|
||||
};
|
||||
|
||||
Ok((
|
||||
|
|
@ -198,6 +219,9 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
|||
Operation::List => {
|
||||
list::run(&storage, &profile, Some(workdir), options)?;
|
||||
}
|
||||
Operation::Show { ref patch_id } => {
|
||||
show::run(&storage, &profile, &workdir, patch_id)?;
|
||||
}
|
||||
Operation::Update {
|
||||
ref patch_id,
|
||||
ref message,
|
||||
|
|
|
|||
|
|
@ -238,23 +238,8 @@ pub fn run(
|
|||
anyhow::bail!("a title must be given");
|
||||
}
|
||||
|
||||
let title_pretty = &term::format::dim(format!("╭─ {} ───────", title));
|
||||
|
||||
term::blank();
|
||||
term::print(title_pretty);
|
||||
term::blank();
|
||||
|
||||
if description.is_empty() {
|
||||
term::print(term::format::italic("No description provided."));
|
||||
} else {
|
||||
term::markdown(&description);
|
||||
}
|
||||
|
||||
term::blank();
|
||||
term::print(term::format::dim(format!(
|
||||
"╰{}",
|
||||
"─".repeat(term::text_width(title_pretty) - 1)
|
||||
)));
|
||||
term::patch::print_title_desc(title, &description);
|
||||
term::blank();
|
||||
|
||||
if !confirm("Create patch?", &options) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
use super::common::*;
|
||||
use super::*;
|
||||
|
||||
use crate::terminal as term;
|
||||
use radicle::cob::patch;
|
||||
use radicle::git;
|
||||
use radicle::prelude::*;
|
||||
use radicle::storage::git::Repository;
|
||||
|
||||
pub fn run(
|
||||
storage: &Repository,
|
||||
profile: &Profile,
|
||||
workdir: &git::raw::Repository,
|
||||
patch_id: &PatchId,
|
||||
) -> anyhow::Result<()> {
|
||||
let patches = patch::Patches::open(profile.public_key, storage)?;
|
||||
let Some(patch) = patches.get(patch_id)? else {
|
||||
anyhow::bail!("Patch `{}` not found", patch_id);
|
||||
};
|
||||
|
||||
term::blank();
|
||||
term::print(format!("patch {}", patch_id));
|
||||
term::blank();
|
||||
|
||||
term::patch::print_title_desc(patch.title(), patch.description().unwrap_or(""));
|
||||
term::blank();
|
||||
|
||||
let target_head = patch_merge_target_oid(patch.target(), storage)?;
|
||||
let base_oid = workdir.merge_base(target_head, **patch.head())?;
|
||||
let commits = patch_commits(workdir, &base_oid, patch.head())?;
|
||||
term::patch::list_commits(&commits)?;
|
||||
term::blank();
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -84,3 +84,22 @@ pub fn print_commits_ahead_behind(
|
|||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Print title and description in a text box.
|
||||
pub fn print_title_desc(title: &str, description: &str) {
|
||||
let title_pretty = &term::format::dim(format!("╭─ {} ───────", title));
|
||||
term::print(title_pretty);
|
||||
term::blank();
|
||||
|
||||
if description.is_empty() {
|
||||
term::print(term::format::italic("No description provided."));
|
||||
} else {
|
||||
term::markdown(description);
|
||||
}
|
||||
|
||||
term::blank();
|
||||
term::print(term::format::dim(format!(
|
||||
"╰{}",
|
||||
"─".repeat(term::text_width(title_pretty) - 1)
|
||||
)));
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue