diff --git a/src/config.rs b/src/config.rs index 790edfa..5b58502 100644 --- a/src/config.rs +++ b/src/config.rs @@ -64,8 +64,9 @@ mod tests { } #[test] + #[cfg_attr(feature = "pure_tests", ignore)] fn deserialize_example_config() { - let args = Args::parse_from(&[ + let args = Args::parse_from([ "github-backup", "--config", &format!( diff --git a/src/engines/git.rs b/src/engines/git.rs index e5cbedd..ca0443a 100644 --- a/src/engines/git.rs +++ b/src/engines/git.rs @@ -134,6 +134,8 @@ impl GitEngine { let original_head = repository.head_id().ok(); + let default_refspecs = vec!["+refs/heads/*:refs/remotes/origin/*".to_string()]; + trace!( "Configuring fetch operation for repository {}", target.display() @@ -150,7 +152,12 @@ impl GitEngine { ) })? .with_fetch_tags(Tags::All) - .with_refspecs(["+refs/heads/*:refs/remotes/origin/*"], gix::remote::Direction::Fetch) + .with_refspecs( + repo.refspecs.as_ref().unwrap_or(&default_refspecs) + .iter() + .map(|s| gix::bstr::BString::from(s.as_str())) + .collect::>(), + gix::remote::Direction::Fetch) .map_err(|e| { errors::user_with_internal( &format!( @@ -319,6 +326,7 @@ mod tests { let repo = GitRepo::new( "SierraSoftworks/grey", "https://github.com/sierrasoftworks/grey.git", + None, ); let state1 = agent diff --git a/src/entities/mod.rs b/src/entities/mod.rs index 46076da..d66249d 100644 --- a/src/entities/mod.rs +++ b/src/entities/mod.rs @@ -41,6 +41,6 @@ entity!(HttpFile(url: U => String) { with_content_type => content_type: Option, }); -entity!(GitRepo(clone_url: U => String) { +entity!(GitRepo(clone_url: U => String, refspecs: R => Option>) { with_credentials => credentials: Credentials, }); diff --git a/src/pairing.rs b/src/pairing.rs index 02d0c4a..7cd8af4 100644 --- a/src/pairing.rs +++ b/src/pairing.rs @@ -178,7 +178,7 @@ mod tests { async_stream::stream! { let repos: Vec = load_test_file("github.repos.0.json").unwrap(); for repo in repos { - yield Ok(GitRepo::new(repo.full_name.as_str(), repo.clone_url.as_str()) + yield Ok(GitRepo::new(repo.full_name.as_str(), repo.clone_url.as_str(), None) .with_metadata_source(&repo)); } } diff --git a/src/sources/github_repo.rs b/src/sources/github_repo.rs index 047ce40..0c4071f 100644 --- a/src/sources/github_repo.rs +++ b/src/sources/github_repo.rs @@ -29,11 +29,11 @@ impl BackupSource for GitHubRepoSource { let target: GitHubRepoSourceKind = policy.from.as_str().parse()?; match target { - GitHubRepoSourceKind::Org(_) if self.artifact_kind == GitHubArtifactKind::Star => return Err(errors::user( + GitHubRepoSourceKind::Org(_) if self.artifact_kind == GitHubArtifactKind::Star => Err(errors::user( "You cannot use an organization as the source for a starred repository backup.", "Either use `from: user` or `from: users/` when using a github/stars source kind.", )), - GitHubRepoSourceKind::Repo(_) if self.artifact_kind == GitHubArtifactKind::Star => return Err(errors::user( + GitHubRepoSourceKind::Repo(_) if self.artifact_kind == GitHubArtifactKind::Star => Err(errors::user( "You cannot use a repository as the source for a starred repository backup.", "Either use `from: user` or `from: users/` when using a github/stars source kind.", )), @@ -83,16 +83,27 @@ impl BackupSource for GitHubRepoSource { tracing_batteries::prelude::debug!("Calling {} to fetch repos", &url); + let refspecs = policy + .properties + .get("refspecs") + .map(|r| r.split(',').map(|r| r.to_string()).collect::>()); + async_stream::try_stream! { if matches!(target, GitHubRepoSourceKind::Repo(_)) { let repo = self.client.get::(url, &policy.credentials, cancel).await?; - yield GitRepo::new(repo.full_name.as_str(), repo.clone_url.as_str()) + yield GitRepo::new( + repo.full_name.as_str(), + repo.clone_url.as_str(), + refspecs.clone()) .with_credentials(policy.credentials.clone()) .with_metadata_source(&repo); } else { for await repo in self.client.get_paginated::(url, &policy.credentials, cancel) { let repo = repo?; - yield GitRepo::new(repo.full_name.as_str(), repo.clone_url.as_str()) + yield GitRepo::new( + repo.full_name.as_str(), + repo.clone_url.as_str(), + refspecs.clone()) .with_credentials(policy.credentials.clone()) .with_metadata_source(&repo); }