diff --git a/node/src/git.rs b/node/src/git.rs new file mode 100644 index 00000000..50394202 --- /dev/null +++ b/node/src/git.rs @@ -0,0 +1,24 @@ +use std::net; + +use crate::identity::ProjId; +use crate::storage::{Error, WriteStorage}; + +/// Default port of the `git` transport protocol. +pub const PROTOCOL_PORT: u16 = 9418; + +pub fn fetch( + _proj: &ProjId, + remote: &net::SocketAddr, + mut storage: S, +) -> Result<(), Error> { + let _repo = storage.repository(); + + let url = format!("git://{}", remote); + let refs: &[&str] = &[]; + let mut remote = git2::Remote::create_detached(&url)?; + let mut opts = git2::FetchOptions::default(); + + remote.fetch(refs, Some(&mut opts), None)?; + + Ok(()) +} diff --git a/node/src/lib.rs b/node/src/lib.rs index caf2afcc..d8693459 100644 --- a/node/src/lib.rs +++ b/node/src/lib.rs @@ -6,6 +6,7 @@ mod address_manager; mod clock; mod collections; mod decoder; +mod git; mod hash; mod identity; mod logger; diff --git a/node/src/protocol.rs b/node/src/protocol.rs index 9502e329..da37fd2c 100644 --- a/node/src/protocol.rs +++ b/node/src/protocol.rs @@ -15,6 +15,7 @@ use crate::address_manager::AddressManager; use crate::clock::RefClock; use crate::collections::{HashMap, HashSet}; use crate::decoder::Decoder; +use crate::git; use crate::identity::{ProjId, UserId}; use crate::storage; use crate::storage::{Inventory, ReadStorage, Remotes, Unverified, WriteStorage}; @@ -38,6 +39,7 @@ pub const MAX_CONNECTION_ATTEMPTS: usize = 3; #[derive(Debug)] pub enum Command { Connect(net::SocketAddr), + Fetch(ProjId, net::SocketAddr), } /// Message envelope. All messages sent over the network are wrapped in this type. @@ -351,7 +353,7 @@ impl Protocol { impl nakamoto::Protocol for Protocol where - T: ReadStorage + WriteStorage, + T: ReadStorage + WriteStorage + 'static, S: address_book::Store, { type Event = (); @@ -416,6 +418,9 @@ where match cmd { Command::Connect(addr) => self.context.connect(addr), + Command::Fetch(proj, remote) => { + git::fetch(&proj, &remote, &mut self.storage).unwrap(); + } } } diff --git a/node/src/storage.rs b/node/src/storage.rs index 4075b5ff..bdffc12d 100644 --- a/node/src/storage.rs +++ b/node/src/storage.rs @@ -1,7 +1,7 @@ use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use std::path::Path; -use std::{fmt, fs, io, net}; +use std::{fmt, fs, io}; use git_ref_format::refspec; use once_cell::sync::Lazy; @@ -100,8 +100,7 @@ pub trait ReadStorage { } pub trait WriteStorage { - /// Fetch a project from a remote peer. - fn fetch(&mut self, proj: &ProjId, remote: &net::SocketAddr) -> Result<(), Error>; + fn repository(&mut self) -> &mut git2::Repository; } impl ReadStorage for T @@ -121,10 +120,10 @@ where impl WriteStorage for T where T: DerefMut, - S: WriteStorage, + S: WriteStorage + 'static, { - fn fetch(&mut self, proj: &ProjId, remote: &net::SocketAddr) -> Result<(), Error> { - self.deref_mut().fetch(proj, remote) + fn repository(&mut self) -> &mut git2::Repository { + self.deref_mut().repository() } } @@ -159,8 +158,8 @@ impl ReadStorage for Storage { } impl WriteStorage for Storage { - fn fetch(&mut self, _id: &ProjId, _remote: &net::SocketAddr) -> Result<(), Error> { - todo!() + fn repository(&mut self) -> &mut git2::Repository { + &mut self.backend } } diff --git a/node/src/test/peer.rs b/node/src/test/peer.rs index 92b15db4..fab51bfa 100644 --- a/node/src/test/peer.rs +++ b/node/src/test/peer.rs @@ -57,7 +57,7 @@ impl DerefMut for Peer { impl Peer where - S: ReadStorage + WriteStorage, + S: ReadStorage + WriteStorage + 'static, { pub fn new(name: &'static str, ip: impl Into, storage: S) -> Self { Self::config( diff --git a/node/src/test/storage.rs b/node/src/test/storage.rs index 7873b0a2..f6040501 100644 --- a/node/src/test/storage.rs +++ b/node/src/test/storage.rs @@ -1,5 +1,3 @@ -use std::net; - use crate::identity::ProjId; use crate::storage::{Error, Inventory, ReadStorage, Remotes, Unverified, WriteStorage}; @@ -40,7 +38,7 @@ impl ReadStorage for MockStorage { } impl WriteStorage for MockStorage { - fn fetch(&mut self, _proj: &ProjId, _remote: &net::SocketAddr) -> Result<(), Error> { + fn repository(&mut self) -> &mut git2::Repository { todo!() } }