node: Implement project retrieval
Signed-off-by: Alexis Sellier <self@cloudhead.io>
This commit is contained in:
parent
910cd74294
commit
c3b7a6fbd7
|
|
@ -1,16 +1,16 @@
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
use git_ref_format as format;
|
use git_ref_format as format;
|
||||||
use radicle_git_ext as git_ext;
|
|
||||||
|
|
||||||
use crate::collections::HashMap;
|
use crate::collections::HashMap;
|
||||||
use crate::identity::UserId;
|
use crate::identity::UserId;
|
||||||
use crate::storage::refs::Refs;
|
use crate::storage::refs::Refs;
|
||||||
use crate::storage::RemoteId;
|
use crate::storage::RemoteId;
|
||||||
|
|
||||||
pub use git_ext::Oid;
|
pub use ext::Oid;
|
||||||
pub use git_ref_format::{refname, RefStr, RefString};
|
pub use git_ref_format::{refname, RefStr, RefString};
|
||||||
pub use git_url::Url;
|
pub use git_url::Url;
|
||||||
|
pub use radicle_git_ext as ext;
|
||||||
|
|
||||||
/// Default port of the `git` transport protocol.
|
/// Default port of the `git` transport protocol.
|
||||||
pub const PROTOCOL_PORT: u16 = 9418;
|
pub const PROTOCOL_PORT: u16 = 9418;
|
||||||
|
|
@ -118,14 +118,14 @@ pub fn set_upstream(
|
||||||
let branch_merge = format!("branch.{}.merge", branch);
|
let branch_merge = format!("branch.{}.merge", branch);
|
||||||
|
|
||||||
config.remove_multivar(&branch_remote, ".*").or_else(|e| {
|
config.remove_multivar(&branch_remote, ".*").or_else(|e| {
|
||||||
if git_ext::is_not_found_err(&e) {
|
if ext::is_not_found_err(&e) {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(e)
|
Err(e)
|
||||||
}
|
}
|
||||||
})?;
|
})?;
|
||||||
config.remove_multivar(&branch_merge, ".*").or_else(|e| {
|
config.remove_multivar(&branch_merge, ".*").or_else(|e| {
|
||||||
if git_ext::is_not_found_err(&e) {
|
if ext::is_not_found_err(&e) {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(e)
|
Err(e)
|
||||||
|
|
|
||||||
|
|
@ -7,8 +7,9 @@ use radicle_git_ext::Oid;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use thiserror::Error;
|
use thiserror::Error;
|
||||||
|
|
||||||
use crate::crypto;
|
use crate::crypto::{self, Verified};
|
||||||
use crate::hash;
|
use crate::hash;
|
||||||
|
use crate::storage::Remotes;
|
||||||
|
|
||||||
pub static IDENTITY_PATH: Lazy<&Path> = Lazy::new(|| Path::new("Radicle.toml"));
|
pub static IDENTITY_PATH: Lazy<&Path> = Lazy::new(|| Path::new("Radicle.toml"));
|
||||||
|
|
||||||
|
|
@ -86,6 +87,17 @@ impl fmt::Display for Did {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A stored and verified project.
|
||||||
|
#[derive(Debug, Clone)]
|
||||||
|
pub struct Project {
|
||||||
|
/// The project identifier.
|
||||||
|
pub id: ProjId,
|
||||||
|
/// The latest project identity document.
|
||||||
|
pub doc: Doc,
|
||||||
|
/// The project remotes.
|
||||||
|
pub remotes: Remotes<Verified>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Error, Debug)]
|
#[derive(Error, Debug)]
|
||||||
pub enum DocError {
|
pub enum DocError {
|
||||||
#[error("toml: {0}")]
|
#[error("toml: {0}")]
|
||||||
|
|
@ -94,20 +106,20 @@ pub enum DocError {
|
||||||
Io(#[from] io::Error),
|
Io(#[from] io::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub struct Delegate {
|
pub struct Delegate {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub id: Did,
|
pub id: Did,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Serialize, Deserialize)]
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||||
pub struct Doc {
|
pub struct Doc {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub description: String,
|
pub description: String,
|
||||||
pub default_branch: String,
|
pub default_branch: String,
|
||||||
pub version: u32,
|
pub version: u32,
|
||||||
pub parent: Option<Oid>,
|
pub parent: Option<Oid>,
|
||||||
pub delegate: NonEmpty<Delegate>,
|
pub delegates: NonEmpty<Delegate>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Doc {
|
impl Doc {
|
||||||
|
|
@ -120,6 +132,10 @@ impl Doc {
|
||||||
|
|
||||||
Ok(id)
|
Ok(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn from_toml(bytes: &[u8]) -> Result<Self, toml::de::Error> {
|
||||||
|
toml::from_slice(bytes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
|
||||||
|
|
@ -19,12 +19,12 @@ use crate::address_manager::AddressManager;
|
||||||
use crate::clock::RefClock;
|
use crate::clock::RefClock;
|
||||||
use crate::collections::{HashMap, HashSet};
|
use crate::collections::{HashMap, HashSet};
|
||||||
use crate::crypto;
|
use crate::crypto;
|
||||||
use crate::identity::{ProjId, UserId};
|
use crate::identity::{ProjId, Project, UserId};
|
||||||
use crate::protocol::config::ProjectTracking;
|
use crate::protocol::config::ProjectTracking;
|
||||||
use crate::protocol::message::Message;
|
use crate::protocol::message::Message;
|
||||||
use crate::protocol::peer::{Peer, PeerError, PeerState};
|
use crate::protocol::peer::{Peer, PeerError, PeerState};
|
||||||
use crate::storage::{self, ReadRepository, WriteRepository};
|
use crate::storage::{self, ReadRepository, WriteRepository};
|
||||||
use crate::storage::{Inventory, ReadStorage, Remotes, WriteStorage};
|
use crate::storage::{Inventory, ReadStorage, WriteStorage};
|
||||||
|
|
||||||
pub use crate::protocol::config::{Config, Network};
|
pub use crate::protocol::config::{Config, Network};
|
||||||
|
|
||||||
|
|
@ -546,7 +546,7 @@ impl<S, T, G> Iterator for Protocol<S, T, G> {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Lookup {
|
pub struct Lookup {
|
||||||
/// Whether the project was found locally or not.
|
/// Whether the project was found locally or not.
|
||||||
pub local: Option<Remotes<crypto::Verified>>,
|
pub local: Option<Project>,
|
||||||
/// A list of remote peers on which the project is known to exist.
|
/// A list of remote peers on which the project is known to exist.
|
||||||
pub remote: Vec<NodeId>,
|
pub remote: Vec<NodeId>,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -52,7 +52,7 @@ pub fn init<S: storage::WriteStorage>(
|
||||||
default_branch: default_branch.clone(),
|
default_branch: default_branch.clone(),
|
||||||
version: 1,
|
version: 1,
|
||||||
parent: None,
|
parent: None,
|
||||||
delegate: NonEmpty::new(delegate),
|
delegates: NonEmpty::new(delegate),
|
||||||
};
|
};
|
||||||
|
|
||||||
let filename = *identity::IDENTITY_PATH;
|
let filename = *identity::IDENTITY_PATH;
|
||||||
|
|
@ -123,7 +123,9 @@ pub fn init<S: storage::WriteStorage>(
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::git;
|
use crate::git;
|
||||||
|
use crate::identity::{Delegate, Did};
|
||||||
use crate::storage::git::Storage;
|
use crate::storage::git::Storage;
|
||||||
|
use crate::storage::ReadStorage;
|
||||||
use crate::test::crypto;
|
use crate::test::crypto;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|
@ -137,7 +139,7 @@ mod tests {
|
||||||
let head = git::commit(&repo, &head, "Second commit", "anonymous").unwrap();
|
let head = git::commit(&repo, &head, "Second commit", "anonymous").unwrap();
|
||||||
let _branch = repo.branch("master", &head, false).unwrap();
|
let _branch = repo.branch("master", &head, false).unwrap();
|
||||||
|
|
||||||
let (_id, _refs) = init(
|
let (id, refs) = init(
|
||||||
&repo,
|
&repo,
|
||||||
"acme",
|
"acme",
|
||||||
"Acme's repo",
|
"Acme's repo",
|
||||||
|
|
@ -145,5 +147,20 @@ mod tests {
|
||||||
&mut storage,
|
&mut storage,
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
|
let project = storage.get(&id).unwrap().unwrap();
|
||||||
|
|
||||||
|
assert_eq!(project.remotes[storage.user_id()].refs, refs);
|
||||||
|
assert_eq!(project.id, id);
|
||||||
|
assert_eq!(project.doc.name, "acme");
|
||||||
|
assert_eq!(project.doc.description, "Acme's repo");
|
||||||
|
assert_eq!(project.doc.default_branch, BranchName::from("master"));
|
||||||
|
assert_eq!(
|
||||||
|
project.doc.delegates.first(),
|
||||||
|
&Delegate {
|
||||||
|
name: String::from("anonymous"),
|
||||||
|
id: Did::from(*storage.user_id()),
|
||||||
|
}
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,7 @@ use crate::crypto::{self, Unverified, Verified};
|
||||||
use crate::git::Url;
|
use crate::git::Url;
|
||||||
use crate::git::{RefError, RefStr};
|
use crate::git::{RefError, RefStr};
|
||||||
use crate::identity;
|
use crate::identity;
|
||||||
use crate::identity::{ProjId, ProjIdError, UserId};
|
use crate::identity::{ProjId, ProjIdError, Project, UserId};
|
||||||
use crate::storage::refs::Refs;
|
use crate::storage::refs::Refs;
|
||||||
|
|
||||||
use self::refs::SignedRefs;
|
use self::refs::SignedRefs;
|
||||||
|
|
@ -168,7 +168,7 @@ impl Remote<Verified> {
|
||||||
pub trait ReadStorage {
|
pub trait ReadStorage {
|
||||||
fn user_id(&self) -> &UserId;
|
fn user_id(&self) -> &UserId;
|
||||||
fn url(&self) -> Url;
|
fn url(&self) -> Url;
|
||||||
fn get(&self, proj: &ProjId) -> Result<Option<Remotes<Verified>>, Error>;
|
fn get(&self, proj: &ProjId) -> Result<Option<Project>, Error>;
|
||||||
fn inventory(&self) -> Result<Inventory, Error>;
|
fn inventory(&self) -> Result<Inventory, Error>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -215,7 +215,7 @@ where
|
||||||
self.deref().inventory()
|
self.deref().inventory()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(&self, proj: &ProjId) -> Result<Option<Remotes<Verified>>, Error> {
|
fn get(&self, proj: &ProjId) -> Result<Option<Project>, Error> {
|
||||||
self.deref().get(proj)
|
self.deref().get(proj)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,14 +5,14 @@ use std::{fmt, fs, io};
|
||||||
|
|
||||||
use git_ref_format::refspec;
|
use git_ref_format::refspec;
|
||||||
use once_cell::sync::Lazy;
|
use once_cell::sync::Lazy;
|
||||||
use radicle_git_ext as git_ext;
|
|
||||||
|
|
||||||
pub use radicle_git_ext::Oid;
|
pub use radicle_git_ext::Oid;
|
||||||
|
|
||||||
use crate::collections::HashMap;
|
use crate::collections::HashMap;
|
||||||
use crate::crypto::{Signer, Verified};
|
use crate::crypto::{Signer, Verified};
|
||||||
use crate::git;
|
use crate::git;
|
||||||
use crate::identity::{ProjId, UserId};
|
use crate::identity::{self, IDENTITY_PATH};
|
||||||
|
use crate::identity::{ProjId, Project, UserId};
|
||||||
use crate::storage::refs;
|
use crate::storage::refs;
|
||||||
use crate::storage::refs::{Refs, SignedRefs};
|
use crate::storage::refs::{Refs, SignedRefs};
|
||||||
use crate::storage::{
|
use crate::storage::{
|
||||||
|
|
@ -21,8 +21,7 @@ use crate::storage::{
|
||||||
|
|
||||||
use super::RemoteId;
|
use super::RemoteId;
|
||||||
|
|
||||||
pub static RADICLE_ID_REF: Lazy<refspec::PatternString> =
|
pub static RADICLE_ID_REF: Lazy<git::RefString> = Lazy::new(|| git::refname!("heads/radicle/id"));
|
||||||
Lazy::new(|| refspec::pattern!("heads/radicle/id"));
|
|
||||||
pub static REMOTES_GLOB: Lazy<refspec::PatternString> =
|
pub static REMOTES_GLOB: Lazy<refspec::PatternString> =
|
||||||
Lazy::new(|| refspec::pattern!("refs/remotes/*"));
|
Lazy::new(|| refspec::pattern!("refs/remotes/*"));
|
||||||
pub static SIGNATURES_GLOB: Lazy<refspec::PatternString> =
|
pub static SIGNATURES_GLOB: Lazy<refspec::PatternString> =
|
||||||
|
|
@ -52,19 +51,26 @@ impl ReadStorage for Storage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(&self, id: &ProjId) -> Result<Option<Remotes<Verified>>, Error> {
|
fn get(&self, id: &ProjId) -> Result<Option<Project>, 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?
|
||||||
match self.repository(id) {
|
let local = self.user_id();
|
||||||
Ok(r) => {
|
let repo = self.repository(id)?;
|
||||||
let remotes = r.remotes()?;
|
|
||||||
if remotes.is_empty() {
|
if let Some(doc) = repo.identity(local)? {
|
||||||
Ok(None)
|
let remotes = repo.remotes()?;
|
||||||
|
|
||||||
|
// TODO: We should check that there is at least one remote, which is
|
||||||
|
// the one of the local user, otherwise it means the project is in
|
||||||
|
// an corrupted state.
|
||||||
|
|
||||||
|
Ok(Some(Project {
|
||||||
|
id: id.clone(),
|
||||||
|
doc,
|
||||||
|
remotes,
|
||||||
|
}))
|
||||||
} else {
|
} else {
|
||||||
Ok(Some(remotes))
|
Ok(None)
|
||||||
}
|
|
||||||
}
|
|
||||||
Err(e) => Err(e),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -163,7 +169,7 @@ pub struct Repository {
|
||||||
impl Repository {
|
impl Repository {
|
||||||
pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
|
pub fn open<P: AsRef<Path>>(path: P) -> Result<Self, Error> {
|
||||||
let backend = match git2::Repository::open_bare(path.as_ref()) {
|
let backend = match git2::Repository::open_bare(path.as_ref()) {
|
||||||
Err(e) if git_ext::is_not_found_err(&e) => {
|
Err(e) if git::ext::is_not_found_err(&e) => {
|
||||||
let backend = git2::Repository::init_opts(
|
let backend = git2::Repository::init_opts(
|
||||||
path,
|
path,
|
||||||
git2::RepositoryInitOptions::new()
|
git2::RepositoryInitOptions::new()
|
||||||
|
|
@ -196,6 +202,23 @@ impl Repository {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn identity(&self, remote: &RemoteId) -> Result<Option<identity::Doc>, refs::Error> {
|
||||||
|
let oid = if let Some(oid) = self.reference_oid(remote, &RADICLE_ID_REF)? {
|
||||||
|
oid
|
||||||
|
} else {
|
||||||
|
return Ok(None);
|
||||||
|
};
|
||||||
|
|
||||||
|
let doc = match self.blob_at(oid, Path::new(&*IDENTITY_PATH)) {
|
||||||
|
Err(git::ext::Error::NotFound(_)) => return Ok(None),
|
||||||
|
Err(e) => return Err(e.into()),
|
||||||
|
Ok(doc) => doc,
|
||||||
|
};
|
||||||
|
let doc = identity::Doc::from_toml(doc.content()).unwrap();
|
||||||
|
|
||||||
|
Ok(Some(doc))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReadRepository for Repository {
|
impl ReadRepository for Repository {
|
||||||
|
|
@ -203,8 +226,8 @@ impl ReadRepository for Repository {
|
||||||
self.backend.path()
|
self.backend.path()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn blob_at<'a>(&'a self, oid: Oid, path: &'a Path) -> Result<git2::Blob<'a>, git_ext::Error> {
|
fn blob_at<'a>(&'a self, oid: Oid, path: &'a Path) -> Result<git2::Blob<'a>, git::ext::Error> {
|
||||||
git_ext::Blob::At {
|
git::ext::Blob::At {
|
||||||
object: oid.into(),
|
object: oid.into(),
|
||||||
path,
|
path,
|
||||||
}
|
}
|
||||||
|
|
@ -218,7 +241,7 @@ impl ReadRepository for Repository {
|
||||||
) -> Result<Option<git2::Reference>, git2::Error> {
|
) -> Result<Option<git2::Reference>, git2::Error> {
|
||||||
let name = format!("refs/remotes/{remote}/{name}");
|
let name = format!("refs/remotes/{remote}/{name}");
|
||||||
self.backend.find_reference(&name).map(Some).or_else(|e| {
|
self.backend.find_reference(&name).map(Some).or_else(|e| {
|
||||||
if git_ext::is_not_found_err(&e) {
|
if git::ext::is_not_found_err(&e) {
|
||||||
Ok(None)
|
Ok(None)
|
||||||
} else {
|
} else {
|
||||||
Err(e)
|
Err(e)
|
||||||
|
|
@ -228,10 +251,10 @@ impl ReadRepository for Repository {
|
||||||
|
|
||||||
fn reference_oid(
|
fn reference_oid(
|
||||||
&self,
|
&self,
|
||||||
user: &RemoteId,
|
remote: &RemoteId,
|
||||||
reference: &git::RefStr,
|
reference: &git::RefStr,
|
||||||
) -> Result<Option<Oid>, git2::Error> {
|
) -> Result<Option<Oid>, git2::Error> {
|
||||||
let reference = self.reference(user, reference)?;
|
let reference = self.reference(remote, reference)?;
|
||||||
Ok(reference.and_then(|r| r.target().map(|o| o.into())))
|
Ok(reference.and_then(|r| r.target().map(|o| o.into())))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2,6 +2,7 @@ use std::collections::{BTreeMap, HashSet};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::ops::RangeBounds;
|
use std::ops::RangeBounds;
|
||||||
|
|
||||||
|
use nonempty::NonEmpty;
|
||||||
use quickcheck::Arbitrary;
|
use quickcheck::Arbitrary;
|
||||||
|
|
||||||
use crate::collections::HashMap;
|
use crate::collections::HashMap;
|
||||||
|
|
@ -9,7 +10,7 @@ use crate::crypto::{self, Signer};
|
||||||
use crate::crypto::{PublicKey, SecretKey};
|
use crate::crypto::{PublicKey, SecretKey};
|
||||||
use crate::git;
|
use crate::git;
|
||||||
use crate::hash;
|
use crate::hash;
|
||||||
use crate::identity::ProjId;
|
use crate::identity::{Delegate, Did, Doc, ProjId, Project};
|
||||||
use crate::storage;
|
use crate::storage;
|
||||||
use crate::storage::refs::Refs;
|
use crate::storage::refs::Refs;
|
||||||
use crate::test::storage::MockStorage;
|
use crate::test::storage::MockStorage;
|
||||||
|
|
@ -49,6 +50,53 @@ impl Arbitrary for MockStorage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Arbitrary for Project {
|
||||||
|
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
|
||||||
|
let mut buf = Vec::new();
|
||||||
|
let doc = Doc::arbitrary(g);
|
||||||
|
let id = doc.write(&mut buf).unwrap();
|
||||||
|
let remotes = storage::Remotes::arbitrary(g);
|
||||||
|
|
||||||
|
Self { id, doc, remotes }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Arbitrary for Did {
|
||||||
|
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
|
||||||
|
Self::from(PublicKey::arbitrary(g))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Arbitrary for Delegate {
|
||||||
|
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
|
||||||
|
Self {
|
||||||
|
name: String::arbitrary(g),
|
||||||
|
id: Did::arbitrary(g),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl Arbitrary for Doc {
|
||||||
|
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
|
||||||
|
let name = String::arbitrary(g);
|
||||||
|
let description = String::arbitrary(g);
|
||||||
|
let default_branch = String::arbitrary(g);
|
||||||
|
let version = u32::arbitrary(g);
|
||||||
|
let parent = None;
|
||||||
|
let delegate = Delegate::arbitrary(g);
|
||||||
|
let delegates = NonEmpty::new(delegate);
|
||||||
|
|
||||||
|
Self {
|
||||||
|
name,
|
||||||
|
description,
|
||||||
|
default_branch,
|
||||||
|
version,
|
||||||
|
parent,
|
||||||
|
delegates,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
impl Arbitrary for Refs {
|
impl Arbitrary for Refs {
|
||||||
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
|
fn arbitrary(g: &mut quickcheck::Gen) -> Self {
|
||||||
let mut refs: BTreeMap<git::RefString, storage::Oid> = BTreeMap::new();
|
let mut refs: BTreeMap<git::RefString, storage::Oid> = BTreeMap::new();
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@ use git_url::Url;
|
||||||
|
|
||||||
use crate::crypto::Verified;
|
use crate::crypto::Verified;
|
||||||
use crate::git;
|
use crate::git;
|
||||||
use crate::identity::{ProjId, UserId};
|
use crate::identity::{ProjId, Project, UserId};
|
||||||
use crate::storage::refs;
|
use crate::storage::refs;
|
||||||
use crate::storage::{
|
use crate::storage::{
|
||||||
Error, Inventory, ReadRepository, ReadStorage, Remote, Remotes, WriteRepository, WriteStorage,
|
Error, Inventory, ReadRepository, ReadStorage, Remote, Remotes, WriteRepository, WriteStorage,
|
||||||
|
|
@ -10,11 +10,11 @@ use crate::storage::{
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct MockStorage {
|
pub struct MockStorage {
|
||||||
pub inventory: Vec<(ProjId, Remotes<Verified>)>,
|
pub inventory: Vec<Project>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MockStorage {
|
impl MockStorage {
|
||||||
pub fn new(inventory: Vec<(ProjId, Remotes<Verified>)>) -> Self {
|
pub fn new(inventory: Vec<Project>) -> Self {
|
||||||
Self { inventory }
|
Self { inventory }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,9 +38,9 @@ impl ReadStorage for MockStorage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get(&self, proj: &ProjId) -> Result<Option<Remotes<Verified>>, Error> {
|
fn get(&self, proj: &ProjId) -> Result<Option<Project>, Error> {
|
||||||
if let Some((_, refs)) = self.inventory.iter().find(|(id, _)| id == proj) {
|
if let Some(proj) = self.inventory.iter().find(|p| p.id == *proj) {
|
||||||
return Ok(Some(refs.clone()));
|
return Ok(Some(proj.clone()));
|
||||||
}
|
}
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
|
@ -49,7 +49,7 @@ impl ReadStorage for MockStorage {
|
||||||
let inventory = self
|
let inventory = self
|
||||||
.inventory
|
.inventory
|
||||||
.iter()
|
.iter()
|
||||||
.map(|(id, _)| id.clone())
|
.map(|proj| proj.id.clone())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
Ok(inventory)
|
Ok(inventory)
|
||||||
|
|
|
||||||
|
|
@ -347,9 +347,9 @@ fn prop_inventory_exchange_dense() {
|
||||||
(bob_inv.inventory, bob.id()),
|
(bob_inv.inventory, bob.id()),
|
||||||
(eve_inv.inventory, eve.id()),
|
(eve_inv.inventory, eve.id()),
|
||||||
] {
|
] {
|
||||||
for (proj, _) in inv {
|
for proj in inv {
|
||||||
routing
|
routing
|
||||||
.entry(proj.clone())
|
.entry(proj.id.clone())
|
||||||
.or_insert_with(|| HashSet::with_hasher(rng.clone().into()))
|
.or_insert_with(|| HashSet::with_hasher(rng.clone().into()))
|
||||||
.insert(*peer);
|
.insert(*peer);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue