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 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(),
)
})?;
}

View File

@ -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))
})

View File

@ -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<Verified> {
Ok((oid, sig))
}
pub fn create<S: WriteStorage>(
&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<git::Oid, DocError> {
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<R: WriteRepository>(
pub fn update(
&self,
remote: &RemoteId,
msg: &str,
signatures: &[(&PublicKey, Signature)],
repo: &R,
repo: &git2::Repository,
) -> Result<git::Oid, DocError> {
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)
}

View File

@ -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<G: Signer>(
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<G: Signer>(
let signed = project.sign_refs(signer)?;
let _head = project.set_head()?;
Ok((id, doc, signed))
Ok((project.id, doc, signed))
}
#[derive(Error, Debug)]

View File

@ -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<PublicKey> 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)]

View File

@ -212,6 +212,20 @@ impl Repository {
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
/// as part of 'sigrefs'. Also verify that no signed reference is missing
/// from the repository.