Move doc initialization to storage

Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
This commit is contained in:
Alexis Sellier 2022-12-08 21:49:55 +01:00
parent b37fef9f22
commit d309f593b1
No known key found for this signature in database
6 changed files with 42 additions and 35 deletions

View File

@ -4,7 +4,7 @@ use std::str::FromStr;
use anyhow::{anyhow, Context as _}; use anyhow::{anyhow, Context as _};
use radicle::identity::Id; use radicle::identity::Id;
use radicle::storage::{ReadStorage, WriteStorage}; use radicle::storage::{ReadStorage, WriteRepository, WriteStorage};
use crate::terminal as term; use crate::terminal as term;
use crate::terminal::args::{Args, Error, Help}; 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(), signer.public_key(),
"Updated payload", "Updated payload",
&[(signer.public_key(), sig)], &[(signer.public_key(), sig)],
&repo, repo.raw(),
) )
})?; })?;
} }

View File

@ -162,7 +162,7 @@ mod test {
use crate::crypto::PublicKey; use crate::crypto::PublicKey;
use crate::rad; use crate::rad;
use crate::storage::git::Storage; use crate::storage::git::Storage;
use crate::storage::{ReadStorage, WriteStorage}; use crate::storage::{ReadStorage, WriteRepository, WriteStorage};
use crate::test::fixtures; use crate::test::fixtures;
use super::did::Did; use super::did::Did;
@ -214,7 +214,7 @@ mod test {
alice.public_key(), alice.public_key(),
"Update description", "Update description",
&[(alice.public_key(), sig)], &[(alice.public_key(), sig)],
&repo, repo.raw(),
) )
}) })
.unwrap(); .unwrap();
@ -228,7 +228,7 @@ mod test {
alice.public_key(), alice.public_key(),
"Add bob", "Add bob",
&[(alice.public_key(), sig)], &[(alice.public_key(), sig)],
&repo, repo.raw(),
) )
}) })
.unwrap(); .unwrap();
@ -242,7 +242,7 @@ mod test {
alice.public_key(), alice.public_key(),
"Add eve", "Add eve",
&[(alice.public_key(), alice_sig), (bob.public_key(), bob_sig)], &[(alice.public_key(), alice_sig), (bob.public_key(), bob_sig)],
&repo, repo.raw(),
) )
}) })
}) })
@ -259,7 +259,7 @@ mod test {
alice.public_key(), alice.public_key(),
"Update description", "Update description",
&[(bob.public_key(), bob_sig), (eve.public_key(), eve_sig)], &[(bob.public_key(), bob_sig), (eve.public_key(), eve_sig)],
&repo, repo.raw(),
) )
.map(|head| (blob_id, head)) .map(|head| (blob_id, head))
}) })

View File

