Make `Id` a `Copy`

This commit is contained in:
Alexis Sellier 2022-09-27 14:13:20 +02:00
parent a20d16fc31
commit 27e39c0df5
No known key found for this signature in database
11 changed files with 78 additions and 77 deletions

View File

@ -108,7 +108,7 @@ fn drain<H: Handle>(stream: &UnixStream, handle: &H) -> Result<(), DrainError> {
} }
fn fetch<W: Write, H: Handle>(id: Id, mut writer: W, handle: &H) -> Result<(), DrainError> { fn fetch<W: Write, H: Handle>(id: Id, mut writer: W, handle: &H) -> Result<(), DrainError> {
match handle.fetch(id.clone()) { match handle.fetch(id) {
Err(e) => { Err(e) => {
return Err(DrainError::Client(e)); return Err(DrainError::Client(e));
} }

View File

@ -272,7 +272,7 @@ where
} }
/// Get a project from storage, using the local node's key. /// Get a project from storage, using the local node's key.
pub fn get(&self, proj: &Id) -> Result<Option<Doc<Verified>>, storage::Error> { pub fn get(&self, proj: Id) -> Result<Option<Doc<Verified>>, storage::Error> {
self.storage.get(&self.node_id(), proj) self.storage.get(&self.node_id(), proj)
} }
@ -306,12 +306,12 @@ where
&mut self.reactor &mut self.reactor
} }
pub fn lookup(&self, id: &Id) -> Lookup { pub fn lookup(&self, id: Id) -> Lookup {
Lookup { Lookup {
local: self.storage.get(&self.node_id(), id).unwrap(), local: self.storage.get(&self.node_id(), id).unwrap(),
remote: self remote: self
.routing .routing
.get(id) .get(&id)
.map_or(vec![], |r| r.iter().cloned().collect()), .map_or(vec![], |r| r.iter().cloned().collect()),
} }
} }
@ -391,7 +391,7 @@ where
}; };
log::debug!("Found {} seeds for {}", seeds.len(), id); log::debug!("Found {} seeds for {}", seeds.len(), id);
let mut repo = match self.storage.repository(&id) { let mut repo = match self.storage.repository(id) {
Ok(repo) => repo, Ok(repo) => repo,
Err(err) => { Err(err) => {
log::error!("Error opening repo for {}: {}", id, err); log::error!("Error opening repo for {}: {}", id, err);
@ -445,7 +445,7 @@ where
} }
Command::AnnounceRefs(id) => { Command::AnnounceRefs(id) => {
let node = self.node_id(); let node = self.node_id();
let repo = self.storage.repository(&id).unwrap(); let repo = self.storage.repository(id).unwrap();
let remote = repo.remote(&node).unwrap(); let remote = repo.remote(&node).unwrap();
let peers = self.sessions.negotiated().map(|(_, p)| p); let peers = self.sessions.negotiated().map(|(_, p)| p);
let refs = remote.refs.into(); let refs = remote.refs.into();
@ -689,12 +689,12 @@ where
// TODO: Check that we're tracking this user as well. // TODO: Check that we're tracking this user as well.
if self.config.is_tracking(&message.id) { if self.config.is_tracking(&message.id) {
// TODO: Check refs to see if we should try to fetch or not. // TODO: Check refs to see if we should try to fetch or not.
let updated = self.storage.fetch(&message.id, git).unwrap(); let updated = self.storage.fetch(message.id, git).unwrap();
let is_updated = !updated.is_empty(); let is_updated = !updated.is_empty();
self.reactor.event(Event::RefsFetched { self.reactor.event(Event::RefsFetched {
from: git.clone(), from: git.clone(),
project: message.id.clone(), project: message.id,
updated, updated,
}); });
@ -747,12 +747,12 @@ where
for proj_id in inventory { for proj_id in inventory {
let inventory = self let inventory = self
.routing .routing
.entry(proj_id.clone()) .entry(*proj_id)
.or_insert_with(|| HashSet::with_hasher(self.rng.clone().into())); .or_insert_with(|| HashSet::with_hasher(self.rng.clone().into()));
// TODO: Fire an event on routing update. // TODO: Fire an event on routing update.
if inventory.insert(from) && self.config.is_tracking(proj_id) { if inventory.insert(from) && self.config.is_tracking(proj_id) {
self.storage.fetch(proj_id, remote).unwrap(); self.storage.fetch(*proj_id, remote).unwrap();
} }
} }
} }

View File

@ -95,7 +95,7 @@ impl Reactor {
/// Relay a message to interested peers. /// Relay a message to interested peers.
pub fn relay<'a>(&mut self, msg: Message, peers: impl IntoIterator<Item = &'a Session>) { pub fn relay<'a>(&mut self, msg: Message, peers: impl IntoIterator<Item = &'a Session>) {
if let Message::RefsAnnouncement { message, .. } = &msg { if let Message::RefsAnnouncement { message, .. } = &msg {
let id = message.id.clone(); let id = message.id;
let peers = peers.into_iter().filter(|p| { let peers = peers.into_iter().filter(|p| {
if let Some(subscribe) = &p.subscribe { if let Some(subscribe) = &p.subscribe {
subscribe.filter.contains(&id) subscribe.filter.contains(&id)

View File

@ -168,7 +168,7 @@ fn test_tracking() {
let proj_id: identity::Id = test::arbitrary::gen(1); let proj_id: identity::Id = test::arbitrary::gen(1);
let (sender, receiver) = chan::bounded(1); let (sender, receiver) = chan::bounded(1);
alice.command(Command::Track(proj_id.clone(), sender)); alice.command(Command::Track(proj_id, sender));
let policy_change = receiver let policy_change = receiver
.recv() .recv()
.map_err(client::handle::Error::from) .map_err(client::handle::Error::from)
@ -177,7 +177,7 @@ fn test_tracking() {
assert!(alice.config().is_tracking(&proj_id)); assert!(alice.config().is_tracking(&proj_id));
let (sender, receiver) = chan::bounded(1); let (sender, receiver) = chan::bounded(1);
alice.command(Command::Untrack(proj_id.clone(), sender)); alice.command(Command::Untrack(proj_id, sender));
let policy_change = receiver let policy_change = receiver
.recv() .recv()
.map_err(client::handle::Error::from) .map_err(client::handle::Error::from)
@ -405,30 +405,30 @@ fn test_push_and_pull() {
// Bob tracks Alice's project. // Bob tracks Alice's project.
let (sender, _) = chan::bounded(1); let (sender, _) = chan::bounded(1);
bob.command(service::Command::Track(proj_id.clone(), sender)); bob.command(service::Command::Track(proj_id, sender));
// Eve tracks Alice's project. // Eve tracks Alice's project.
let (sender, _) = chan::bounded(1); let (sender, _) = chan::bounded(1);
eve.command(service::Command::Track(proj_id.clone(), sender)); eve.command(service::Command::Track(proj_id, sender));
// Neither of them have it in the beginning. // Neither of them have it in the beginning.
assert!(eve.get(&proj_id).unwrap().is_none()); assert!(eve.get(proj_id).unwrap().is_none());
assert!(bob.get(&proj_id).unwrap().is_none()); assert!(bob.get(proj_id).unwrap().is_none());
// Alice announces her refs. // Alice announces her refs.
// We now expect Eve to fetch Alice's project from Alice. // We now expect Eve to fetch Alice's project from Alice.
// Then we expect Bob to fetch Alice's project from Eve. // Then we expect Bob to fetch Alice's project from Eve.
alice.command(service::Command::AnnounceRefs(proj_id.clone())); alice.command(service::Command::AnnounceRefs(proj_id));
sim.run_while([&mut alice, &mut bob, &mut eve], |s| !s.is_settled()); sim.run_while([&mut alice, &mut bob, &mut eve], |s| !s.is_settled());
assert!(eve assert!(eve
.storage() .storage()
.get(&alice.node_id(), &proj_id) .get(&alice.node_id(), proj_id)
.unwrap() .unwrap()
.is_some()); .is_some());
assert!(bob assert!(bob
.storage() .storage()
.get(&alice.node_id(), &proj_id) .get(&alice.node_id(), proj_id)
.unwrap() .unwrap()
.is_some()); .is_some());
assert_matches!( assert_matches!(
@ -455,7 +455,7 @@ fn prop_inventory_exchange_dense() {
] { ] {
for id in inv.keys() { for id in inv.keys() {
routing routing
.entry(id.clone()) .entry(*id)
.or_insert_with(|| HashSet::with_hasher(rng.clone().into())) .or_insert_with(|| HashSet::with_hasher(rng.clone().into()))
.insert(*peer); .insert(*peer);
} }
@ -481,16 +481,16 @@ fn prop_inventory_exchange_dense() {
for (proj_id, remotes) in &routing { for (proj_id, remotes) in &routing {
for peer in peers.values() { for peer in peers.values() {
let lookup = peer.lookup(proj_id); let lookup = peer.lookup(*proj_id);
if lookup.local.is_some() { if lookup.local.is_some() {
peer.get(proj_id) peer.get(*proj_id)
.expect("There are no errors querying storage") .expect("There are no errors querying storage")
.expect("The project is available locally"); .expect("The project is available locally");
} else { } else {
for remote in &lookup.remote { for remote in &lookup.remote {
peers[remote] peers[remote]
.get(proj_id) .get(*proj_id)
.expect("There are no errors querying storage") .expect("There are no errors querying storage")
.expect("The project is available remotely"); .expect("The project is available remotely");
} }

View File

@ -11,7 +11,7 @@ fn main() -> anyhow::Result<()> {
let output = radicle::git::run(&cwd, &["push", "rad"])?; let output = radicle::git::run(&cwd, &["push", "rad"])?;
println!("{}", output); println!("{}", output);
let project = profile.storage.repository(&id)?; let project = profile.storage.repository(id)?;
let sigrefs = profile.storage.sign_refs(&project, &profile.signer)?; let sigrefs = profile.storage.sign_refs(&project, &profile.signer)?;
profile.node()?.announce_refs(&id)?; profile.node()?.announce_refs(&id)?;

View File

@ -138,7 +138,7 @@ impl Doc<Verified> {
// //
let (doc_oid, doc) = self.encode()?; let (doc_oid, doc) = self.encode()?;
let id = Id::from(doc_oid); let id = Id::from(doc_oid);
let repo = storage.repository(&id).unwrap(); let repo = storage.repository(id).unwrap();
let tree = git::write_tree(*PATH, doc.as_slice(), repo.raw())?; let tree = git::write_tree(*PATH, doc.as_slice(), repo.raw())?;
let oid = Doc::commit(remote, &tree, msg, &[], repo.raw())?; let oid = Doc::commit(remote, &tree, msg, &[], repo.raw())?;
@ -379,6 +379,8 @@ pub enum IdentityError {
InvalidSignature(PublicKey, crypto::Error), InvalidSignature(PublicKey, crypto::Error),
#[error("quorum not reached: {0} signatures for a threshold of {1}")] #[error("quorum not reached: {0} signatures for a threshold of {1}")]
QuorumNotReached(usize, usize), QuorumNotReached(usize, usize),
#[error("the identity branch was not found")]
NotFound,
} }
#[derive(Clone, Debug, PartialEq, Eq)] #[derive(Clone, Debug, PartialEq, Eq)]
@ -421,7 +423,7 @@ impl Identity<Untrusted> {
pub fn load<R: ReadRepository>( pub fn load<R: ReadRepository>(
remote: &RemoteId, remote: &RemoteId,
repo: &R, repo: &R,
) -> Result<Option<Identity<Oid>>, IdentityError> { ) -> Result<Identity<Oid>, IdentityError> {
if let Some(head) = Doc::<Untrusted>::head(remote, repo)? { if let Some(head) = Doc::<Untrusted>::head(remote, repo)? {
let mut history = repo.revwalk(head)?.collect::<Vec<_>>(); let mut history = repo.revwalk(head)?.collect::<Vec<_>>();
@ -466,16 +468,16 @@ impl Identity<Untrusted> {
current = blob.id().into(); current = blob.id().into();
} }
return Ok(Some(Identity { return Ok(Identity {
root, root,
head, head,
current, current,
revision, revision,
doc: trusted, doc: trusted,
signatures: signatures.into_iter().collect(), signatures: signatures.into_iter().collect(),
})); });
} }
Ok(None) Err(IdentityError::NotFound)
} }
} }
@ -505,14 +507,14 @@ mod test {
fixtures::project(tempdir.path().join("copy"), &storage, &alice).unwrap(); fixtures::project(tempdir.path().join("copy"), &storage, &alice).unwrap();
// Bob and Eve fork the project from Alice. // Bob and Eve fork the project from Alice.
rad::fork_remote(&id, alice.public_key(), &bob, &storage).unwrap(); rad::fork_remote(id, alice.public_key(), &bob, &storage).unwrap();
rad::fork_remote(&id, alice.public_key(), &eve, &storage).unwrap(); rad::fork_remote(id, alice.public_key(), &eve, &storage).unwrap();
// TODO: In some cases we want to get the repo and the project, but don't // TODO: In some cases we want to get the repo and the project, but don't
// want to have to create a repository object twice. Perhaps there should // want to have to create a repository object twice. Perhaps there should
// be a way of getting a project from a repo. // be a way of getting a project from a repo.
let mut proj = storage.get(alice.public_key(), &id).unwrap().unwrap(); let mut proj = storage.get(alice.public_key(), id).unwrap().unwrap();
let repo = storage.repository(&id).unwrap(); let repo = storage.repository(id).unwrap();
// Make a change to the description and sign it. // Make a change to the description and sign it.
proj.payload.description += "!"; proj.payload.description += "!";
@ -575,8 +577,7 @@ mod test {
let identity: Identity<Id> = Identity::load(alice.public_key(), &repo) let identity: Identity<Id> = Identity::load(alice.public_key(), &repo)
.unwrap() .unwrap()
.unwrap() .verified(id)
.verified(id.clone())
.unwrap(); .unwrap();
assert_eq!(identity.signatures.len(), 2); assert_eq!(identity.signatures.len(), 2);
@ -586,7 +587,7 @@ mod test {
assert_eq!(identity.head, head); assert_eq!(identity.head, head);
assert_eq!(identity.doc, proj); assert_eq!(identity.doc, proj);
let proj = storage.get(alice.public_key(), &id).unwrap().unwrap(); let proj = storage.get(alice.public_key(), id).unwrap().unwrap();
assert_eq!(proj.description, "Acme's repository!?"); assert_eq!(proj.description, "Acme's repository!?");
} }

View File

@ -17,7 +17,7 @@ pub enum IdError {
Multibase(#[from] multibase::Error), Multibase(#[from] multibase::Error),
} }
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub struct Id(git::Oid); pub struct Id(git::Oid);
impl fmt::Display for Id { impl fmt::Display for Id {

View File

@ -100,7 +100,7 @@ pub enum ForkError {
/// Create a local tree for an existing project, from an existing remote. /// Create a local tree for an existing project, from an existing remote.
pub fn fork_remote<G: Signer, S: storage::WriteStorage>( pub fn fork_remote<G: Signer, S: storage::WriteStorage>(
proj: &Id, proj: Id,
remote: &RemoteId, remote: &RemoteId,
signer: G, signer: G,
storage: S, storage: S,
@ -117,7 +117,7 @@ pub fn fork_remote<G: Signer, S: storage::WriteStorage>(
let me = signer.public_key(); let me = signer.public_key();
let project = storage let project = storage
.get(remote, proj)? .get(remote, proj)?
.ok_or_else(|| ForkError::NotFound(proj.clone()))?; .ok_or(ForkError::NotFound(proj))?;
let repository = storage.repository(proj)?; let repository = storage.repository(proj)?;
let raw = repository.raw(); let raw = repository.raw();
@ -149,7 +149,7 @@ pub fn fork_remote<G: Signer, S: storage::WriteStorage>(
} }
pub fn fork<G: Signer, S: storage::WriteStorage>( pub fn fork<G: Signer, S: storage::WriteStorage>(
proj: &Id, proj: Id,
signer: &G, signer: &G,
storage: &S, storage: &S,
) -> Result<(), ForkError> { ) -> Result<(), ForkError> {
@ -208,13 +208,13 @@ pub enum CloneError {
} }
pub fn clone<P: AsRef<Path>, G: Signer, S: storage::WriteStorage, H: node::Handle>( pub fn clone<P: AsRef<Path>, G: Signer, S: storage::WriteStorage, H: node::Handle>(
proj: &Id, proj: Id,
path: P, path: P,
signer: &G, signer: &G,
storage: &S, storage: &S,
handle: &H, handle: &H,
) -> Result<git2::Repository, CloneError> { ) -> Result<git2::Repository, CloneError> {
let _ = handle.fetch(proj)?; let _ = handle.fetch(&proj)?;
let _ = fork(proj, signer, storage)?; let _ = fork(proj, signer, storage)?;
let working = checkout(proj, signer.public_key(), path, storage)?; let working = checkout(proj, signer.public_key(), path, storage)?;
@ -234,7 +234,7 @@ pub enum CloneUrlError {
} }
pub fn clone_url<P: AsRef<Path>, G: Signer, S: storage::WriteStorage>( pub fn clone_url<P: AsRef<Path>, G: Signer, S: storage::WriteStorage>(
proj: &Id, proj: Id,
url: &git::Url, url: &git::Url,
path: P, path: P,
signer: &G, signer: &G,
@ -261,7 +261,7 @@ pub enum CheckoutError {
/// Checkout a project from storage as a working copy. /// Checkout a project from storage as a working copy.
/// This effectively does a `git-clone` from storage. /// This effectively does a `git-clone` from storage.
pub fn checkout<P: AsRef<Path>, S: storage::ReadStorage>( pub fn checkout<P: AsRef<Path>, S: storage::ReadStorage>(
proj: &Id, proj: Id,
remote: &RemoteId, remote: &RemoteId,
path: P, path: P,
storage: &S, storage: &S,
@ -270,14 +270,14 @@ pub fn checkout<P: AsRef<Path>, S: storage::ReadStorage>(
// TODO: Look into sharing object databases. // TODO: Look into sharing object databases.
let project = storage let project = storage
.get(remote, proj)? .get(remote, proj)?
.ok_or_else(|| CheckoutError::NotFound(proj.clone()))?; .ok_or(CheckoutError::NotFound(proj))?;
let mut opts = git2::RepositoryInitOptions::new(); let mut opts = git2::RepositoryInitOptions::new();
opts.no_reinit(true).description(&project.description); opts.no_reinit(true).description(&project.description);
let repo = git2::Repository::init_opts(path, &opts)?; let repo = git2::Repository::init_opts(path, &opts)?;
let default_branch = project.default_branch.as_str(); let default_branch = project.default_branch.as_str();
let url = storage.url(proj); let url = storage.url(&proj);
// Configure and fetch all refs from remote. // Configure and fetch all refs from remote.
git::configure_remote(&repo, REMOTE_NAME, remote, &url)?.fetch::<&str>(&[], None, None)?; git::configure_remote(&repo, REMOTE_NAME, remote, &url)?.fetch::<&str>(&[], None, None)?;
@ -341,9 +341,9 @@ mod tests {
) )
.unwrap(); .unwrap();
let project = storage.get(&public_key, &proj).unwrap().unwrap(); let project = storage.get(&public_key, proj).unwrap().unwrap();
let remotes: HashMap<_, _> = storage let remotes: HashMap<_, _> = storage
.repository(&proj) .repository(proj)
.unwrap() .unwrap()
.remotes() .remotes()
.unwrap() .unwrap()
@ -385,10 +385,10 @@ mod tests {
.unwrap(); .unwrap();
// Bob forks it and creates a checkout. // Bob forks it and creates a checkout.
fork(&id, &bob, &storage).unwrap(); fork(id, &bob, &storage).unwrap();
checkout(&id, bob_id, tempdir.path().join("copy"), &storage).unwrap(); checkout(id, bob_id, tempdir.path().join("copy"), &storage).unwrap();
let bob_remote = storage.repository(&id).unwrap().remote(bob_id).unwrap(); let bob_remote = storage.repository(id).unwrap().remote(bob_id).unwrap();
assert_eq!( assert_eq!(
bob_remote.refs.get(&refname!("master")), bob_remote.refs.get(&refname!("master")),
@ -414,7 +414,7 @@ mod tests {
) )
.unwrap(); .unwrap();
let copy = checkout(&id, remote_id, tempdir.path().join("copy"), &storage).unwrap(); let copy = checkout(id, remote_id, tempdir.path().join("copy"), &storage).unwrap();
assert_eq!( assert_eq!(
copy.head().unwrap().target(), copy.head().unwrap().target(),

View File

@ -218,20 +218,20 @@ impl Remote<Verified> {
pub trait ReadStorage { pub trait ReadStorage {
fn path(&self) -> &Path; fn path(&self) -> &Path;
fn url(&self, proj: &Id) -> Url; fn url(&self, proj: &Id) -> Url;
fn get(&self, remote: &RemoteId, proj: &Id) -> Result<Option<identity::Doc<Verified>>, Error>; fn get(&self, remote: &RemoteId, proj: Id) -> Result<Option<identity::Doc<Verified>>, Error>;
fn inventory(&self) -> Result<Inventory, Error>; fn inventory(&self) -> Result<Inventory, Error>;
} }
pub trait WriteStorage: ReadStorage { pub trait WriteStorage: ReadStorage {
type Repository: WriteRepository; type Repository: WriteRepository;
fn repository(&self, proj: &Id) -> Result<Self::Repository, Error>; fn repository(&self, proj: Id) -> Result<Self::Repository, Error>;
fn sign_refs<G: Signer>( fn sign_refs<G: Signer>(
&self, &self,
repository: &Self::Repository, repository: &Self::Repository,
signer: G, signer: G,
) -> Result<SignedRefs<Verified>, Error>; ) -> Result<SignedRefs<Verified>, Error>;
fn fetch(&self, proj_id: &Id, remote: &Url) -> Result<Vec<RefUpdate>, FetchError>; fn fetch(&self, proj_id: Id, remote: &Url) -> Result<Vec<RefUpdate>, FetchError>;
} }
pub trait ReadRepository { pub trait ReadRepository {
@ -280,7 +280,7 @@ where
self.deref().inventory() self.deref().inventory()
} }
fn get(&self, remote: &RemoteId, proj: &Id) -> Result<Option<identity::Doc<Verified>>, Error> { fn get(&self, remote: &RemoteId, proj: Id) -> Result<Option<identity::Doc<Verified>>, Error> {
self.deref().get(remote, proj) self.deref().get(remote, proj)
} }
} }
@ -292,7 +292,7 @@ where
{ {
type Repository = S::Repository; type Repository = S::Repository;
fn repository(&self, proj: &Id) -> Result<Self::Repository, Error> { fn repository(&self, proj: Id) -> Result<Self::Repository, Error> {
self.deref().repository(proj) self.deref().repository(proj)
} }
@ -304,7 +304,7 @@ where
self.deref().sign_refs(repository, signer) self.deref().sign_refs(repository, signer)
} }
fn fetch(&self, proj_id: &Id, remote: &Url) -> Result<Vec<RefUpdate>, FetchError> { fn fetch(&self, proj_id: Id, remote: &Url) -> Result<Vec<RefUpdate>, FetchError> {
self.deref().fetch(proj_id, remote) self.deref().fetch(proj_id, remote)
} }
} }

View File

@ -66,7 +66,7 @@ impl ReadStorage for Storage {
} }
} }
fn get(&self, remote: &RemoteId, proj: &Id) -> Result<Option<Doc<Verified>>, Error> { fn get(&self, remote: &RemoteId, proj: Id) -> Result<Option<Doc<Verified>>, Error> {
// TODO: Don't create a repo here if it doesn't exist? // TODO: Don't create a repo here if it doesn't exist?
// Perhaps for checking we could have a `contains` method? // Perhaps for checking we could have a `contains` method?
self.repository(proj)? self.repository(proj)?
@ -82,8 +82,8 @@ impl ReadStorage for Storage {
impl WriteStorage for Storage { impl WriteStorage for Storage {
type Repository = Repository; type Repository = Repository;
fn repository(&self, proj: &Id) -> Result<Self::Repository, Error> { fn repository(&self, proj: Id) -> Result<Self::Repository, Error> {
Repository::open(paths::repository(self, proj)) Repository::open(paths::repository(self, &proj))
} }
fn sign_refs<G: Signer>( fn sign_refs<G: Signer>(
@ -94,7 +94,7 @@ impl WriteStorage for Storage {
repository.sign_refs(signer) repository.sign_refs(signer)
} }
fn fetch(&self, proj_id: &Id, remote: &Url) -> Result<Vec<RefUpdate>, FetchError> { fn fetch(&self, proj_id: Id, remote: &Url) -> Result<Vec<RefUpdate>, FetchError> {
let mut repo = self.repository(proj_id).unwrap(); let mut repo = self.repository(proj_id).unwrap();
let mut path = remote.path.clone(); let mut path = remote.path.clone();
@ -139,7 +139,7 @@ impl Storage {
pub fn inspect(&self) -> Result<(), Error> { pub fn inspect(&self) -> Result<(), Error> {
for proj in self.projects()? { for proj in self.projects()? {
let repo = self.repository(&proj)?; let repo = self.repository(proj)?;
for r in repo.raw().references()? { for r in repo.raw().references()? {
let r = r?; let r = r?;
@ -264,7 +264,7 @@ impl Repository {
Ok(()) Ok(())
} }
pub fn identity(&self, remote: &RemoteId) -> Result<Option<Identity<Oid>>, IdentityError> { pub fn identity(&self, remote: &RemoteId) -> Result<Identity<Oid>, IdentityError> {
Identity::load(remote, self) Identity::load(remote, self)
} }
@ -648,7 +648,7 @@ mod tests {
}) })
.unwrap(); .unwrap();
let project = storage.repository(proj).unwrap(); let project = storage.repository(*proj).unwrap();
let remotes = project.remotes().unwrap(); let remotes = project.remotes().unwrap();
// Strip the remote refs of sigrefs so we can compare them. // Strip the remote refs of sigrefs so we can compare them.
@ -671,7 +671,7 @@ mod tests {
let alice = fixtures::storage(tmp.path().join("alice"), alice_signer).unwrap(); let alice = fixtures::storage(tmp.path().join("alice"), alice_signer).unwrap();
let bob = Storage::open(tmp.path().join("bob")).unwrap(); let bob = Storage::open(tmp.path().join("bob")).unwrap();
let inventory = alice.inventory().unwrap(); let inventory = alice.inventory().unwrap();
let proj = inventory.first().unwrap(); let proj = *inventory.first().unwrap();
let repo = alice.repository(proj).unwrap(); let repo = alice.repository(proj).unwrap();
let remotes = repo.remotes().unwrap().collect::<Vec<_>>(); let remotes = repo.remotes().unwrap().collect::<Vec<_>>();
let refname = git::refname!("heads/master"); let refname = git::refname!("heads/master");
@ -682,7 +682,7 @@ mod tests {
.unwrap() .unwrap()
.fetch(&git::Url { .fetch(&git::Url {
scheme: git_url::Scheme::File, scheme: git_url::Scheme::File,
path: paths::repository(&alice, proj) path: paths::repository(&alice, &proj)
.to_string_lossy() .to_string_lossy()
.into_owned() .into_owned()
.into(), .into(),
@ -734,11 +734,11 @@ mod tests {
}; };
// Have Bob fetch Alice's refs. // Have Bob fetch Alice's refs.
let updates = bob.repository(&proj_id).unwrap().fetch(&alice_url).unwrap(); let updates = bob.repository(proj_id).unwrap().fetch(&alice_url).unwrap();
// Three refs are created: the branch, the signature and the id. // Three refs are created: the branch, the signature and the id.
assert_eq!(updates.len(), 3); assert_eq!(updates.len(), 3);
let alice_proj_storage = alice.repository(&proj_id).unwrap(); let alice_proj_storage = alice.repository(proj_id).unwrap();
let alice_head = proj_repo.find_commit(alice_head).unwrap(); let alice_head = proj_repo.find_commit(alice_head).unwrap();
let alice_head = git::commit(&proj_repo, &alice_head, &refname, "Making changes", "Alice") let alice_head = git::commit(&proj_repo, &alice_head, &refname, "Making changes", "Alice")
.unwrap() .unwrap()
@ -747,7 +747,7 @@ mod tests {
alice.sign_refs(&alice_proj_storage, &alice_signer).unwrap(); alice.sign_refs(&alice_proj_storage, &alice_signer).unwrap();
// Have Bob fetch Alice's new commit. // Have Bob fetch Alice's new commit.
let updates = bob.repository(&proj_id).unwrap().fetch(&alice_url).unwrap(); let updates = bob.repository(proj_id).unwrap().fetch(&alice_url).unwrap();
// The branch and signature refs are updated. // The branch and signature refs are updated.
assert_matches!( assert_matches!(
updates.as_slice(), updates.as_slice(),
@ -755,7 +755,7 @@ mod tests {
); );
// Bob's storage is updated. // Bob's storage is updated.
let bob_repo = bob.repository(&proj_id).unwrap(); let bob_repo = bob.repository(proj_id).unwrap();
let bob_master = bob_repo.reference(alice_id, &refname).unwrap().unwrap(); let bob_master = bob_repo.reference(alice_id, &refname).unwrap().unwrap();
assert_eq!(bob_master.target().unwrap(), alice_head); assert_eq!(bob_master.target().unwrap(), alice_head);
@ -769,7 +769,7 @@ mod tests {
let storage = Storage::open(tmp.path()).unwrap(); let storage = Storage::open(tmp.path()).unwrap();
let proj_id = arbitrary::gen::<Id>(1); let proj_id = arbitrary::gen::<Id>(1);
let alice = *signer.public_key(); let alice = *signer.public_key();
let project = storage.repository(&proj_id).unwrap(); let project = storage.repository(proj_id).unwrap();
let backend = &project.backend; let backend = &project.backend;
let sig = git2::Signature::now(&alice.to_string(), "anonymous@radicle.xyz").unwrap(); let sig = git2::Signature::now(&alice.to_string(), "anonymous@radicle.xyz").unwrap();
let head = git::initial_commit(backend, &sig).unwrap(); let head = git::initial_commit(backend, &sig).unwrap();

View File

@ -44,8 +44,8 @@ impl ReadStorage for MockStorage {
} }
} }
fn get(&self, _remote: &RemoteId, proj: &Id) -> Result<Option<Doc<Verified>>, Error> { fn get(&self, _remote: &RemoteId, proj: Id) -> Result<Option<Doc<Verified>>, Error> {
Ok(self.inventory.get(proj).cloned()) Ok(self.inventory.get(&proj).cloned())
} }
fn inventory(&self) -> Result<Inventory, Error> { fn inventory(&self) -> Result<Inventory, Error> {
@ -56,7 +56,7 @@ impl ReadStorage for MockStorage {
impl WriteStorage for MockStorage { impl WriteStorage for MockStorage {
type Repository = MockRepository; type Repository = MockRepository;
fn repository(&self, _proj: &Id) -> Result<Self::Repository, Error> { fn repository(&self, _proj: Id) -> Result<Self::Repository, Error> {
Ok(MockRepository {}) Ok(MockRepository {})
} }
@ -68,7 +68,7 @@ impl WriteStorage for MockStorage {
todo!() todo!()
} }
fn fetch(&self, _proj_id: &Id, _remote: &Url) -> Result<Vec<RefUpdate>, FetchError> { fn fetch(&self, _proj_id: Id, _remote: &Url) -> Result<Vec<RefUpdate>, FetchError> {
Ok(vec![]) Ok(vec![])
} }
} }