Radish alpha
h
rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5
Radicle Heartwood Protocol & Stack
Radicle
Git
cli: Fix `id` COB notifications in `rad inbox`
Merged did:key:z6MksFqX...wzpT opened 2 years ago
5 files changed +86 -5 eff40166 c63aaace
modified radicle-cli/examples/rad-inbox.md
@@ -106,3 +106,35 @@ $ rad inbox clear --all
$ rad inbox clear --all
Your inbox is empty.
```
+

+
Now let's do an identity update.
+

+
``` ~alice
+
$ rad id update --title "Modify description" --description "Use website" --payload xyz.radicle.project description '"https://radicle.xyz"' -q
+
[..]
+
$ rad sync -a
+
✓ Synced with 1 node(s)
+
```
+

+
``` ~bob
+
$ rad inbox --all
+
╭──────────────────────────────────────────────────────────────────────╮
+
│ heartwood                                                            │
+
├──────────────────────────────────────────────────────────────────────┤
+
│ 001   ●   [ ... ]   Modify description   id   accepted   alice   now │
+
╰──────────────────────────────────────────────────────────────────────╯
+
$ rad inbox show 1
+
{
+
  "payload": {
+
    "xyz.radicle.project": {
+
      "defaultBranch": "master",
+
      "description": "https://radicle.xyz",
+
      "name": "heartwood"
+
    }
+
  },
+
  "delegates": [
+
    "did:key:z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi"
+
  ],
+
  "threshold": 1
+
}
+
```
modified radicle-cli/src/commands/inbox.rs
@@ -1,9 +1,11 @@
use std::ffi::OsString;
+
use std::path::Path;
use std::process;

use anyhow::anyhow;

use localtime::LocalTime;
+
use radicle::identity::Identity;
use radicle::issue::Issues;
use radicle::node::notifications;
use radicle::node::notifications::*;
@@ -298,6 +300,26 @@ where
                        patch.title().to_owned(),
                        term::format::patch::state(patch.state()),
                    )
+
                } else if type_name == *cob::identity::TYPENAME {
+
                    let Ok(identity) = Identity::get(&id, &repo) else {
+
                        log::error!(
+
                            target: "cli",
+
                            "Error retrieving identity {id} for notification {}", n.id
+
                        );
+
                        continue;
+
                    };
+
                    let Some(rev) = n.update.new().and_then(|id| identity.revision(&id)) else {
+
                        log::error!(
+
                            target: "cli",
+
                            "Error retrieving identity revision for notification {}", n.id
+
                        );
+
                        continue;
+
                    };
+
                    (
+
                        String::from("id"),
+
                        rev.title.clone(),
+
                        term::format::identity::state(&rev.state),
+
                    )
                } else {
                    (
                        type_name.to_string(),
@@ -395,6 +417,11 @@ fn show(

            term::patch::show(&patch, &id, false, &repo, None, profile)?;
        }
+
        NotificationKind::Cob { type_name, id } if type_name == *cob::identity::TYPENAME => {
+
            let identity = Identity::get(&id, &repo)?;
+

+
            term::json::to_pretty(&identity.doc, Path::new("radicle.json"))?.print();
+
        }
        NotificationKind::Branch { .. } => {
            let refstr = if let Some(remote) = n.remote {
                n.qualified
@@ -409,8 +436,8 @@ fn show(
                .spawn()?
                .wait()?;
        }
-
        _ => {
-
            todo!();
+
        notification => {
+
            term::json::to_pretty(&notification, Path::new("notification.json"))?.print();
        }
    }
    notifs.set_status(NotificationStatus::ReadAt(LocalTime::now()), &[id])?;
modified radicle-cli/src/terminal/format.rs
@@ -277,6 +277,22 @@ pub mod patch {
    }
}

+
/// Identity formatting
+
pub mod identity {
+
    use super::*;
+
    use radicle::cob::identity::State;
+

+
    /// Format identity revision state.
+
    pub fn state(s: &State) -> term::Paint<String> {
+
        match s {
+
            State::Active { .. } => term::format::tertiary(s.to_string()),
+
            State::Accepted { .. } => term::format::positive(s.to_string()),
+
            State::Rejected { .. } => term::format::negative(s.to_string()),
+
            State::Stale { .. } => term::format::dim(s.to_string()),
+
        }
+
    }
+
}
+

#[cfg(test)]
mod test {
    use super::*;
modified radicle-node/src/worker/fetch.rs
@@ -170,6 +170,11 @@ fn notify(
                // Don't notify about signed refs.
                continue;
            }
+
            if r == *git::refs::storage::IDENTITY_BRANCH {
+
                // Don't notify about the peers's identity branch pointer, since there will
+
                // be a separate notification on the identity COB itself.
+
                continue;
+
            }
            if let Some(rest) = r.strip_prefix(git::refname!("refs/heads/patches")) {
                if radicle::cob::ObjectId::from_str(rest.as_str()).is_ok() {
                    // Don't notify about patch branches, since we already get
modified radicle/src/node/notifications.rs
@@ -1,6 +1,7 @@
pub mod store;

use localtime::LocalTime;
+
use serde::Serialize;
use sqlite as sql;
use thiserror::Error;

@@ -19,7 +20,7 @@ pub type StoreReader = Store<store::Read>;
/// Unique identifier for a notification.
pub type NotificationId = u32;

-
#[derive(Debug, PartialEq, Eq, Clone)]
+
#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
pub enum NotificationStatus {
    ReadAt(LocalTime),
    Unread,
@@ -32,7 +33,7 @@ impl NotificationStatus {
}

/// A notification for an updated ref.
-
#[derive(Debug, PartialEq, Eq, Clone)]
+
#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
pub struct Notification {
    /// Unique notification ID.
    pub id: NotificationId,
@@ -53,7 +54,7 @@ pub struct Notification {
}

/// Type of notification.
-
#[derive(Debug, PartialEq, Eq, Clone)]
+
#[derive(Debug, PartialEq, Eq, Clone, Serialize)]
pub enum NotificationKind {
    /// A COB changed.
    Cob { type_name: TypeName, id: ObjectId },