Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: Show timeline in `patch show`
Alexis Sellier committed 3 years ago
commit 6b44955cd95c12f4bad9bbbb012086d7bdec871d
parent ed4c266a51cd696ec7dd7a223920ec9a0fbc9857
6 files changed +93 -66
modified radicle-cli/examples/rad-patch.md
@@ -51,14 +51,16 @@ $ rad patch
```
```
$ rad patch show 191a14e520f2eeff7c0e3ee0a5523c5217eecb89
-
╭──────────────────────────────────────────────────────────────────╮
-
│ Title   Define power requirements                                │
-
│ Patch   191a14e520f2eeff7c0e3ee0a5523c5217eecb89                 │
-
│ Author  did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi │
-
│ Status  open                                                     │
-
│                                                                  │
-
│ See details.                                                     │
-
╰──────────────────────────────────────────────────────────────────╯
+
╭─────────────────────────────────────────────────────────────────────────────────────────╮
+
│ Title   Define power requirements                                                       │
+
│ Patch   191a14e520f2eeff7c0e3ee0a5523c5217eecb89                                        │
+
│ Author  did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi                        │
+
│ Status  open                                                                            │
+
│                                                                                         │
+
│ See details.                                                                            │
+
├─────────────────────────────────────────────────────────────────────────────────────────┤
+
│ ● opened by did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi (you) 3 months ago │
+
╰─────────────────────────────────────────────────────────────────────────────────────────╯

commit 3e674d1a1df90807e934f9ae5da2591dd6848a33
Author: radicle <radicle@localhost>
modified radicle-cli/examples/workflow/4-patching-contributor.md
@@ -49,14 +49,16 @@ $ rad patch
│ ● opened by did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (you) 3 months ago │
╰─────────────────────────────────────────────────────────────────────────────────────────╯
$ rad patch show a07ef7743a32a2e902672ea3526d1db6ee08108a
-
╭──────────────────────────────────────────────────────────────────╮
-
│ Title   Define power requirements                                │
-
│ Patch   a07ef7743a32a2e902672ea3526d1db6ee08108a                 │
-
│ Author  did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk │
-
│ Status  open                                                     │
-
│                                                                  │
-
│ See details.                                                     │
-
╰──────────────────────────────────────────────────────────────────╯
+
╭─────────────────────────────────────────────────────────────────────────────────────────╮
+
│ Title   Define power requirements                                                       │
+
│ Patch   a07ef7743a32a2e902672ea3526d1db6ee08108a                                        │
+
│ Author  did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk                        │
+
│ Status  open                                                                            │
+
│                                                                                         │
+
│ See details.                                                                            │
+
├─────────────────────────────────────────────────────────────────────────────────────────┤
+
│ ● opened by did:key:z6Mkt67GdsW7715MEfRuP4pSZxJRJh6kj6Y48WRqVv4N1tRk (you) 3 months ago │
+
╰─────────────────────────────────────────────────────────────────────────────────────────╯

