Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
radicle: temporary repository helper
Fintan Halpenny committed 2 years ago
commit e71f07e592823faf289a3c13c4b6143d13146de3
parent 25ed6b8b28d2280429b0de7d8dba1d0214891b63
4 files changed +32 -26
modified radicle-node/src/runtime.rs
@@ -136,13 +136,7 @@ impl Runtime {
        let network = config.network;
        let rng = fastrand::Rng::new();
        let clock = LocalTime::now();
-
        let storage = Storage::open(
-
            home.storage(),
-
            git::UserInfo {
-
                alias: alias.clone(),
-
                key: id,
-
            },
-
        )?;
+
        let storage = Storage::open(home.storage(), git::UserInfo { alias, key: id })?;
        let address_db = node_dir.join(ADDRESS_DB_FILE);
        let routing_db = node_dir.join(ROUTING_DB_FILE);
        let tracking_db = node_dir.join(TRACKING_DB_FILE);
@@ -254,7 +248,6 @@ impl Runtime {
            scope,
            tracking_db,
            limit: FetchLimit::default(),
-
            info: git::UserInfo { alias, key: nid },
            local: nid,
            expiry: worker::garbage::Expiry::default(),
        };
modified radicle-node/src/worker.rs
@@ -14,7 +14,7 @@ use radicle::identity::Id;
use radicle::prelude::NodeId;
use radicle::storage::refs::RefsAt;
use radicle::storage::{ReadRepository, ReadStorage};
-
use radicle::{crypto, git, Storage};
+
use radicle::{crypto, Storage};
use radicle_fetch::FetchLimit;

use crate::runtime::{thread, Handle};
@@ -159,8 +159,6 @@ pub struct FetchConfig {
    pub tracking_db: PathBuf,
    /// Data limits when fetching from a remote.
    pub limit: FetchLimit,
-
    /// Information of the local peer.
-
    pub info: git::UserInfo,
    /// Public key of the local peer.
    pub local: crypto::PublicKey,
    /// Configuration for `git gc` garbage collection. Defaults to `1
@@ -281,7 +279,6 @@ impl Worker {
            scope,
            tracking_db,
            limit,
-
            info,
            local,
            expiry,
        } = &self.fetch_config;
@@ -292,15 +289,7 @@ impl Worker {
        let tracked = radicle_fetch::Tracked::from_config(rid, &tracking)?;
        let blocked = radicle_fetch::BlockList::from_config(&tracking)?;

-
        let handle = fetch::Handle::new(
-
            rid,
-
            *local,
-
            info.clone(),
-
            &self.storage,
-
            tracked,
-
            blocked,
-
            channels,
-
        )?;
+
        let handle = fetch::Handle::new(rid, *local, &self.storage, tracked, blocked, channels)?;
        let result = handle.fetch(rid, &self.storage, *limit, remote, refs_at)?;

        if let Err(e) = garbage::collect(&self.storage, rid, *expiry) {
modified radicle-node/src/worker/fetch.rs
@@ -3,9 +3,7 @@ pub mod error;
use std::collections::HashSet;

use radicle::crypto::PublicKey;
-
use radicle::git::UserInfo;
use radicle::prelude::Id;
-
use radicle::storage::git::Repository;
use radicle::storage::refs::RefsAt;
use radicle::storage::{ReadStorage as _, RefUpdate, WriteRepository as _};
use radicle::Storage;
@@ -35,7 +33,6 @@ impl Handle {
    pub fn new(
        rid: Id,
        local: PublicKey,
-
        info: UserInfo,
        storage: &Storage,
        tracked: Tracked,
        blocked: BlockList,
@@ -47,8 +44,7 @@ impl Handle {
            let handle = radicle_fetch::Handle::new(local, repo, tracked, blocked, channels)?;
            Ok(Handle::Pull { handle })
        } else {
-
            let tmp = tempfile::tempdir()?;
-
            let repo = Repository::create(tmp.path(), rid, &info)?;
+
            let (repo, tmp) = storage.lock_repository(rid)?;
            let handle = radicle_fetch::Handle::new(local, repo, tracked, blocked, channels)?;
            Ok(Handle::Clone { handle, tmp })
        }
modified radicle/src/storage/git.rs
@@ -9,6 +9,7 @@ use std::{fs, io};

use crypto::{Signer, Verified};
use once_cell::sync::Lazy;
+
use tempfile::TempDir;

use crate::crypto::Unverified;
use crate::git;
@@ -152,6 +153,27 @@ impl Storage {
        Ok(Self { path, info })
    }

+
    /// Create a [`Repository`] in a temporary directory.
+
    ///
+
    /// N.b. it is important to keep the [`TempDir`] in scope while
+
    /// using the [`Repository`]. If it is dropped, any action on the
+
    /// `Repository` will fail.
+
    pub fn lock_repository(&self, rid: Id) -> Result<(Repository, TempDir), RepositoryError> {
+
        if self.contains(&rid)? {
+
            return Err(Error::Io(io::Error::new(
+
                io::ErrorKind::AlreadyExists,
+
                format!("refusing to create '{}.lock'", rid),
+
            ))
+
            .into());
+
        }
+
        let tmp = tempfile::Builder::new()
+
            .prefix(&rid.canonical())
+
            .suffix(".lock")
+
            .tempdir_in(self.path())
+
            .map_err(Error::from)?;
+
        Ok((Repository::create(tmp.path(), rid, &self.info)?, tmp))
+
    }
+

    pub fn path(&self) -> &Path {
        self.path.as_path()
    }
@@ -170,6 +192,12 @@ impl Storage {
            if path.file_name().to_string_lossy().starts_with('.') {
                continue;
            }
+
            // Skip lock files.
+
            if let Some(ext) = path.path().extension() {
+
                if ext == "lock" {
+
                    continue;
+
                }
+
            }
            let rid =
                Id::try_from(path.file_name()).map_err(|_| Error::InvalidId(path.file_name()))?;