Unified · Split
| @@ -40,8 +40,8 @@ pub enum Error { · 39 unmodified lines | |||
| 40 | 40 | ||
| 41 | /// Given an objects directory, try to resolve alternate object directories possibly located in the | 41 | /// Given an objects directory, try to resolve alternate object directories possibly located in the |
| 42 | /// `./info/alternates` file. | 42 | /// `./info/alternates` file. |
| 43 | /// If no alternate object database was resolved, the resulting `Vec` is empty, and it is not an error | 43 | /// If no alternate object database was resolved, the resulting `Vec` is empty (it is not an error |
| 44 | /// if there are no alternates. | 44 | /// if there are no alternates). |
| 45 | /// It is an error once a repository is seen again as it would lead to a cycle. | 45 | /// It is an error once a repository is seen again as it would lead to a cycle. |
| 46 | pub fn resolve(objects_directory: impl Into<PathBuf>) -> Result<Vec<PathBuf>, Error> { | 46 | pub fn resolve(objects_directory: impl Into<PathBuf>) -> Result<Vec<PathBuf>, Error> { |
| 47 | let relative_base = objects_directory.into(); | 47 | let relative_base = objects_directory.into(); |
| @@ -3,14 +3,39 @@ use crate::compound; · 2 unmodified lines | |||
| 3 | 3 | ||
| 4 | #[allow(missing_docs)] | 4 | #[allow(missing_docs)] |
| 5 | pub struct Db { | 5 | pub struct Db { |
| 6 | dbs: Vec<compound::Db>, | 6 | pub dbs: Vec<compound::Db>, |
| 7 | } | 7 | } |
| 8 | 8 | ||
| 9 | use std::path::PathBuf; | 9 | pub mod init { |
| 10 | use crate::{alternate, compound, linked}; | ||
| 11 | use std::path::PathBuf; | ||
| 10 | 12 | ||
| 11 | impl Db { | 13 | /// The error returned by [`linked::Db::at()`] |
| 14 | #[derive(Debug, thiserror::Error)] | ||
| 12 | #[allow(missing_docs)] | 15 | #[allow(missing_docs)] |
| 13 | pub fn at(objects_directory: impl Into<PathBuf>) -> Result<Self, compound::init::Error> { | 16 | pub enum Error { |
| 14 | unimplemented!("todo") | 17 | #[error(transparent)] |
| 18 | CompoundDbInit(#[from] compound::init::Error), | ||
| 19 | #[error(transparent)] | ||
| 20 | AlternateResolve(#[from] alternate::Error), | ||
| 21 | } | ||
| 22 | |||
| 23 | impl linked::Db { | ||
| 24 | #[allow(missing_docs)] | ||
| 25 | pub fn at(objects_directory: impl Into<PathBuf>) -> Result<Self, Error> { | ||
| 26 | let mut dbs = vec![compound::Db::at(objects_directory.into())?]; | ||
| 27 | for object_path in alternate::resolve(dbs[0].loose.path.clone())?.into_iter() { | ||
| 28 | dbs.push(compound::Db::at(object_path)?); | ||
| 29 | } | ||
| 30 | Ok(linked::Db { dbs }) | ||
| 31 | } | ||
| 32 | } | ||
| 33 | |||
| 34 | impl std::convert::TryFrom<PathBuf> for linked::Db { | ||
| 35 | type Error = Error; | ||
| 36 | |||
| 37 | fn try_from(value: PathBuf) -> Result<Self, Self::Error> { | ||
| 38 | linked::Db::at(value) | ||
| 39 | } | ||
| 15 | } | 40 | } |
| 16 | } | 41 | } |
| @@ -4,7 +4,10 @@ use std::{ · 3 unmodified lines | |||
| 4 | path::{Path, PathBuf}, | 4 | path::{Path, PathBuf}, |
| 5 | }; | 5 | }; |
| 6 | 6 | ||
| 7 | fn alternate(objects_at: impl Into<PathBuf>, objects_to: impl Into<PathBuf>) -> Result<(PathBuf, PathBuf), io::Error> { | 7 | pub fn alternate( |
| 8 | objects_at: impl Into<PathBuf>, | ||
| 9 | objects_to: impl Into<PathBuf>, | ||
| 10 | ) -> Result<(PathBuf, PathBuf), io::Error> { | ||
| 8 | alternate_with(objects_at, objects_to, None) | 11 | alternate_with(objects_at, objects_to, None) |
| 9 | } | 12 | } |
| 10 | 13 | ||
| @@ -1,10 +1,25 @@ | |||
| 1 | mod init { | 1 | mod init { |
| 2 | use crate::alternate::alternate; | ||
| 2 | use git_odb::linked; | 3 | use git_odb::linked; |
| 4 | use std::convert::TryFrom; | ||
| 5 | |||
| 6 | #[test] | ||
| 7 | fn multiple_linked_repositories_via_alternates() -> crate::Result { | ||
| 8 | let tmp = tempdir::TempDir::new("alternates")?; | ||
| 9 | let (object_path, linked_object_path) = alternate(tmp.path().join("a"), tmp.path().join("b"))?; | ||
| 10 | let db = linked::Db::try_from(object_path.clone())?; | ||
| 11 | assert_eq!(db.dbs.len(), 2); | ||
| 12 | assert_eq!(db.dbs[0].loose.path, object_path); | ||
| 13 | assert_eq!(db.dbs[1].loose.path, linked_object_path); | ||
| 14 | Ok(()) | ||
| 15 | } | ||
| 3 | 16 | ||
| 4 | #[test] | 17 | #[test] |
| 5 | fn a_linked_db_without_alternates() -> crate::Result { | 18 | fn a_linked_db_without_alternates() -> crate::Result { |
| 6 | let tmp = tempdir::TempDir::new("alternates")?; | 19 | let tmp = tempdir::TempDir::new("alternates")?; |
| 7 | let _ = linked::Db::at(tmp.path())?; | 20 | let db = linked::Db::at(tmp.path())?; |
| 21 | assert_eq!(db.dbs.len(), 1); | ||
| 22 | assert_eq!(db.dbs[0].loose.path, tmp.path()); | ||
| 8 | Ok(()) | 23 | Ok(()) |
| 9 | } | 24 | } |
| 10 | } | 25 | } |