commit 3e674d1a1df90807e934f9ae5da2591dd6848a33
Author: radicle <radicle@localhost>
modified radicle-cli/src/commands/patch.rs
@@ -215,7 +215,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
        }
        Operation::Show { patch_id } => {
            let patch_id = patch_id.resolve(&repository.backend)?;
-
            show::run(&repository, &workdir, &patch_id)?;
+
            show::run(&profile, &repository, &workdir, &patch_id)?;
        }
        Operation::Update {
            ref patch_id,
modified radicle-cli/src/commands/patch/common.rs
@@ -96,7 +96,7 @@ pub fn pretty_sync_status(
/// For example '<oid> (branch1[, branch2])'.
pub fn pretty_commit_version(
    revision_oid: &Oid,
-
    repo: &Option<git::raw::Repository>,
+
    repo: Option<&git::raw::Repository>,
) -> anyhow::Result<term::Line> {
    let oid = term::format::secondary(term::format::oid(*revision_oid));
    let mut line = term::Line::new(oid);
modified radicle-cli/src/commands/patch/list.rs
@@ -1,6 +1,6 @@
use anyhow::anyhow;

-
use radicle::cob::patch::{Patch, PatchId, Patches, Verdict};
+
use radicle::cob::patch::{Patch, PatchId, Patches, Revision, Verdict};
use radicle::git;
use radicle::prelude::*;
use radicle::profile::Profile;
@@ -40,65 +40,82 @@ pub fn run(
    }

    for (id, patch) in &mut own {
-
        print(&me, id, patch, &workdir, repository)?;
+
        widget(&me, id, patch, workdir.as_ref(), repository)?.print();
    }
    for (id, patch) in &mut other {
-
        print(profile.id(), id, patch, &workdir, repository)?;
+
        widget(profile.id(), id, patch, workdir.as_ref(), repository)?.print();
    }

    Ok(())
}

-
/// Print patch details.
-
fn print(
-
    whoami: &PublicKey,
+
pub fn header(
    patch_id: &PatchId,
    patch: &Patch,
-
    workdir: &Option<git::raw::Repository>,
+
    workdir: Option<&git::raw::Repository>,
    repository: &Repository,
-
) -> anyhow::Result<()> {
+
    revision: &Revision,
+
) -> anyhow::Result<term::Line> {
    let target_head = common::patch_merge_target_oid(patch.target(), repository)?;
+
    let header = term::Line::spaced([
+
        term::format::bold(patch.title()).into(),
+
        term::format::highlight(term::format::cob(patch_id)).into(),
+
        term::format::dim(format!("R{}", patch.version())).into(),
+
    ])
+
    .space()
+
    .extend(common::pretty_commit_version(&revision.head(), workdir)?)
+
    .space()
+
    .extend(common::pretty_sync_status(
+
        repository.raw(),
+
        revision.head().into(),
+
        target_head,
+
    )?);
+

+
    Ok(header)
+
}
+

+
/// Patch widget.
+
pub fn widget<'a>(
+
    whoami: &PublicKey,
+
    patch_id: &PatchId,
+
    patch: &Patch,
+
    workdir: Option<&git::raw::Repository>,
+
    repository: &Repository,
+
) -> anyhow::Result<term::VStack<'a>> {
+
    let (_, revision) = patch
+
        .latest()
+
        .ok_or_else(|| anyhow!("patch is malformed: no revisions found"))?;
+
    let header = header(patch_id, patch, workdir, repository, revision)?;
+
    let mut widget = term::VStack::default()
+
        .child(header)
+
        .divider()
+
        .border(Some(term::colors::FAINT));

+
    for line in timeline(whoami, patch_id, patch, repository)? {
+
        widget.push(line);
+
    }
+
    Ok(widget)
+
}
+

+
pub fn timeline(
+
    whoami: &PublicKey,
+
    patch_id: &PatchId,
+
    patch: &Patch,
+
    repository: &Repository,
+
) -> anyhow::Result<Vec<term::Line>> {
    let you = patch.author().id().as_key() == whoami;
-
    let mut author_info = term::Line::spaced([
+
    let mut open = term::Line::spaced([
        term::format::positive("●").into(),
        term::format::default("opened by").into(),
        term::format::tertiary(patch.author().id()).into(),
    ]);

    if you {
-
        author_info.push(term::Label::space());
-
        author_info.push(term::format::primary("(you)"));
+
        open.push(term::Label::space());
+
        open.push(term::format::primary("(you)"));
    }
-
    author_info.push(term::Label::space());
-
    author_info.push(term::format::dim(term::format::timestamp(
-
        &patch.timestamp(),
-
    )));
+
    let mut timeline = vec![(patch.timestamp(), open)];

-
    let (_, revision) = patch
-
        .latest()
-
        .ok_or_else(|| anyhow!("patch is malformed: no revisions found"))?;
-
    let mut widget = term::VStack::default()
-
        .child(
-
            term::Line::spaced([
-
                term::format::bold(patch.title()).into(),
-
                term::format::highlight(term::format::cob(patch_id)).into(),
-
                term::format::dim(format!("R{}", patch.version())).into(),
-
            ])
-
            .space()
-
            .extend(common::pretty_commit_version(&revision.head(), workdir)?)
-
            .space()
-
            .extend(common::pretty_sync_status(
-
                repository.raw(),
-
                revision.head().into(),
-
                target_head,
-
            )?),
-
        )
-
        .divider()
-
        .child(author_info)
-
        .border(Some(term::colors::FAINT));
-

-
    let mut timeline = Vec::new();
    for (revision_id, revision) in patch.revisions() {
        // Don't show an "update" line for the first revision.
        if **revision_id != **patch_id {
@@ -176,12 +193,12 @@ fn print(
    }
    timeline.sort_by_key(|(t, _)| *t);

+
    let mut lines = Vec::new();
    for (time, mut line) in timeline.into_iter() {
        line.push(term::Label::space());
        line.push(term::format::dim(term::format::timestamp(&time)));
-
        widget.push(line);
+
        lines.push(line);
    }
-
    widget.print();

-
    Ok(())
+
    Ok(lines)
}
modified radicle-cli/src/commands/patch/show.rs
@@ -35,11 +35,13 @@ fn show_patch_diff(
}

pub fn run(
-
    storage: &Repository,
+
    profile: &Profile,
+
    stored: &Repository,
+
    // TODO: Should be optional.
    workdir: &git::raw::Repository,
    patch_id: &PatchId,
) -> anyhow::Result<()> {
-
    let patches = patch::Patches::open(storage)?;
+
    let patches = patch::Patches::open(stored)?;
    let Some(patch) = patches.get(patch_id)? else {
        anyhow::bail!("Patch `{patch_id}` not found");
    };
@@ -66,7 +68,7 @@ pub fn run(
    ]);

    let description = patch.description().trim();
-
    let meta = VStack::default()
+
    let mut widget = VStack::default()
        .border(Some(term::colors::FAINT))
        .child(attrs)
        .children(if !description.is_empty() {
@@ -76,12 +78,16 @@ pub fn run(
            ]
        } else {
            vec![]
-
        });
+
        })
+
        .divider();

-
    meta.print();
+
    for line in list::timeline(profile.id(), patch_id, &patch, stored)? {
+
        widget.push(line);
+
    }
+
    widget.print();
    term::blank();

-
    show_patch_diff(&patch, storage, workdir)?;
+
    show_patch_diff(&patch, stored, workdir)?;
    term::blank();

    Ok(())