Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
radicle: add clean method
Fintan Halpenny committed 2 years ago
commit d23120ca8bf082e7dc7171a3b53829593cbf7701
parent 53013f306fd98469f9f1eb3e830361fbf3b9a7d8
3 files changed +67 -1
modified radicle/src/storage.rs
@@ -348,6 +348,9 @@ pub trait WriteStorage: ReadStorage {
    fn create(&self, rid: Id) -> Result<Self::RepositoryMut, Error>;
    /// Delete a repository.
    fn remove(&self, rid: Id) -> Result<(), Error>;
+
    /// Delete all remote namespaces apart from the local node's and
+
    /// delegates' namespace.
+
    fn clean(&self, rid: Id) -> Result<Vec<RemoteId>, RepositoryError>;
}

/// Allows read-only access to a repository.
@@ -592,6 +595,10 @@ where
    fn remove(&self, rid: Id) -> Result<(), Error> {
        self.deref().remove(rid)
    }
+

+
    fn clean(&self, rid: Id) -> Result<Vec<RemoteId>, RepositoryError> {
+
        self.deref().clean(rid)
+
    }
}

#[cfg(test)]
modified radicle/src/storage/git.rs
@@ -2,7 +2,7 @@
pub mod cob;
pub mod transport;

-
use std::collections::{BTreeMap, HashMap};
+
use std::collections::{BTreeMap, BTreeSet, HashMap};
use std::ops::{Deref, DerefMut};
use std::path::{Path, PathBuf};
use std::{fs, io};
@@ -142,6 +142,11 @@ impl WriteStorage for Storage {
    fn remove(&self, rid: Id) -> Result<(), Error> {
        self.repository(rid)?.remove()
    }
+

+
    fn clean(&self, rid: Id) -> Result<Vec<RemoteId>, RepositoryError> {
+
        let repo = self.repository(rid)?;
+
        repo.clean(&self.info.key)
+
    }
}

impl Storage {
@@ -357,6 +362,56 @@ impl Repository {
        Ok(())
    }

+
    /// Remove all the remotes of a repository that are not the
+
    /// `local` remote or a delegate of the repository.
+
    ///
+
    /// N.b. failure to delete remotes or references will not result
+
    /// in an early exit. Instead, this method continues to delete the
+
    /// next available remote or reference.
+
    pub fn clean(&self, local: &RemoteId) -> Result<Vec<RemoteId>, RepositoryError> {
+
        let delegates = self
+
            .delegates()?
+
            .into_iter()
+
            .map(RemoteId::from)
+
            .collect::<BTreeSet<_>>();
+
        let mut deleted = Vec::new();
+
        for id in self.remote_ids()? {
+
            let id = match id {
+
                Ok(id) => id,
+
                Err(e) => {
+
                    log::error!(target: "storage", "Failed to clean up remote: {e}");
+
                    continue;
+
                }
+
            };
+
            // N.b. it is fatal to delete local or delegates
+
            if *local == id || delegates.contains(&id) {
+
                continue;
+
            }
+
            let glob = git::refname!("refs/namespaces")
+
                .join(git::Component::from(&id))
+
                .with_pattern(git::refspec::STAR);
+
            let refs = match self.references_glob(&glob) {
+
                Ok(refs) => refs,
+
                Err(e) => {
+
                    log::error!(target: "storage", "Failed to clean up remote '{id}': {e}");
+
                    continue;
+
                }
+
            };
+
            for (refname, _) in refs {
+
                if let Ok(mut r) = self.backend.find_reference(refname.as_str()) {
+
                    if let Err(e) = r.delete() {
+
                        log::error!(target: "storage", "Failed to clean up reference '{refname}': {e}");
+
                    }
+
                } else {
+
                    log::error!(target: "storage", "Failed to clean up reference '{refname}'");
+
                }
+
            }
+
            deleted.push(id);
+
        }
+

+
        Ok(deleted)
+
    }
+

    /// Create the repository's identity branch.
    pub fn init<G: Signer, S: WriteStorage>(
        doc: &Doc<Verified>,
modified radicle/src/test/storage.rs
@@ -99,6 +99,10 @@ impl WriteStorage for MockStorage {
    fn remove(&self, _rid: Id) -> Result<(), Error> {
        todo!()
    }
+

+
    fn clean(&self, _rid: Id) -> Result<Vec<RemoteId>, RepositoryError> {
+
        todo!()
+
    }
}

#[derive(Clone, Debug)]