Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: Add `rad cob list` subcommand
Lars Wirzenius committed 2 years ago
commit b1337854498b6989cb24e09b45013a8f0eef2596
parent 504a198cecab3217b46d0dd13ae8e969f1b0a19f
3 files changed +165 -9
added radicle-cli/examples/rad-cob.md
@@ -0,0 +1,121 @@
+
Handle arbitrary COBs.
+

+
First create an issue.
+

+
```
+
$ rad issue open --title "flux capacitor underpowered" --description "Flux capacitor power requirements exceed current supply" --no-announce
+
╭─────────────────────────────────────────────────────────╮
+
│ Title   flux capacitor underpowered                     │
+
│ Issue   42028af21fabc09bfac2f25490f119f7c7e11542        │
+
│ Author  z6MknSL…StBU8Vi (you)                           │
+
│ Status  open                                            │
+
│                                                         │
+
│ Flux capacitor power requirements exceed current supply │
+
╰─────────────────────────────────────────────────────────╯
+
```
+

+
The issue is now listed under our project.
+

+
```
+
$ rad issue list
+
╭─────────────────────────────────────────────────────────────────────────────────────────────────────────╮
+
│ ●   ID        Title                         Author                    Labels   Assignees   Opened       │
+
├─────────────────────────────────────────────────────────────────────────────────────────────────────────┤
+
│ ●   42028af   flux capacitor underpowered   z6MknSL…StBU8Vi   (you)                        [    ..    ] │
+
╰─────────────────────────────────────────────────────────────────────────────────────────────────────────╯
+
```
+

+
Let's create a patch, too.
+

+
```
+
$ git checkout -b flux-capacitor-power
+
$ touch REQUIREMENTS
+
$ git add REQUIREMENTS
+
$ git commit -v -m "Define power requirements"
+
[flux-capacitor-power 3e674d1] Define power requirements
+
 1 file changed, 0 insertions(+), 0 deletions(-)
+
 create mode 100644 REQUIREMENTS
+
$ git push rad -o patch.message="Define power requirements" -o patch.message="See details." HEAD:refs/patches
+
```
+

+
Patch can be listed.
+

+
```
+
$ rad patch
+
╭──────────────────────────────────────────────────────────────────────────────────────────────╮
+
│ ●  ID       Title                      Author                  Head     +   -   Updated      │
+
├──────────────────────────────────────────────────────────────────────────────────────────────┤
+
│ ●  73b73f3  Define power requirements  z6MknSL…StBU8Vi  (you)  3e674d1  +0  -0  [   ...    ] │
+
╰──────────────────────────────────────────────────────────────────────────────────────────────╯
+
```
+

+
Both issue and patch COBs can be listed.
+

+
```
+
$ rad cob list --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --type xyz.radicle.issue
+
42028af21fabc09bfac2f25490f119f7c7e11542
+
$ rad cob list --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --type xyz.radicle.patch
+
73b73f376e93e09e0419664766ac9e433bf7d389
+
```
+

+
We can look at the issue COB.
+

+
```
+
$ rad cob show --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --type xyz.radicle.issue --object 42028af21fabc09bfac2f25490f119f7c7e11542
+
commit 42028af21fabc09bfac2f25490f119f7c7e11542
+
parent 175267b8910895ba87760313af254c2900743912
+
author z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
date   Thu, 15 Dec 2022 17:28:04 +0000
+

+
    {
+
      "body": "Flux capacitor power requirements exceed current supply",
+
      "type": "comment"
+
    }
+

+
    {
+
      "assignees": [],
+
      "type": "assign"
+
    }
+

+
    {
+
      "title": "flux capacitor underpowered",
+
      "type": "edit"
+
    }
+

+
    {
+
      "labels": [],
+
      "type": "label"
+
    }
+

+
```
+

+
We can look at the patch COB too.
+

+
```
+
$ rad cob show --repo rad:z42hL2jL4XNk6K8oHQaSWfMgCL7ji --type xyz.radicle.patch --object 73b73f376e93e09e0419664766ac9e433bf7d389
+
commit 73b73f376e93e09e0419664766ac9e433bf7d389
+
parent 175267b8910895ba87760313af254c2900743912
+
parent 3e674d1a1df90807e934f9ae5da2591dd6848a33
+
parent f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354
+
author z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi
+
date   Thu, 15 Dec 2022 17:28:04 +0000
+

+
    {
+
      "base": "f2de534b5e81d7c6e2dcaf58c3dd91573c0a0354",
+
      "description": "See details.",
+
      "oid": "3e674d1a1df90807e934f9ae5da2591dd6848a33",
+
      "type": "revision"
+
    }
+

+
    {
+
      "target": "delegates",
+
      "title": "Define power requirements",
+
      "type": "edit"
+
    }
+

+
    {
+
      "labels": [],
+
      "type": "label"
+
    }
+

+
```
modified radicle-cli/src/commands/cob.rs
@@ -3,9 +3,11 @@ use std::str::FromStr;

