From d309f593b1ac8640e05c8c122f51d832ed259d61 Mon Sep 17 00:00:00 2001 From: Alexis Sellier Date: Thu, 8 Dec 2022 21:49:55 +0100 Subject: [PATCH] Move doc initialization to storage Signed-off-by: Alexis Sellier --- radicle-cli/src/commands/edit.rs | 4 ++-- radicle/src/identity.rs | 10 ++++----- radicle/src/identity/doc.rs | 37 ++++++++++++-------------------- radicle/src/rad.rs | 9 ++++---- radicle/src/storage.rs | 3 +++ radicle/src/storage/git.rs | 14 ++++++++++++ 6 files changed, 42 insertions(+), 35 deletions(-) diff --git a/radicle-cli/src/commands/edit.rs b/radicle-cli/src/commands/edit.rs index 73b4e869..00059c24 100644 --- a/radicle-cli/src/commands/edit.rs +++ b/radicle-cli/src/commands/edit.rs @@ -4,7 +4,7 @@ use std::str::FromStr; use anyhow::{anyhow, Context as _}; use radicle::identity::Id; -use radicle::storage::{ReadStorage, WriteStorage}; +use radicle::storage::{ReadStorage, WriteRepository, WriteStorage}; use crate::terminal as term; use crate::terminal::args::{Args, Error, Help}; @@ -86,7 +86,7 @@ pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> { signer.public_key(), "Updated payload", &[(signer.public_key(), sig)], - &repo, + repo.raw(), ) })?; } diff --git a/radicle/src/identity.rs b/radicle/src/identity.rs index a8b998b9..9766323e 100644 --- a/radicle/src/identity.rs +++ b/radicle/src/identity.rs @@ -162,7 +162,7 @@ mod test { use crate::crypto::PublicKey; use crate::rad; use crate::storage::git::Storage; - use crate::storage::{ReadStorage, WriteStorage}; + use crate::storage::{ReadStorage, WriteRepository, WriteStorage}; use crate::test::fixtures; use super::did::Did; @@ -214,7 +214,7 @@ mod test { alice.public_key(), "Update description", &[(alice.public_key(), sig)], - &repo, + repo.raw(), ) }) .unwrap(); @@ -228,7 +228,7 @@ mod test { alice.public_key(), "Add bob", &[(alice.public_key(), sig)], - &repo, + repo.raw(), ) }) .unwrap(); @@ -242,7 +242,7 @@ mod test { alice.public_key(), "Add eve", &[(alice.public_key(), alice_sig), (bob.public_key(), bob_sig)], - &repo, + repo.raw(), ) }) }) @@ -259,7 +259,7 @@ mod test { alice.public_key(), "Update description", &[(bob.public_key(), bob_sig), (eve.public_key(), eve_sig)], - &repo, + repo.raw(), ) .map(|head| (blob_id, head)) }) diff --git a/radicle/src/identity/doc.rs b/radicle/src/identity/doc.rs index f1cf3d0d..dac303d9 100644 --- a/radicle/src/identity/doc.rs +++ b/radicle/src/identity/doc.rs @@ -17,9 +17,8 @@ use crate::crypto; use crate::crypto::{Signature, Unverified, Verified}; use crate::git; use crate::identity::{project::Project, Did}; -use crate::storage; use crate::storage::git::trailers; -use crate::storage::{ReadRepository, RemoteId, WriteRepository, WriteStorage}; +use crate::storage::{ReadRepository, RemoteId}; pub use crypto::PublicKey; pub use id::*; @@ -45,8 +44,6 @@ pub enum DocError { Git(#[from] git::Error), #[error("git: {0}")] RawGit(#[from] git2::Error), - #[error("storage: {0}")] - Storage(#[from] storage::Error), } impl DocError { @@ -166,41 +163,35 @@ impl Doc { Ok((oid, sig)) } - pub fn create( - &self, + pub fn init( + doc: &[u8], remote: &RemoteId, - msg: &str, - storage: &S, - ) -> Result<(Id, git::Oid, S::Repository), DocError> { - let (doc_oid, doc) = self.encode()?; - let id = Id::from(doc_oid); - let repo = storage.repository(id)?; - let tree = git::write_tree(*PATH, doc.as_slice(), repo.raw())?; - let oid = Doc::commit(remote, &tree, msg, &[], repo.raw())?; + repo: &git2::Repository, + ) -> Result { + let tree = git::write_tree(*PATH, doc, repo)?; + let oid = Doc::commit(remote, &tree, "Initialize Radicle\n", &[], repo)?; - drop(tree); - - Ok((id, oid, repo)) + Ok(oid) } - pub fn update( + pub fn update( &self, remote: &RemoteId, msg: &str, signatures: &[(&PublicKey, Signature)], - repo: &R, + repo: &git2::Repository, ) -> Result { - let mut msg = format!("{msg}\n\n"); + let mut msg = format!("{}\n\n", msg.trim()); for (key, sig) in signatures { writeln!(&mut msg, "{}: {key} {sig}", trailers::SIGNATURE_TRAILER) .expect("in-memory writes don't fail"); } let (_, doc) = self.encode()?; - let tree = git::write_tree(*PATH, doc.as_slice(), repo.raw())?; + let tree = git::write_tree(*PATH, doc.as_slice(), repo)?; let id_ref = git::refs::storage::id(remote); - let head = repo.raw().find_reference(&id_ref)?.peel_to_commit()?; - let oid = Doc::commit(remote, &tree, &msg, &[&head], repo.raw())?; + let head = repo.find_reference(&id_ref)?.peel_to_commit()?; + let oid = Doc::commit(remote, &tree, &msg, &[&head], repo)?; Ok(oid) } diff --git a/radicle/src/rad.rs b/radicle/src/rad.rs index 0e18b271..cd45303c 100644 --- a/radicle/src/rad.rs +++ b/radicle/src/rad.rs @@ -14,7 +14,7 @@ use crate::identity::project::Project; use crate::node; use crate::node::NodeId; use crate::storage::git::transport::{self, remote}; -use crate::storage::git::{ProjectError, Storage}; +use crate::storage::git::{ProjectError, Repository, Storage}; use crate::storage::refs::SignedRefs; use crate::storage::{BranchName, ReadRepository as _, RemoteId, WriteRepository as _}; use crate::{identity, storage}; @@ -65,9 +65,8 @@ pub fn init( default_branch: default_branch.clone(), }; let doc = identity::Doc::initial(proj, delegate).verified()?; - - let (id, _, project) = doc.create(pk, "Initialize Radicle\n", storage)?; - let url = git::Url::from(id).with_namespace(*pk); + let (project, _) = Repository::init(&doc, pk, storage)?; + let url = git::Url::from(project.id).with_namespace(*pk); git::configure_remote(repo, &REMOTE_NAME, &url)?; git::push( @@ -81,7 +80,7 @@ pub fn init( let signed = project.sign_refs(signer)?; let _head = project.set_head()?; - Ok((id, doc, signed)) + Ok((project.id, doc, signed)) } #[derive(Error, Debug)] diff --git a/radicle/src/storage.rs b/radicle/src/storage.rs index a8bd6a75..629c30da 100644 --- a/radicle/src/storage.rs +++ b/radicle/src/storage.rs @@ -17,6 +17,7 @@ use crate::collections::HashMap; use crate::git::ext as git_ext; use crate::git::{Qualified, RefError, RefString}; use crate::identity; +use crate::identity::doc::DocError; use crate::identity::{Id, IdError}; use crate::storage::refs::Refs; @@ -46,6 +47,8 @@ impl From for Namespaces { pub enum Error { #[error("invalid git reference")] InvalidRef, + #[error("identity doc: {0}")] + Doc(#[from] DocError), #[error("git reference error: {0}")] Ref(#[from] RefError), #[error(transparent)] diff --git a/radicle/src/storage/git.rs b/radicle/src/storage/git.rs index 61350552..1988f124 100644 --- a/radicle/src/storage/git.rs +++ b/radicle/src/storage/git.rs @@ -212,6 +212,20 @@ impl Repository { Ok(Self { id, backend }) } + /// Create the repository's identity branch. + pub fn init( + doc: &Doc, + remote: &RemoteId, + storage: &Storage, + ) -> Result<(Self, git::Oid), Error> { + let (doc_oid, doc) = doc.encode()?; + let id = Id::from(doc_oid); + let repo = Self::open(paths::repository(storage, &id), id)?; + let oid = Doc::init(doc.as_slice(), remote, repo.raw())?; + + Ok((repo, oid)) + } + /// Verify all references in the repository, checking that they are signed /// as part of 'sigrefs'. Also verify that no signed reference is missing /// from the repository.