Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
node: Use `Url` type
Alexis Sellier committed 3 years ago
commit 45d6de80e8f90f18d5db347df79a5aa4472f9159
parent f18afb793c52fb5501546fe33a8d335aad8ba7b5
5 files changed +39 -22
modified 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<Remotes<Unverified>, ListRefsError> {
+
pub fn list_remotes(url: &Url) -> Result<Remotes<Unverified>, 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)?;

modified 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();
            }
        }
modified 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>;
}

modified 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/<project>
-
        //              /refs/namespaces/<remote>
-
        //                    /heads
-
        //                      /master
-
        //                    /tags
-
        //                    ...
+
        //   /refs/namespaces/<remote>
+
        //         /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() {
modified 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!()
    }