use anyhow::anyhow;
use chrono::prelude::*;
+
use nonempty::NonEmpty;
use radicle::cob;
use radicle::prelude::Id;
use radicle::storage::ReadStorage;
+
use radicle_cob::object::collaboration::list;

use crate::git::Rev;
use crate::terminal as term;
@@ -19,10 +21,12 @@ pub const HELP: Help = Help {
Usage

    rad cob <command> [<option>...]
+
    rad cob list --repo <rid> --type <typename>
    rad cob show --repo <rid> --type <typename> --object <oid>

Commands

+
    list       List all COBs of a given type (--object is not needed)
    show       Show a COB as raw operations

Options
@@ -31,15 +35,20 @@ Options
"#,
};

-
enum Operation {
+
enum OperationName {
+
    List,
    Show,
}

+
enum Operation {
+
    List,
+
    Show(Rev),
+
}
+

pub struct Options {
    rid: Id,
    op: Operation,
    type_name: cob::TypeName,
-
    oid: Rev,
}

impl Args for Options {
@@ -47,7 +56,7 @@ impl Args for Options {
        use lexopt::prelude::*;

        let mut parser = lexopt::Parser::from_args(args);
-
        let mut op: Option<Operation> = None;
+
        let mut op: Option<OperationName> = None;
        let mut type_name: Option<cob::TypeName> = None;
        let mut oid: Option<Rev> = None;
        let mut rid: Option<Id> = None;
@@ -55,7 +64,8 @@ impl Args for Options {
        while let Some(arg) = parser.next()? {
            match arg {
                Value(val) if op.is_none() => match val.to_string_lossy().as_ref() {
-
                    "s" | "show" => op = Some(Operation::Show),
+
                    "l" | "list" => op = Some(OperationName::List),
+
                    "s" | "show" => op = Some(OperationName::Show),
                    unknown => anyhow::bail!("unknown operation '{unknown}'"),
                },
                Long("type") | Short('t') => {
@@ -86,9 +96,14 @@ impl Args for Options {

        Ok((
            Options {
-
                op: op.ok_or_else(|| anyhow!("a command must be specified"))?,
-
                oid: oid
-
                    .ok_or_else(|| anyhow!("an object id must be specified with `--object`"))?,
+
                op: {
+
                    match op.ok_or_else(|| anyhow!("a command must be specified"))? {
+
                        OperationName::List => Operation::List,
+
                        OperationName::Show => Operation::Show(oid.ok_or_else(|| {
+
                            anyhow!("an object id must be specified with `--object")
+
                        })?),
+
                    }
+
                },
                rid: rid
                    .ok_or_else(|| anyhow!("a repository id must be specified with `--repo`"))?,
                type_name: type_name
@@ -105,8 +120,14 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
    let repo = storage.repository(options.rid)?;

    match options.op {
-
        Operation::Show => {
-
            let oid = options.oid.resolve(&repo.backend)?;
+
        Operation::List => {
+
            let cobs = list::<NonEmpty<cob::Entry>, _>(&repo, &options.type_name)?;
+
            for cob in cobs {
+
                println!("{}", cob.id);
+
            }
+
        }
+
        Operation::Show(oid) => {
+
            let oid = oid.resolve(&repo.backend)?;
            let ops = cob::store::ops(&oid, &options.type_name, &repo)?;

            for op in ops.into_iter().rev() {
modified radicle-cli/tests/commands.rs
@@ -95,6 +95,20 @@ fn rad_issue() {
}

#[test]
+
fn rad_cob() {
+
    let mut environment = Environment::new();
+
    let profile = environment.profile("alice");
+
    let home = &profile.home;
+
    let working = environment.tmp().join("working");
+

+
    // Setup a test repository.
+
    fixtures::repository(&working);
+

+
    test("examples/rad-init.md", &working, Some(home), []).unwrap();
+
    test("examples/rad-cob.md", &working, Some(home), []).unwrap();
+
}
+

+
#[test]
fn rad_label() {
    let mut environment = Environment::new();
    let profile = environment.profile("alice");