From 45d6de80e8f90f18d5db347df79a5aa4472f9159 Mon Sep 17 00:00:00 2001 From: Alexis Sellier Date: Mon, 29 Aug 2022 11:57:09 +0200 Subject: [PATCH] node: Use `Url` type Signed-off-by: Alexis Sellier --- node/src/git.rs | 6 ++++-- node/src/protocol.rs | 9 ++++++++- node/src/storage.rs | 3 ++- node/src/storage/git.rs | 39 ++++++++++++++++++++++----------------- node/src/test/storage.rs | 4 +++- 5 files changed, 39 insertions(+), 22 deletions(-) diff --git a/node/src/git.rs b/node/src/git.rs index 1097f4b4..b10a79c2 100644 --- a/node/src/git.rs +++ b/node/src/git.rs @@ -4,6 +4,7 @@ use crate::collections::HashMap; use crate::identity::UserId; use crate::storage::{Remote, Remotes, Unverified}; use git_ref_format as format; +use git_url::Url; /// Default port of the `git` transport protocol. pub const PROTOCOL_PORT: u16 = 9418; @@ -25,9 +26,10 @@ pub enum ListRefsError { } /// List remote refs of a project, given the remote URL. -pub fn list_remotes(url: &str) -> Result, ListRefsError> { +pub fn list_remotes(url: &Url) -> Result, ListRefsError> { + let url = url.to_string(); let mut remotes = HashMap::default(); - let mut remote = git2::Remote::create_detached(url)?; + let mut remote = git2::Remote::create_detached(&url)?; remote.connect(git2::Direction::Fetch)?; diff --git a/node/src/protocol.rs b/node/src/protocol.rs index 75cd6d89..66ec1765 100644 --- a/node/src/protocol.rs +++ b/node/src/protocol.rs @@ -454,7 +454,14 @@ where self.storage .repository(&proj) .unwrap() - .fetch(&format!("git://{}", remote)) + .fetch(&Url { + scheme: git_url::Scheme::Git, + host: Some(remote.ip().to_string()), + port: Some(remote.port()), + // TODO: Fix upstream crate so that it adds a `/` when needed. + path: format!("/{}", proj).into(), + ..Url::default() + }) .unwrap(); } } diff --git a/node/src/storage.rs b/node/src/storage.rs index 9af8ce48..0eb406dd 100644 --- a/node/src/storage.rs +++ b/node/src/storage.rs @@ -6,6 +6,7 @@ use std::marker::PhantomData; use std::ops::{Deref, DerefMut}; use std::path::Path; +use git_url::Url; use once_cell::sync::Lazy; use serde::{Deserialize, Serialize}; use thiserror::Error; @@ -130,7 +131,7 @@ pub trait ReadRepository { } pub trait WriteRepository { - fn fetch(&mut self, url: &str) -> Result<(), git2::Error>; + fn fetch(&mut self, url: &Url) -> Result<(), git2::Error>; fn namespace(&mut self, user: &UserId) -> Result<&mut git2::Repository, git2::Error>; } diff --git a/node/src/storage/git.rs b/node/src/storage/git.rs index 6779b7be..ca8ccb67 100644 --- a/node/src/storage/git.rs +++ b/node/src/storage/git.rs @@ -2,6 +2,7 @@ use std::path::{Path, PathBuf}; use std::{fmt, fs}; use git_ref_format::refspec; +use git_url::Url; use once_cell::sync::Lazy; use radicle_git_ext as git_ext; @@ -174,22 +175,21 @@ impl ReadRepository for Repository { impl WriteRepository for Repository { /// Fetch all remotes of a project from the given URL. - fn fetch(&mut self, url: &str) -> Result<(), git2::Error> { - // TODO: Use `Url` type? + fn fetch(&mut self, url: &Url) -> Result<(), git2::Error> { // TODO: Have function to fetch specific remotes. // TODO: Return meaningful info on success. // // Repository layout should look like this: // - // /refs/namespaces/ - // /refs/namespaces/ - // /heads - // /master - // /tags - // ... + // /refs/namespaces/ + // /heads + // /master + // /tags + // ... // + let url = url.to_string(); let refs: &[&str] = &["refs/namespaces/*:refs/namespaces/*"]; - let mut remote = self.backend.remote_anonymous(url)?; + let mut remote = self.backend.remote_anonymous(&url)?; let mut opts = git2::FetchOptions::default(); remote.fetch(refs, Some(&mut opts), None)?; @@ -219,6 +219,7 @@ mod tests { use crate::git; use crate::storage::{ReadStorage, WriteRepository}; use crate::test::fixtures; + use git_url::Url; #[test] fn test_list_remotes() { @@ -226,10 +227,12 @@ mod tests { let storage = fixtures::storage(dir.path()); let inv = storage.inventory().unwrap(); let (proj, _) = inv.first().unwrap(); - let refs = git::list_remotes(&format!( - "file://{}", - dir.path().join(&proj.to_string()).display(), - )) + let refs = git::list_remotes(&Url { + host: Some(dir.path().to_string_lossy().to_string()), + scheme: git_url::Scheme::File, + path: format!("/{}", proj).into(), + ..Url::default() + }) .unwrap(); let remotes = storage.repository(proj).unwrap().remotes().unwrap(); @@ -249,10 +252,12 @@ mod tests { // Have Bob fetch Alice's refs. bob.repository(proj) .unwrap() - .fetch(&format!( - "file://{}", - alice.path().join(&proj.to_string()).display() - )) + .fetch(&Url { + host: Some(alice.path().to_string_lossy().to_string()), + scheme: git_url::Scheme::File, + path: format!("/{}", proj).into(), + ..Url::default() + }) .unwrap(); for remote in remotes.values() { diff --git a/node/src/test/storage.rs b/node/src/test/storage.rs index ccb5b9bc..ac2a602b 100644 --- a/node/src/test/storage.rs +++ b/node/src/test/storage.rs @@ -1,3 +1,5 @@ +use git_url::Url; + use crate::identity::ProjId; use crate::storage::{ Error, Inventory, ReadStorage, Remotes, Unverified, WriteRepository, WriteStorage, @@ -50,7 +52,7 @@ impl WriteStorage for MockStorage { pub struct MockRepository {} impl WriteRepository for MockRepository { - fn fetch(&mut self, _url: &str) -> Result<(), git2::Error> { + fn fetch(&mut self, _url: &Url) -> Result<(), git2::Error> { todo!() }