Skip to content

Commit

Permalink
Merge pull request #130 from yu-ichiro/feat/clone-retry
Browse files Browse the repository at this point in the history
Add retry feature to cloning
  • Loading branch information
siketyan authored Apr 23, 2023
2 parents 2e4d93c + 823845a commit f2d12b7
Showing 1 changed file with 28 additions and 9 deletions.
37 changes: 28 additions & 9 deletions src/cmd/clone.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
use std::path::PathBuf;
use std::time::Duration;

use anyhow::{anyhow, Result};
use async_hofs::iter::AsyncMapExt;
use clap::Parser;
use console::style;
use git2::Repository;
use itertools::Itertools;
use tokio::time::sleep;
use tokio_stream::StreamExt;
use tracing::info;
use tracing::{info, warn};

use crate::config::Config;
use crate::console::Spinner;
Expand All @@ -16,6 +17,11 @@ use crate::path::Path;
use crate::root::Root;
use crate::url::Url;

// Constant values taken from implementation of GitHub Cli (gh)
// ref: https://github.com/cli/cli/blob/350011/pkg/cmd/repo/fork/fork.go#L328-L344
const CLONE_RETRY_COUNT: u32 = 3;
const CLONE_RETRY_DURATION: Duration = Duration::from_secs(2);

#[derive(Debug, Parser)]
pub struct Cmd {
/// URL or pattern of the repository to clone.
Expand Down Expand Up @@ -53,11 +59,12 @@ impl Cmd {
let repo: Vec<CloneResult> = Spinner::new("Cloning the repository...")
.spin_while(|| async move {
urls.into_iter()
.map(|url| {
.async_map(|url| async {
info!("Cloning from '{}'", url.to_string());
self.clone(&root, &config, url)
self.clone(&root, &config, url).await
})
.try_collect()
.collect::<Result<Vec<_>>>()
.await
})
.await?;

Expand Down Expand Up @@ -113,20 +120,32 @@ impl Cmd {
Ok(url)
}

fn clone(&self, root: &Root, config: &Config, url: Url) -> Result<CloneResult> {
async fn clone(&self, root: &Root, config: &Config, url: Url) -> Result<CloneResult> {
let path = PathBuf::from(Path::resolve(root, &url));
let profile = config
.rules
.resolve(&url)
.and_then(|r| config.profiles.resolve(&r.profile));

config.git.strategy.clone.clone_repository(
url,
let mut retries = 0;
while let Err(e) = config.git.strategy.clone.clone_repository(
url.clone(),
&path,
&CloneOptions {
recursive: self.recursive,
},
)?;
) {
retries += 1;
if retries > CLONE_RETRY_COUNT {
return Err(e);
} else {
warn!(
"Cloning failed. Retrying in {} seconds",
CLONE_RETRY_DURATION.as_secs(),
);
sleep(CLONE_RETRY_DURATION).await;
}
}

let repo = Repository::open(&path)?;
let profile = if let Some((name, p)) = profile {
Expand Down

0 comments on commit f2d12b7

Please sign in to comment.