@ -17,9 +17,8 @@ use crate::crypto;
use crate::crypto::{Signature, Unverified, Verified}; use crate::crypto::{Signature, Unverified, Verified};
use crate::git; use crate::git;
use crate::identity::{project::Project, Did}; use crate::identity::{project::Project, Did};
use crate::storage;
use crate::storage::git::trailers; use crate::storage::git::trailers;
use crate::storage::{ReadRepository, RemoteId, WriteRepository, WriteStorage}; use crate::storage::{ReadRepository, RemoteId};
pub use crypto::PublicKey; pub use crypto::PublicKey;
pub use id::*; pub use id::*;
@ -45,8 +44,6 @@ pub enum DocError {
Git(#[from] git::Error), Git(#[from] git::Error),
#[error("git: {0}")] #[error("git: {0}")]
RawGit(#[from] git2::Error), RawGit(#[from] git2::Error),
#[error("storage: {0}")]
Storage(#[from] storage::Error),
} }
impl DocError { impl DocError {
@ -166,41 +163,35 @@ impl Doc<Verified> {
Ok((oid, sig)) Ok((oid, sig))
} }
pub fn create<S: WriteStorage>( pub fn init(
&self, doc: &[u8],
remote: &RemoteId, remote: &RemoteId,
msg: &str, repo: &git2::Repository,
storage: &S, ) -> Result<git::Oid, DocError> {
) -> Result<(Id, git::Oid, S::Repository), DocError> { let tree = git::write_tree(*PATH, doc, repo)?;
let (doc_oid, doc) = self.encode()?; let oid = Doc::commit(remote, &tree, "Initialize Radicle\n", &[], repo)?;
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())?;
drop(tree); Ok(oid)
Ok((id, oid, repo))
} }
pub fn update<R: WriteRepository>( pub fn update(
&self, &self,
remote: &RemoteId, remote: &RemoteId,
msg: &str, msg: &str,
signatures: &[(&PublicKey, Signature)], signatures: &[(&PublicKey, Signature)],
repo: &R, repo: &git2::Repository,
) -> Result<git::Oid, DocError> { ) -> Result<git::Oid, DocError> {
let mut msg = format!("{msg}\n\n"); let mut msg = format!("{}\n\n", msg.trim());
for (key, sig) in signatures { for (key, sig) in signatures {
writeln!(&mut msg, "{}: {key} {sig}", trailers::SIGNATURE_TRAILER) writeln!(&mut msg, "{}: {key} {sig}", trailers::SIGNATURE_TRAILER)
.expect("in-memory writes don't fail"); .expect("in-memory writes don't fail");
} }
let (_, doc) = self.encode()?; 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 id_ref = git::refs::storage::id(remote);
let head = repo.raw().find_reference(&id_ref)?.peel_to_commit()?; let head = repo.find_reference(&id_ref)?.peel_to_commit()?;
let oid = Doc::commit(remote, &tree, &msg, &[&head], repo.raw())?; let oid = Doc::commit(remote, &tree, &msg, &[&head], repo)?;
Ok(oid) Ok(oid)
} }

View File

@ -14,7 +14,7 @@ use crate::identity::project::Project;
use crate::node; use crate::node;
use crate::node::NodeId; use crate::node::NodeId;
use crate::storage::git::transport::{self, remote}; 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::refs::SignedRefs;
use crate::storage::{BranchName, ReadRepository as _, RemoteId, WriteRepository as _}; use crate::storage::{BranchName, ReadRepository as _, RemoteId, WriteRepository as _};
use crate::{identity, storage}; use crate::{identity, storage};
@ -65,9 +65,8 @@ pub fn init<G: Signer>(
default_branch: default_branch.clone(), default_branch: default_branch.clone(),
}; };
let doc = identity::Doc::initial(proj, delegate).verified()?; let doc = identity::Doc::initial(proj, delegate).verified()?;
let (project, _) = Repository::init(&doc, pk, storage)?;
let (id, _, project) = doc.create(pk, "Initialize Radicle\n", storage)?; let url = git::Url::from(project.id).with_namespace(*pk);
let url = git::Url::from(id).with_namespace(*pk);
git::configure_remote(repo, &REMOTE_NAME, &url)?; git::configure_remote(repo, &REMOTE_NAME, &url)?;
git::push( git::push(
@ -81,7 +80,7 @@ pub fn init<G: Signer>(
let signed = project.sign_refs(signer)?; let signed = project.sign_refs(signer)?;
let _head = project.set_head()?; let _head = project.set_head()?;
Ok((id, doc, signed)) Ok((project.id, doc, signed))
} }
#[derive(Error, Debug)] #[derive(Error, Debug)]

View File

@ -17,6 +17,7 @@ use crate::collections::HashMap;
use crate::git::ext as git_ext; use crate::git::ext as git_ext;
use crate::git::{Qualified, RefError, RefString}; use crate::git::{Qualified, RefError, RefString};
use crate::identity; use crate::identity;
use crate::identity::doc::DocError;
use crate::identity::{Id, IdError}; use crate::identity::{Id, IdError};
use crate::storage::refs::Refs; use crate::storage::refs::Refs;
@ -46,6 +47,8 @@ impl From<PublicKey> for Namespaces {
pub enum Error { pub enum Error {
#[error("invalid git reference")] #[error("invalid git reference")]
InvalidRef, InvalidRef,
#[error("identity doc: {0}")]
Doc(#[from] DocError),
#[error("git reference error: {0}")] #[error("git reference error: {0}")]
Ref(#[from] RefError), Ref(#[from] RefError),
#[error(transparent)] #[error(transparent)]

View File

@ -212,6 +212,20 @@ impl Repository {
Ok(Self { id, backend }) Ok(Self { id, backend })
} }
/// Create the repository's identity branch.
pub fn init(
doc: &Doc<Verified>,
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 /// Verify all references in the repository, checking that they are signed
/// as part of 'sigrefs'. Also verify that no signed reference is missing /// as part of 'sigrefs'. Also verify that no signed reference is missing
/// from the repository. /// from the repository.