parent
72df0f0b21
commit
2663838af0
@ -1 +1,2 @@ |
||||
/target |
||||
.cargo |
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1 @@ |
||||
pub mod origin; |
@ -1,13 +0,0 @@ |
||||
mod origin; |
||||
|
||||
use crate::origin::Descr; |
||||
|
||||
fn main() { |
||||
|
||||
let d = Descr::Git{ |
||||
url: "foo", |
||||
branch: "bar", |
||||
}; |
||||
|
||||
println!("{}", d.id()); |
||||
} |
@ -0,0 +1,138 @@ |
||||
use std::error::Error; |
||||
|
||||
use super::Descr; |
||||
use super::View; |
||||
|
||||
#[derive(Clone,Copy)] |
||||
pub struct Limits {} |
||||
|
||||
pub enum GetViewError { |
||||
TODO, |
||||
Unexpected(Box<dyn Error>), |
||||
} |
||||
|
||||
#[derive(Debug)] |
||||
pub enum SyncError { |
||||
InvalidURL, |
||||
InvalidBranchName, |
||||
Unexpected(Box<dyn Error>), |
||||
} |
||||
|
||||
pub trait Store { |
||||
fn get_view(&self, descr: Descr) -> Result<&dyn View, GetViewError>; |
||||
fn sync(&self, descr: Descr, limits: Limits) -> Result<(), SyncError>; |
||||
} |
||||
|
||||
pub mod git { |
||||
|
||||
use std::path::Path; |
||||
use super::{Store as originStore, *}; |
||||
|
||||
use gix::clone::Error as gixCloneErr; |
||||
use gix::progress::Discard; |
||||
|
||||
// Catching error from gix::prepare_clone_bare
|
||||
impl From<gixCloneErr> for SyncError { |
||||
fn from(e: gixCloneErr) -> SyncError { |
||||
match e { |
||||
gixCloneErr::Init(gix::init::Error::InvalidBranchName{..}) => |
||||
SyncError::InvalidBranchName, |
||||
gixCloneErr::UrlParse(_) | |
||||
gixCloneErr::CanonicalizeUrl{..} => |
||||
SyncError::InvalidURL, |
||||
_ => |
||||
SyncError::Unexpected(Box::from(e)), |
||||
} |
||||
} |
||||
} |
||||
|
||||
pub struct Store<'a> { |
||||
dir_path: &'a Path, |
||||
} |
||||
|
||||
impl<'a> Store<'a> { |
||||
|
||||
pub fn new(dir_path: &Path) -> std::io::Result<Store> { |
||||
std::fs::create_dir_all(dir_path)?; |
||||
println!("{}", &dir_path.display()); |
||||
Ok(Store{dir_path}) |
||||
} |
||||
} |
||||
|
||||
impl<'a> originStore for Store<'a> { |
||||
|
||||
fn sync(&self, descr: Descr, _limits: Limits) -> Result<(), SyncError> { |
||||
|
||||
let should_interrupt = &core::sync::atomic::AtomicBool::new(false); |
||||
|
||||
let Descr::Git{url, ..} = descr; |
||||
|
||||
let path = &self.dir_path.clone().join(descr.id()); |
||||
|
||||
// if the path doesn't exist then use the gix clone feature to clone it into the
|
||||
// directory.
|
||||
if std::fs::read_dir(path).is_err() { |
||||
|
||||
std::fs::create_dir_all(path) |
||||
.map_err(|e| SyncError::Unexpected(Box::from(e)))?; |
||||
|
||||
gix::prepare_clone_bare(url, path)? |
||||
.fetch_only(Discard, should_interrupt) |
||||
.map_err(|_| SyncError::InvalidURL)?; |
||||
|
||||
return Ok(()); |
||||
} |
||||
|
||||
let direction = gix::remote::Direction::Fetch; |
||||
|
||||
let repo = gix::open(path) |
||||
.map_err(|e| SyncError::Unexpected(Box::from(e)))?; |
||||
|
||||
let remote = repo.find_default_remote(direction) |
||||
.ok_or(SyncError::Unexpected(Box::from("no default configured")))? |
||||
.map_err(|e| SyncError::Unexpected(Box::from(e)))?; |
||||
|
||||
remote |
||||
.connect(direction) |
||||
.map_err(|e| SyncError::Unexpected(Box::from(e)))? |
||||
.prepare_fetch(Discard, Default::default()) |
||||
.map_err(|e| SyncError::Unexpected(Box::from(e)))? |
||||
.receive(Discard, should_interrupt) |
||||
.map_err(|e| SyncError::Unexpected(Box::from(e)))?; |
||||
|
||||
Ok(()) |
||||
} |
||||
|
||||
fn get_view(&self, _descr: Descr) -> Result<&dyn View, GetViewError> { |
||||
Err(GetViewError::TODO) |
||||
} |
||||
|
||||
} |
||||
|
||||
#[cfg(test)] |
||||
mod tests { |
||||
|
||||
use super::Descr; |
||||
use super::super::Store; |
||||
|
||||
use tempdir::TempDir; |
||||
|
||||
#[test] |
||||
fn sync() { |
||||
|
||||
let tmp_dir = TempDir::new("origin_store_git").unwrap(); |
||||
|
||||
let descr = Descr::Git{ |
||||
url: "https://github.com/mediocregopher/priority-finder.git", |
||||
branch_name: "master", |
||||
}; |
||||
|
||||
let limits = super::Limits{}; |
||||
|
||||
let store = super::Store::new(tmp_dir.path()).expect("store created"); |
||||
|
||||
store.sync(descr, limits).expect("sync should succeed"); |
||||
store.sync(descr, limits).expect("second sync should succeed"); |
||||
} |
||||
} |
||||
} |
Loading…
Reference in new issue