Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
Update Rust toolchain to 1.74
cloudhead committed 2 years ago
commit d4ec2176bbbec9eac876af5bd06c46e651c64b14
parent 79644941bdfd595456e3b66a7d6630fcac9c7699
35 files changed +154 -97
modified Cargo.toml
@@ -25,6 +25,7 @@ default-members = [
  "radicle-remote-helper",
  "radicle-term",
]
+
resolver = "2"

[profile.container]
inherits = "release"
modified radicle-cli/src/commands/issue.rs
@@ -589,13 +589,13 @@ fn edit<'a, 'g, R: WriteRepository + cob::Store, G: radicle::crypto::Signer>(
    }

    // Editing via the editor.
-
    let Some((title, description)) =
-
        term::issue::get_title_description(
-
            Some(title.unwrap_or(issue.title().to_owned())),
-
            Some(description.unwrap_or(issue.description().to_owned())),
-
        )? else {
-
            return Ok(issue);
-
        };
+
    let Some((title, description)) = term::issue::get_title_description(
+
        Some(title.unwrap_or(issue.title().to_owned())),
+
        Some(description.unwrap_or(issue.description().to_owned())),
+
    )?
+
    else {
+
        return Ok(issue);
+
    };

    issue.transaction("Edit", signer, |tx| {
        tx.edit(title)?;
modified radicle-cli/src/commands/label.rs
@@ -86,7 +86,7 @@ fn label(
            let labels = issue
                .labels()
                .cloned()
-
                .chain(options.labels.into_iter())
+
                .chain(options.labels)
                .collect::<Vec<_>>();

            issue.label(labels, &signer)?;
@@ -103,7 +103,7 @@ fn label(
            let labels = patch
                .labels()
                .cloned()
-
                .chain(options.labels.into_iter())
+
                .chain(options.labels)
                .collect::<Vec<_>>();

            patch.label(labels, &signer)?;
modified radicle-cli/src/commands/unlabel.rs
@@ -83,8 +83,8 @@ fn unlabel(
        Ok(mut issue) => {
            let labels = issue
                .labels()
+
                .filter(|&l| !options.labels.contains(l))
                .cloned()
-
                .filter(|l| !options.labels.contains(l))
                .collect::<Vec<_>>();
            issue.label(labels, &signer)?;

@@ -99,8 +99,8 @@ fn unlabel(
        Ok(mut patch) => {
            let labels = patch
                .labels()
+
                .filter(|&l| !options.labels.contains(l))
                .cloned()
-
                .filter(|l| !options.labels.contains(l))
                .collect::<Vec<_>>();
            patch.label(labels, &signer)?;

modified radicle-cli/src/git/unified_diff.rs
@@ -439,10 +439,10 @@ impl Decode for Hunk<Modification> {
            }

            let Some(line) = Modification::try_decode(r)? else {
-
                    return Err(Error::syntax(format!(
-
                        "expected '{}' old lines and '{}' new lines, but found '{}' and '{}'",
-
                        header.old_size, header.new_size, old_line, new_line,
-
                    )));
+
                return Err(Error::syntax(format!(
+
                    "expected '{}' old lines and '{}' new lines, but found '{}' and '{}'",
+
                    header.old_size, header.new_size, old_line, new_line,
+
                )));
            };

            let line = match line {
modified radicle-cli/src/terminal/args.rs
@@ -123,7 +123,7 @@ pub fn rid(val: &OsString) -> anyhow::Result<Id> {
pub fn pubkey(val: &OsString) -> anyhow::Result<NodeId> {
    let Ok(did) = did(val) else {
        let nid = nid(val)?;
-
        return Ok(nid)
+
        return Ok(nid);
    };
    Ok(did.as_key().to_owned())
}
modified radicle-cli/src/terminal/highlight.rs
@@ -142,10 +142,8 @@ impl Builder {
                    let name = HIGHLIGHTS[h.0];

                    self.advance();
-
                    self.styles.push(
-
                        term::Style::default()
-
                            .fg(theme.highlight(name).unwrap_or(term::Color::default())),
-
                    );
+
                    self.styles
+
                        .push(term::Style::default().fg(theme.highlight(name).unwrap_or_default()));
                }
                ts::HighlightEvent::HighlightEnd => {
                    self.advance();
modified radicle-crypto/src/lib.rs
@@ -284,7 +284,7 @@ pub enum PublicKeyError {

impl PartialOrd for PublicKey {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
-
        self.0.as_ref().partial_cmp(other.as_ref())
+
        Some(self.cmp(other))
    }
}

modified radicle-fetch/src/stage.rs
@@ -511,12 +511,13 @@ fn special_refs_updates<'a>(
            }
            refs::ReceivedRefname::RadId => None,
        })
-
        .fold(BTreeMap::new(), |mut acc, (remote_id, tip, name)| {
-
            acc.entry(*remote_id)
-
                .or_insert_with(Vec::new)
-
                .push((tip, name));
-
            acc
-
        });
+
        .fold(
+
            BTreeMap::<PublicKey, Vec<_>>::new(),
+
            |mut acc, (remote_id, tip, name)| {
+
                acc.entry(*remote_id).or_default().push((tip, name));
+
                acc
+
            },
+
        );

    let mut updates = Updates::default();

modified radicle-fetch/src/state.rs
@@ -267,7 +267,7 @@ impl FetchState {
        }

        let up = step.prepare_updates(self, &handle.repo, &refs)?;
-
        self.update_all(up.tips.into_iter());
+
        self.update_all(up.tips);

        Ok(fetched)
    }
modified radicle-fetch/src/transport.rs
@@ -159,7 +159,7 @@ where
        {
            use gix_pack::index::File;

-
            let idx = File::at(&pack_path, gix_hash::Kind::Sha1).map_err(io_other)?;
+
            let idx = File::at(pack_path, gix_hash::Kind::Sha1).map_err(io_other)?;
            for oid in wants_haves.wants {
                if idx.lookup(oid::to_object_id(oid)).is_none() {
                    return Err(io::Error::new(
modified radicle-httpd/src/api/json.rs
@@ -137,7 +137,7 @@ pub(crate) fn patch(
                "description": rev.description(),
                "base": rev.base(),
                "oid": rev.head(),
-
                "refs": get_refs(repo, patch.author().id(), &rev.head()).unwrap_or(vec![]),
+
                "refs": get_refs(repo, patch.author().id(), &rev.head()).unwrap_or_default(),
                "discussions": rev.discussion().comments()
                  .map(|(id, comment)| Comment::new(id, comment,  aliases))
                  .collect::<Vec<_>>(),
modified radicle-httpd/src/api/v1/delegates.rs
@@ -40,19 +40,35 @@ async fn delegates_projects_handler(
        .inventory()?
        .into_iter()
        .filter_map(|id| {
-
            let Ok(repo) = storage.repository(id) else { return None };
-
            let Ok((_, head)) = repo.head() else { return None };
-
            let Ok(DocAt { doc, .. }) = repo.identity_doc() else { return None };
-
            let Ok(payload) = doc.project() else { return None };
+
            let Ok(repo) = storage.repository(id) else {
+
                return None;
+
            };
+
            let Ok((_, head)) = repo.head() else {
+
                return None;
+
            };
+
            let Ok(DocAt { doc, .. }) = repo.identity_doc() else {
+
                return None;
+
            };
+
            let Ok(payload) = doc.project() else {
+
                return None;
+
            };

            if !doc.delegates.iter().any(|d| *d == delegate) {
                return None;
            }

-
            let Ok(issues) = Issues::open(&repo) else { return None };
-
            let Ok(issues) = issues.counts() else { return None };
-
            let Ok(patches) = Patches::open(&repo) else { return None };
-
            let Ok(patches) = patches.counts() else { return None };
+
            let Ok(issues) = Issues::open(&repo) else {
+
                return None;
+
            };
+
            let Ok(issues) = issues.counts() else {
+
                return None;
+
            };
+
            let Ok(patches) = Patches::open(&repo) else {
+
                return None;
+
            };
+
            let Ok(patches) = patches.counts() else {
+
                return None;
+
            };

            let delegates = doc.delegates;
            let trackings = routing.count(&id).unwrap_or_default();
modified radicle-httpd/src/api/v1/projects.rs
@@ -87,15 +87,31 @@ async fn project_root_handler(
        .inventory()?
        .into_iter()
        .filter_map(|id| {
-
            let Ok(repo) = storage.repository(id) else { return None };
-
            let Ok((_, head)) = repo.head() else { return None };
-
            let Ok(DocAt { doc, .. }) = repo.identity_doc() else { return None };
-

-
            let Ok(payload) = doc.project() else { return None };
-
            let Ok(issues) = issue::Issues::open(&repo) else { return None };
-
            let Ok(issues) = issues.counts() else { return None };
-
            let Ok(patches) = patch::Patches::open(&repo) else { return None };
-
            let Ok(patches) = patches.counts() else { return None };
+
            let Ok(repo) = storage.repository(id) else {
+
                return None;
+
            };
+
            let Ok((_, head)) = repo.head() else {
+
                return None;
+
            };
+
            let Ok(DocAt { doc, .. }) = repo.identity_doc() else {
+
                return None;
+
            };
+

+
            let Ok(payload) = doc.project() else {
+
                return None;
+
            };
+
            let Ok(issues) = issue::Issues::open(&repo) else {
+
                return None;
+
            };
+
            let Ok(issues) = issues.counts() else {
+
                return None;
+
            };
+
            let Ok(patches) = patch::Patches::open(&repo) else {
+
                return None;
+
            };
+
            let Ok(patches) = patches.counts() else {
+
                return None;
+
            };
            let delegates = doc.delegates;
            let trackings = routing.count(&id).unwrap_or_default();

modified radicle-httpd/src/test.rs
@@ -95,7 +95,7 @@ pub fn contributor(dir: &Path) -> Context {
}

fn seed_with_signer<G: Signer>(dir: &Path, profile: radicle::Profile, signer: &G) -> Context {
-
    const DEFAULT_BRANCH: &'static str = "master";
+
    const DEFAULT_BRANCH: &str = "master";

    let tracking_db = dir.join("radicle").join("node").join("tracking.db");
    let routing_db = dir.join("radicle").join("node").join("routing.db");
modified radicle-node/src/runtime.rs
@@ -159,7 +159,7 @@ impl Runtime {
        log::info!(target: "node", "Default tracking policy set to '{}'", &policy);
        log::info!(target: "node", "Initializing service ({:?})..", network);

-
        let announcement = if let Some(ann) = fs::read(&node_dir.join(NODE_ANNOUNCEMENT_FILE))
+
        let announcement = if let Some(ann) = fs::read(node_dir.join(NODE_ANNOUNCEMENT_FILE))
            .ok()
            .and_then(|ann| NodeAnnouncement::decode(&mut ann.as_slice()).ok())
            .and_then(|ann| {
modified radicle-node/src/service.rs
@@ -1777,7 +1777,7 @@ where
                    .filter(|(nid, _)| !self.sessions.contains_key(nid))
                    .filter(|(nid, _)| nid != &self.node_id())
                    .fold(HashMap::new(), |mut acc, (nid, addr)| {
-
                        acc.entry(nid).or_insert_with(Vec::new).push(addr);
+
                        acc.entry(nid).or_default().push(addr);
                        acc
                    })
            }
modified radicle-node/src/service/message.rs
@@ -369,7 +369,7 @@ impl Announcement {
    #[cfg(not(debug_assertions))]
    pub const POW_PARAMS: (u8, u32, u32) = (15, 8, 1);
    /// Salt used for generating PoW.
-
    pub const POW_SALT: &[u8] = &[b'r', b'a', b'd'];
+
    pub const POW_SALT: &'static [u8] = &[b'r', b'a', b'd'];

    /// Verify this announcement's signature.
    pub fn verify(&self) -> bool {
modified radicle-node/src/wire/protocol.rs
@@ -393,7 +393,10 @@ where
            return;
        };

-
        let Peer::Connected { nid, link, streams, .. } = peer else {
+
        let Peer::Connected {
+
            nid, link, streams, ..
+
        } = peer
+
        else {
            log::warn!(target: "wire", "Peer {nid} is not connected; ignoring fetch result");
            return;
        };
@@ -834,15 +837,16 @@ where
                } => {
                    log::trace!(target: "wire", "Processing fetch for {rid} from {remote}..");

-
                    let Some((fd, Peer::Connected { link, streams,  .. })) =
-
                        self.peers.lookup_mut(&remote) else {
-
                            // Nb. It's possible that a peer is disconnected while an `Io::Fetch`
-
                            // is in the service's i/o buffer. Since the service may not purge the
-
                            // buffer on disconnect, we should just ignore i/o actions that don't
-
                            // have a connected peer.
-
                            log::error!(target: "wire", "Peer {remote} is not connected: dropping fetch");
-
                            continue;
-
                        };
+
                    let Some((fd, Peer::Connected { link, streams, .. })) =
+
                        self.peers.lookup_mut(&remote)
+
                    else {
+
                        // Nb. It's possible that a peer is disconnected while an `Io::Fetch`
+
                        // is in the service's i/o buffer. Since the service may not purge the
+
                        // buffer on disconnect, we should just ignore i/o actions that don't
+
                        // have a connected peer.
+
                        log::error!(target: "wire", "Peer {remote} is not connected: dropping fetch");
+
                        continue;
+
                    };
                    let (stream, channels) = streams.open();

                    log::debug!(target: "wire", "Opened new stream with id {stream} for {rid} and remote {remote}");
modified radicle-term/src/editor.rs
@@ -63,12 +63,10 @@ impl Editor {
        }

        let Some(cmd) = self::default_editor() else {
-
            return Err(
-
                io::Error::new(
-
                    io::ErrorKind::NotFound,
-
                    "editor not configured: the `EDITOR` environment variable is not set"
-
                )
-
            );
+
            return Err(io::Error::new(
+
                io::ErrorKind::NotFound,
+
                "editor not configured: the `EDITOR` environment variable is not set",
+
            ));
        };

        // We duplicate the stderr file descriptor to pass it to the child process, otherwise, if
modified radicle-term/src/io.rs
@@ -1,4 +1,5 @@
use std::ffi::OsStr;
+
use std::fmt::Write;
use std::{env, fmt, io, process};

use inquire::ui::{ErrorMessageRenderConfig, StyleSheet, Styled};
@@ -127,9 +128,10 @@ pub fn print(msg: impl fmt::Display) {
}

pub fn prefixed(prefix: &str, text: &str) -> String {
-
    text.split('\n')
-
        .map(|line| format!("{prefix}{line}\n"))
-
        .collect()
+
    text.split('\n').fold(String::new(), |mut s, line| {
+
        writeln!(&mut s, "{prefix}{line}").ok();
+
        s
+
    })
}

pub fn help(name: &str, version: &str, description: &str, usage: &str) {
modified radicle/src/cob/identity.rs
@@ -293,10 +293,17 @@ impl store::Cob for Identity {

    fn from_root<R: ReadRepository>(op: Op, repo: &R) -> Result<Self, Self::Error> {
        let mut actions = op.actions.into_iter();
-
        let Some(
-
            Action::Revision { title, description, blob, signature, parent }
-
        ) = actions.next() else {
-
            return Err(ApplyError::Init("the first action must be of type `revision`"));
+
        let Some(Action::Revision {
+
            title,
+
            description,
+
            blob,
+
            signature,
+
            parent,
+
        }) = actions.next()
+
        else {
+
            return Err(ApplyError::Init(
+
                "the first action must be of type `revision`",
+
            ));
        };
        if parent.is_some() {
            return Err(ApplyError::Init(
modified radicle/src/cob/issue.rs
@@ -131,7 +131,12 @@ impl store::Cob for Issue {
    fn from_root<R: ReadRepository>(op: Op, repo: &R) -> Result<Self, Self::Error> {
        let doc = op.identity_doc(repo)?.ok_or(Error::MissingIdentity)?;
        let mut actions = op.actions.into_iter();
-
        let Some(Action::Comment { body, reply_to: None, embeds }) = actions.next() else {
+
        let Some(Action::Comment {
+
            body,
+
            reply_to: None,
+
            embeds,
+
        }) = actions.next()
+
        else {
            return Err(Error::Init("the first action must be of type `comment`"));
        };
        let comment = Comment::new(op.author, body, None, None, embeds, op.timestamp);
modified radicle/src/cob/op.rs
@@ -46,7 +46,7 @@ pub struct Op<A> {

impl<A: Eq> PartialOrd for Op<A> {
    fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
-
        self.id.partial_cmp(&other.id)
+
        Some(self.cmp(other))
    }
}

modified radicle/src/cob/patch.rs
@@ -1073,7 +1073,13 @@ impl store::Cob for Patch {
    fn from_root<R: ReadRepository>(op: Op, repo: &R) -> Result<Self, Self::Error> {
        let doc = op.identity_doc(repo)?.ok_or(Error::MissingIdentity)?;
        let mut actions = op.actions.into_iter();
-
        let Some(Action::Revision { description, base, oid, resolves }) = actions.next() else {
+
        let Some(Action::Revision {
+
            description,
+
            base,
+
            oid,
+
            resolves,
+
        }) = actions.next()
+
        else {
            return Err(Error::Init("the first action must be of type `revision`"));
        };
        let Some(Action::Edit { title, target }) = actions.next() else {
modified radicle/src/cob/thread.rs
@@ -383,7 +383,11 @@ impl cob::store::Cob for Thread {
        let timestamp = op.timestamp;
        let identity = op.identity.ok_or(Error::MissingIdentity)?;
        let mut actions = op.actions.into_iter();
-
        let Some(Action::Comment { body, reply_to: None }) = actions.next() else {
+
        let Some(Action::Comment {
+
            body,
+
            reply_to: None,
+
        }) = actions.next()
+
        else {
            return Err(Error::Init("missing initial comment"));
        };

modified radicle/src/node/address/store.rs
@@ -46,8 +46,8 @@ impl From<sql::Connection> for Book {
}

impl Book {
-
    const SCHEMA: &str = include_str!("schema.sql");
-
    const PRAGMA: &str = "PRAGMA foreign_keys = ON";
+
    const SCHEMA: &'static str = include_str!("schema.sql");
+
    const PRAGMA: &'static str = "PRAGMA foreign_keys = ON";

    /// Open an address book at the given path. Creates a new address book if it
    /// doesn't exist.
modified radicle/src/node/routing.rs
@@ -50,7 +50,7 @@ impl fmt::Debug for Table {
}

impl Table {
-
    const SCHEMA: &str = include_str!("routing/schema.sql");
+
    const SCHEMA: &'static str = include_str!("routing/schema.sql");

    /// Open a routing file store at the given path. Creates a new empty store
    /// if an existing store isn't found.
modified radicle/src/node/tracking/store.rs
@@ -49,7 +49,7 @@ impl<T> fmt::Debug for Config<T> {
}

impl Config<Read> {
-
    const SCHEMA: &str = include_str!("schema.sql");
+
    const SCHEMA: &'static str = include_str!("schema.sql");

    /// Same as [`Self::open`], but in read-only mode. This is useful to have multiple
    /// open databases, as no locking is required.
@@ -81,7 +81,7 @@ impl Config<Read> {
}

impl Config<Write> {
-
    const SCHEMA: &str = include_str!("schema.sql");
+
    const SCHEMA: &'static str = include_str!("schema.sql");

    /// Open a policy store at the given path. Creates a new store if it
    /// doesn't exist.
modified radicle/src/storage.rs
@@ -116,7 +116,7 @@ impl Error {
    pub fn is_not_found(&self) -> bool {
        match self {
            Self::Io(e) if e.kind() == io::ErrorKind::NotFound => true,
-
            Self::Git(e) if git::is_not_found_err(e) => true,
+
            Self::Git(e) if git::ext::is_not_found_err(e) => true,
            Self::Doc(e) if e.is_not_found() => true,
            _ => false,
        }
modified radicle/src/storage/git.rs
@@ -23,7 +23,9 @@ use crate::storage::{
    WriteRepository, WriteStorage,
};

-
pub use crate::git::*;
+
pub use crate::git::{
+
    ext, raw, refname, refspec, Oid, PatternStr, Qualified, RefError, RefString, UserInfo,
+
};
pub use crate::storage::Error;

use super::{RemoteId, RemoteRepository, ValidateRepository};
@@ -605,8 +607,8 @@ impl ReadRepository for Repository {

    fn references_glob(
        &self,
-
        pattern: &self::PatternStr,
-
    ) -> Result<Vec<(Qualified, Oid)>, self::ext::Error> {
+
        pattern: &PatternStr,
+
    ) -> Result<Vec<(Qualified, Oid)>, git::ext::Error> {
        let mut refs = Vec::new();

        for r in self.backend.references_glob(pattern)? {
@@ -715,11 +717,11 @@ impl ReadRepository for Repository {
        Err(DocError::Missing.into())
    }

-
    fn merge_base(&self, left: &Oid, right: &Oid) -> Result<Oid, ext::Error> {
+
    fn merge_base(&self, left: &Oid, right: &Oid) -> Result<Oid, git::ext::Error> {
        self.backend
            .merge_base(**left, **right)
            .map(Oid::from)
-
            .map_err(ext::Error::from)
+
            .map_err(git::ext::Error::from)
    }
}

@@ -941,7 +943,7 @@ mod tests {
        let m1 = fixtures::commit("M1", &[*c2, *b2], &repo);
        let m2 = fixtures::commit("M2", &[*a1, *b2], &repo);
        let mut rng = fastrand::Rng::new();
-
        let choices = vec![*c0, *c1, *c2, *b2, *a1, *a2, *d1, *m1, *m2];
+
        let choices = [*c0, *c1, *c2, *b2, *a1, *a2, *d1, *m1, *m2];

        for _ in 0..100 {
            let count = rng.usize(1..=choices.len());
modified radicle/src/storage/git/transport/local/url.rs
@@ -45,7 +45,7 @@ pub struct Url {

impl Url {
    /// URL scheme.
-
    pub const SCHEME: &str = "rad";
+
    pub const SCHEME: &'static str = "rad";

    /// Return this URL with the given namespace added.
    pub fn with_namespace(mut self, namespace: Namespace) -> Self {
modified radicle/src/storage/git/transport/remote/url.rs
@@ -47,7 +47,7 @@ pub struct Url {

impl Url {
    /// URL scheme.
-
    pub const SCHEME: &str = "heartwood";
+
    pub const SCHEME: &'static str = "heartwood";
}

impl fmt::Display for Url {
modified radicle/src/test/storage.rs
@@ -40,10 +40,7 @@ impl MockStorage {

    /// Add a remote `node` with `signed_refs` for the repo `rid`.
    pub fn insert_remote(&mut self, rid: Id, node: NodeId, refs: refs::SignedRefsAt) {
-
        self.remotes
-
            .entry(rid)
-
            .or_insert(HashMap::new())
-
            .insert(node, refs);
+
        self.remotes.entry(rid).or_default().insert(node, refs);
    }
}

modified rust-toolchain
@@ -1 +1 @@
-
1.71
+
1.74