Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cob: Change history type to a string
Alexis Sellier committed 3 years ago
commit 5a47023ac085c0e66599cdc005eb74dd19116623
parent 0dc34dc15d596f2118b4eaa63949e8f41fc5c0a2
11 files changed +54 -59
modified radicle-cob/src/backend/git/change.rs
@@ -13,7 +13,7 @@ use crate::{
    change::{self, store, Change},
    history::entry,
    signatures::{Signature, Signatures},
-
    trailers, HistoryType,
+
    trailers,
};

const MANIFEST_BLOB_NAME: &str = "manifest";
@@ -154,7 +154,7 @@ impl change::Storage for git2::Repository {

        let tree = self.find_tree(commit.tree())?;
        let manifest = load_manifest(self, &tree)?;
-
        let contents = load_contents(self, &tree, &manifest)?;
+
        let contents = load_contents(self, &tree)?;

        Ok(Change {
            id,
@@ -210,20 +210,15 @@ fn load_manifest(
fn load_contents(
    repo: &git2::Repository,
    tree: &git2::Tree,
-
    manifest: &store::Manifest,
) -> Result<entry::Contents, error::Load> {
-
    Ok(match manifest.history_type {
-
        HistoryType::Radicle | HistoryType::Automerge => {
-
            let contents_tree_entry = tree
-
                .get_name(CHANGE_BLOB_NAME)
-
                .ok_or_else(|| error::Load::NoChange(tree.id().into()))?;
-
            let contents_object = contents_tree_entry.to_object(repo)?;
-
            let contents_blob = contents_object
-
                .as_blob()
-
                .ok_or_else(|| error::Load::ChangeNotBlob(tree.id().into()))?;
-
            contents_blob.content().to_owned()
-
        }
-
    })
+
    let contents_tree_entry = tree
+
        .get_name(CHANGE_BLOB_NAME)
+
        .ok_or_else(|| error::Load::NoChange(tree.id().into()))?;
+
    let contents_object = contents_tree_entry.to_object(repo)?;
+
    let contents_blob = contents_object
+
        .as_blob()
+
        .ok_or_else(|| error::Load::ChangeNotBlob(tree.id().into()))?;
+
    Ok(contents_blob.content().to_owned())
}

fn write_commit<O>(
modified radicle-cob/src/change/store.rs
@@ -7,10 +7,7 @@ use std::{error::Error, fmt};

use serde::{Deserialize, Serialize};

-
use crate::{
-
    history::{Contents, HistoryType},
-
    signatures, TypeName,
-
};
+
use crate::{history::Contents, signatures, TypeName};

pub trait Storage {
    type CreateError: Error + Send + Sync + 'static;
@@ -47,7 +44,7 @@ pub trait Storage {

pub struct Create<Id> {
    pub typename: TypeName,
-
    pub history_type: HistoryType,
+
    pub history_type: String,
    pub tips: Vec<Id>,
    pub message: String,
    pub contents: Contents,
@@ -126,10 +123,10 @@ where
    }
}

-
#[derive(Clone, Debug, Serialize, Deserialize)]
+
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct Manifest {
    /// The name given to the type of collaborative object.
    pub typename: TypeName,
    /// The type of history for the collaborative oject.
-
    pub history_type: HistoryType,
+
    pub history_type: String,
}
modified radicle-cob/src/change_graph.rs
@@ -102,9 +102,9 @@ impl ChangeGraph {
        // This is okay because we check that the graph has a root node in
        // GraphBuilder::build
        let root = roots.first().unwrap();
-
        let typename = {
+
        let manifest = {
            let first_node = &self.graph[*root];
-
            first_node.typename().clone()
+
            first_node.manifest.clone()
        };
        let topo = Topo::new(&self.graph);
        let items = topo.iter(&self.graph).map(|idx| {
@@ -121,7 +121,7 @@ impl ChangeGraph {
            evaluate(*root_change.id(), &self.graph, items)
        };
        CollaborativeObject {
-
            typename,
+
            manifest,
            history,
            id: self.object_id,
        }
modified radicle-cob/src/history.rs
@@ -17,16 +17,6 @@ use crate::pruning_fold;
pub mod entry;
pub use entry::{Clock, Contents, Entry, EntryId, EntryWithClock};

-
#[derive(
-
    Clone, Copy, Debug, Default, PartialEq, Eq, Hash, serde::Serialize, serde::Deserialize,
-
)]
-
#[serde(rename_all = "lowercase")]
-
pub enum HistoryType {
-
    #[default]
-
    Radicle,
-
    Automerge,
-
}
-

/// The DAG of changes making up the history of a collaborative object.
#[derive(Clone, Debug)]
pub struct History {
modified radicle-cob/src/lib.rs
@@ -92,7 +92,7 @@ pub use change::Change;
pub mod identity;

pub mod history;
-
pub use history::{Contents, Entry, History, HistoryType};
+
pub use history::{Contents, Entry, History};

mod pruning_fold;

modified radicle-cob/src/object/collaboration.rs
@@ -7,6 +7,7 @@ use std::collections::BTreeSet;

use git_ext::Oid;

+
use crate::change::store::Manifest;
use crate::{change, identity::Identity, Contents, History, ObjectId, TypeName};

pub mod error;
@@ -28,8 +29,8 @@ pub use update::{update, Update};
/// A collaborative object
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct CollaborativeObject {
-
    /// The typename of this object
-
    pub(crate) typename: TypeName,
+
    /// The manifest of this object
+
    pub(crate) manifest: Manifest,
    /// The CRDT history we know about for this object
    pub(crate) history: History,
    /// The id of the object
@@ -46,7 +47,11 @@ impl CollaborativeObject {
    }

    pub fn typename(&self) -> &TypeName {
-
        &self.typename
+
        &self.manifest.typename
+
    }
+

+
    pub fn manifest(&self) -> &Manifest {
+
        &self.manifest
    }

    fn tips(&self) -> BTreeSet<Oid> {
modified radicle-cob/src/object/collaboration/create.rs
@@ -3,7 +3,7 @@
// This file is part of radicle-link, distributed under the GPLv3 with Radicle
// Linking Exception. For full terms see the included LICENSE file.

-
use crate::{HistoryType, Store};
+
use crate::Store;

use super::*;

@@ -12,7 +12,7 @@ pub struct Create<Author> {
    /// The identity of the author for this object's first change.
    pub author: Option<Author>,
    /// The type of history that will be used for this object.
-
    pub history_type: HistoryType,
+
    pub history_type: String,
    /// The CRDT history to initialize this object with.
    pub contents: Contents,
    /// The typename for this object.
@@ -25,7 +25,7 @@ impl<Author> Create<Author> {
    fn create_spec(&self) -> change::Create<git_ext::Oid> {
        change::Create {
            typename: self.typename.clone(),
-
            history_type: self.history_type,
+
            history_type: self.history_type.clone(),
            tips: Vec::new(),
            message: self.message.clone(),
            contents: self.contents.clone(),
@@ -101,7 +101,10 @@ where
        .map_err(|err| error::Create::Refs { err: Box::new(err) })?;

    Ok(CollaborativeObject {
-
        typename: args.typename,
+
        manifest: Manifest {
+
            typename: args.typename,
+
            history_type: args.history_type,
+
        },
        history,
        id: init_change.id().into(),
    })
modified radicle-cob/src/object/collaboration/update.rs
@@ -4,8 +4,8 @@
// Linking Exception. For full terms see the included LICENSE file.

use crate::{
-
    change, change_graph::ChangeGraph, identity::Identity, CollaborativeObject, Contents,
-
    HistoryType, ObjectId, Store, TypeName,
+
    change, change_graph::ChangeGraph, identity::Identity, CollaborativeObject, Contents, ObjectId,
+
    Store, TypeName,
};

use super::error;
@@ -15,7 +15,7 @@ pub struct Update<Author> {
    /// The identity of the author for the update of this object.
    pub author: Option<Author>,
    /// The type of history that will be used for this object.
-
    pub history_type: HistoryType,
+
    pub history_type: String,
    /// The CRDT changes to add to the object.
    pub changes: Contents,
    /// The object ID of the object to be updated.
modified radicle-cob/src/tests.rs
@@ -6,8 +6,7 @@ use quickcheck::Arbitrary;
use radicle_crypto::Signer;

use crate::{
-
    create, get, list, object, test::arbitrary::Invalid, update, Create, HistoryType, ObjectId,
-
    TypeName, Update,
+
    create, get, list, object, test::arbitrary::Invalid, update, Create, ObjectId, TypeName, Update,
};

use super::test;
@@ -30,7 +29,7 @@ fn roundtrip() {
        &proj.identifier(),
        Create {
            author: Some(terry),
-
            history_type: HistoryType::Automerge,
+
            history_type: "test".to_string(),
            contents: Vec::new(),
            typename: typename.clone(),
            message: "creating xyz.rad.issue".to_string(),
@@ -63,7 +62,7 @@ fn list_cobs() {
        &proj.identifier(),
        Create {
            author: Some(terry.clone()),
-
            history_type: HistoryType::Automerge,
+
            history_type: "test".to_string(),
            contents: b"issue 1".to_vec(),
            typename: typename.clone(),
            message: "creating xyz.rad.issue".to_string(),
@@ -78,7 +77,7 @@ fn list_cobs() {
        &proj.identifier(),
        Create {
            author: Some(terry),
-
            history_type: HistoryType::Automerge,
+
            history_type: "test".to_string(),
            contents: b"issue 2".to_vec(),
            typename: typename.clone(),
            message: "commenting xyz.rad.issue".to_string(),
@@ -113,7 +112,7 @@ fn update_cob() {
        &proj.identifier(),
        Create {
            author: Some(terry.clone()),
-
            history_type: HistoryType::Automerge,
+
            history_type: "test".to_string(),
            contents: Vec::new(),
            typename: typename.clone(),
            message: "creating xyz.rad.issue".to_string(),
@@ -133,7 +132,7 @@ fn update_cob() {
        Update {
            author: Some(terry),
            changes: b"issue 1".to_vec(),
-
            history_type: HistoryType::Automerge,
+
            history_type: "test".to_string(),
            object_id: *cob.id(),
            typename: typename.clone(),
            message: "commenting xyz.rad.issue".to_string(),
@@ -174,7 +173,7 @@ fn traverse_cobs() {
        Create {
            author: Some(terry),
            contents: b"issue 1".to_vec(),
-
            history_type: HistoryType::Automerge,
+
            history_type: "test".to_string(),
            typename: typename.clone(),
            message: "creating xyz.rad.issue".to_string(),
        },
@@ -197,7 +196,7 @@ fn traverse_cobs() {
        Update {
            author: Some(neil),
            changes: b"issue 2".to_vec(),
-
            history_type: HistoryType::Automerge,
+
            history_type: "test".to_string(),
            object_id: *cob.id(),
            typename,
            message: "commenting on xyz.rad.issue".to_string(),
modified radicle/src/cob.rs
@@ -6,7 +6,7 @@ pub mod thread;

pub use cob::{
    identity, object::collaboration::error, CollaborativeObject, Contents, Create, Entry, History,
-
    HistoryType, ObjectId, TypeName, Update,
+
    ObjectId, TypeName, Update,
};
pub use common::*;

modified radicle/src/cob/store.rs
@@ -8,13 +8,16 @@ use serde::Serialize;
use crate::cob;
use crate::cob::common::Author;
use crate::cob::CollaborativeObject;
-
use crate::cob::{Create, History, HistoryType, ObjectId, TypeName, Update};
+
use crate::cob::{Create, History, ObjectId, TypeName, Update};
use crate::crypto::PublicKey;
use crate::git;
use crate::identity::project;
use crate::prelude::*;
use crate::storage::git as storage;

+
/// History type for standard radicle COBs.
+
pub const HISTORY_TYPE: &str = "radicle";
+

/// A type that can be materialized from an event history.
/// All collaborative objects implement this trait.
pub trait FromHistory: Sized {
@@ -102,7 +105,7 @@ where
            Update {
                author: Some(cob::Author::from(*signer.public_key())),
                object_id,
-
                history_type: HistoryType::default(),
+
                history_type: HISTORY_TYPE.to_owned(),
                typename: T::type_name().clone(),
                message: message.to_owned(),
                changes,
@@ -125,7 +128,7 @@ where
            &self.project,
            Create {
                author: Some(cob::Author::from(*signer.public_key())),
-
                history_type: HistoryType::default(),
+
                history_type: HISTORY_TYPE.to_owned(),
                typename: T::type_name().clone(),
                message: message.to_owned(),
                contents,
@@ -141,6 +144,9 @@ where
        let cob = cob::get(self.raw, T::type_name(), id)?;

        if let Some(cob) = cob {
+
            if cob.manifest().history_type != HISTORY_TYPE {
+
                panic!();
+
            }
            let (obj, clock) = T::from_history(cob.history())?;
            Ok(Some((obj, clock)))
        } else {