Move doc initialization to storage
Signed-off-by: Alexis Sellier <alexis@radicle.xyz>
This commit is contained in:
parent
b37fef9f22
commit
d309f593b1
|
|
@ -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(),
|
||||||
)
|
)
|
||||||
})?;
|
})?;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
})
|
})
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue