Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
cli: Don't fail clone if we have repo locally
Alexis Sellier committed 3 years ago
commit 207030d2e15547a95e6142a2f4746312b153e61d
parent c70dc71b18ec5ec211e87bfce6b66e07413349a3
4 files changed +59 -23
modified radicle-cli/src/commands/clone.rs
@@ -175,28 +175,33 @@ pub fn clone<G: Signer>(

    // Get seeds. This consults the local routing table only.
    let mut seeds = node.seeds(id)?;
-
    if !seeds.has_connections() {
-
        return Err(CloneError::NotFound(id));
-
    }
-
    // Fetch from all seeds.
-
    for seed in seeds.connected() {
-
        let spinner = term::spinner(format!(
-
            "Fetching {} from {}..",
-
            term::format::tertiary(id),
-
            term::format::tertiary(term::format::node(seed))
-
        ));
-

-
        // TODO: If none of them succeeds, output an error. Otherwise tell the caller
-
        // how many succeeded.
-
        match node.fetch(id, *seed)? {
-
            FetchResult::Success { .. } => {
-
                spinner.finish();
-
            }
-
            FetchResult::Failed { reason } => {
-
                spinner.error(reason);
+
    if seeds.has_connections() {
+
        // Fetch from all seeds.
+
        for seed in seeds.connected() {
+
            let spinner = term::spinner(format!(
+
                "Fetching {} from {}..",
+
                term::format::tertiary(id),
+
                term::format::tertiary(term::format::node(seed))
+
            ));
+

+
            // TODO: If none of them succeeds, output an error. Otherwise tell the caller
+
            // how many succeeded.
+
            match node.fetch(id, *seed)? {
+
                FetchResult::Success { .. } => {
+
                    spinner.finish();
+
                }
+
                FetchResult::Failed { reason } => {
+
                    spinner.error(reason);
+
                }
            }
        }
    }
+
    // TODO: Warn if no seeds were found, and we might be checking out stale data.
+
    // If we don't have the project locally, even after attempting to fetch,
+
    // there's nothing we can do.
+
    if !storage.contains(&id)? {
+
        return Err(CloneError::NotFound(id));
+
    }

    // Create a local fork of the project, under our own id.
    {
modified radicle-cli/tests/commands.rs
@@ -4,6 +4,7 @@ use std::str::FromStr;
use std::{thread, time};

use radicle::git;
+
use radicle::node::Handle as _;
use radicle::prelude::Id;
use radicle::profile::Home;
use radicle::storage::{ReadRepository, ReadStorage};
@@ -294,6 +295,29 @@ fn rad_init_sync_and_clone() {
}

#[test]
+
// User tries to clone; no seeds are available, but user has the repo locally.
+
fn test_clone_without_seeds() {
+
    logger::init(log::Level::Debug);
+

+
    let mut environment = Environment::new();
+
    let mut alice = environment.node("alice");
+
    let working = environment.tmp().join("working");
+
    let rid = alice.project("heartwood", "Radicle Heartwood Protocol & Stack");
+
    let mut alice = alice.spawn(Config::default());
+
    let seeds = alice.handle.seeds(rid).unwrap();
+

+
    assert!(!seeds.has_connections());
+

+
    alice
+
        .rad("clone", &[rid.to_string().as_str()], working.as_path())
+
        .unwrap();
+

+
    alice
+
        .rad("inspect", &[], working.join("heartwood").as_path())
+
        .unwrap();
+
}
+

+
#[test]
//
//     alice -- seed -- bob
//
modified radicle-node/src/test/environment.rs
@@ -1,3 +1,4 @@
+
use std::io::BufRead as _;
use std::mem::ManuallyDrop;
use std::path::{Path, PathBuf};
use std::{
@@ -209,15 +210,21 @@ impl<G: Signer + cyphernet::Ecdh> NodeHandle<G> {
            .args(args)
            .output()?;

+
        for line in io::BufReader::new(io::Cursor::new(&result.stdout))
+
            .lines()
+
            .flatten()
+
        {
+
            log::debug!(target: "test", "rad {cmd}: {line}");
+
        }
+

        log::debug!(
            target: "test",
            "Ran command `rad {cmd}` (status={})", result.status.code().unwrap()
        );

        if !result.status.success() {
-
            log::debug!(target: "test", "Command: {result:#?}");
+
            return Err(io::ErrorKind::Other.into());
        }
-

        Ok(())
    }
}
modified radicle/src/rad.rs
@@ -158,12 +158,12 @@ pub fn fork_remote<G: Signer, S: storage::WriteStorage>(
}

pub fn fork<G: Signer, S: storage::WriteStorage>(
-
    proj: Id,
+
    rid: Id,
    signer: &G,
    storage: &S,
) -> Result<(), ForkError> {
    let me = signer.public_key();
-
    let repository = storage.repository_mut(proj)?;
+
    let repository = storage.repository_mut(rid)?;
    // TODO: We should get the id branch pointer from a stored canonical reference.
    let (canonical_id, _) = repository.identity_doc()?;
    let (canonical_branch, canonical_head) = repository.head()?;