cli: Don't fail clone if we have repo locally
This commit is contained in:
parent
c70dc71b18
commit
207030d2e1
|
|
@ -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))
|
||||
));
|
||||
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: 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.
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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};
|
||||
|
|
@ -293,6 +294,29 @@ fn rad_init_sync_and_clone() {
|
|||
.unwrap();
|
||||
}
|
||||
|
||||
#[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
|
||||
|
|
|
|||
|
|
@ -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(())
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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()?;
|
||||
|
|
|
|||
Loading…
Reference in New Issue