feat: optionally specify max commits between dev and main
All checks were successful
Rust / build (push) Successful in 6m21s
ci/woodpecker/push/cron-docker-builder Pipeline was successful
ci/woodpecker/push/push-next Pipeline was successful
ci/woodpecker/push/tag-created Pipeline was successful
Release Please / Release-plz (push) Successful in 2m9s

The default is 25.

Closes kemitix/git-next#121
This commit is contained in:
Paul Campbell 2024-09-05 09:41:17 +01:00
parent 3672fd5d45
commit e759e495fd
24 changed files with 351 additions and 85 deletions

View file

@ -198,13 +198,14 @@ forge_type = "GitHub"
hostname = "github.com"
user = "username"
token = "api-key"
max_dev_commits = 25
```
- **forge_type** - one of: `ForgeJo` or `GitHub`
- **hostname** - the hostname for the forge.
- **user** - the user to authenticate as
- **token** - application token for the user. See below for the permissions
required for on each forge.
- **token** - application token for the user. See [Forges](#forges) below for the permissions required for each forge.
- **max_dev_commits** - [optional] the maximum number of commits allowed between `dev` and `main`. Defaults to 25.
Generally, the `user` will need to be able to push to `main` and to _force-push_
to `next`.

View file

@ -1,8 +1,5 @@
//
use git_next_core::{
git::{ForgeLike, RepoDetails},
ForgeType,
};
use git_next_core::git::{ForgeLike, RepoDetails};
#[cfg(feature = "forgejo")]
use git_next_forge_forgejo::ForgeJo;
@ -19,9 +16,9 @@ impl Forge {
pub fn create(repo_details: RepoDetails, net: Network) -> Box<dyn ForgeLike> {
match repo_details.forge.forge_type() {
#[cfg(feature = "forgejo")]
ForgeType::ForgeJo => Box::new(ForgeJo::new(repo_details, net)),
git_next_core::ForgeType::ForgeJo => Box::new(ForgeJo::new(repo_details, net)),
#[cfg(feature = "github")]
ForgeType::GitHub => Box::new(Github::new(repo_details, net)),
git_next_core::ForgeType::GitHub => Box::new(Github::new(repo_details, net)),
_ => {
drop(repo_details);
drop(net);

View file

@ -11,7 +11,7 @@ use git_next_core::{
#[test]
fn test_forgejo_name() {
let net = Network::new_mock();
let repo_details = given_repo_details(ForgeType::ForgeJo);
let repo_details = given_repo_details(git_next_core::ForgeType::ForgeJo);
let forge = Forge::create(repo_details, net);
assert_eq!(forge.name(), "forgejo");
}
@ -20,20 +20,17 @@ fn test_forgejo_name() {
#[test]
fn test_github_name() {
let net = Network::new_mock();
let repo_details = given_repo_details(ForgeType::GitHub);
let repo_details = given_repo_details(git_next_core::ForgeType::GitHub);
let forge = Forge::create(repo_details, net);
assert_eq!(forge.name(), "github");
}
fn given_fs() -> kxio::fs::FileSystem {
kxio::fs::temp().unwrap_or_else(|e| {
#[allow(dead_code)]
fn given_repo_details(forge_type: git_next_core::ForgeType) -> RepoDetails {
let fs = kxio::fs::temp().unwrap_or_else(|e| {
println!("{e}");
panic!("fs")
})
}
fn given_repo_details(forge_type: ForgeType) -> RepoDetails {
let fs = given_fs();
});
git::repo_details(
1,
git::Generation::default(),

View file

@ -69,6 +69,22 @@ pub fn a_name() -> String {
generate(5)
}
pub fn maybe_a_number() -> Option<u32> {
use rand::Rng;
let mut rng = rand::thread_rng();
if Rng::gen_ratio(&mut rng, 1, 2) {
Some(a_number())
} else {
None
}
}
pub fn a_number() -> u32 {
use rand::Rng;
let mut rng = rand::thread_rng();
rng.gen_range(0..100)
}
pub fn a_webhook_id() -> WebhookId {
WebhookId::new(a_name())
}
@ -89,6 +105,7 @@ pub fn a_forge_config() -> ForgeConfig {
a_name(),
a_name(),
a_name(),
maybe_a_number(),
BTreeMap::default(), // no repos
)
}

View file

@ -0,0 +1,4 @@
//
use crate::newtype;
newtype!(CommitCount, u32, Default, "A number of commits");

View file

@ -11,6 +11,7 @@ pub fn forge_details(n: u32, forge_type: ForgeType) -> ForgeDetails {
hostname(n),
user(n),
api_token(n),
None,
)
}

View file

@ -2,6 +2,8 @@ use std::collections::BTreeMap;
use crate::config::{ApiToken, ForgeType, Hostname, RepoAlias, ServerRepoConfig, User};
use super::CommitCount;
/// Defines a Forge to connect to
/// Maps from `git-next-server.toml` at `forge.{forge}`
#[derive(
@ -22,6 +24,7 @@ pub struct ForgeConfig {
hostname: String,
user: String,
token: String,
max_dev_commits: Option<u32>,
repos: BTreeMap<String, ServerRepoConfig>,
}
impl ForgeConfig {
@ -41,6 +44,10 @@ impl ForgeConfig {
ApiToken::new(self.token.clone().into())
}
pub(crate) fn max_dev_commits(&self) -> Option<CommitCount> {
self.max_dev_commits.map(CommitCount::from)
}
pub fn repos(&self) -> impl Iterator<Item = (RepoAlias, &ServerRepoConfig)> {
self.repos
.iter()

View file

@ -1,5 +1,7 @@
use crate::config::{ApiToken, ForgeAlias, ForgeConfig, ForgeType, Hostname, User};
use super::CommitCount;
/// The derived information about a Forge, used to create interactions with it
#[derive(Clone, Default, Debug, derive_more::Constructor, derive_with::With)]
pub struct ForgeDetails {
@ -8,8 +10,7 @@ pub struct ForgeDetails {
hostname: Hostname,
user: User,
token: ApiToken,
// API Token
// Private SSH Key Path
max_dev_commits: Option<CommitCount>,
}
impl ForgeDetails {
#[must_use]
@ -35,15 +36,21 @@ impl ForgeDetails {
pub const fn token(&self) -> &ApiToken {
&self.token
}
#[must_use]
pub const fn max_dev_commits(&self) -> Option<&CommitCount> {
self.max_dev_commits.as_ref()
}
}
impl From<(&ForgeAlias, &ForgeConfig)> for ForgeDetails {
fn from(forge: (&ForgeAlias, &ForgeConfig)) -> Self {
fn from((forge_alias, forge_config): (&ForgeAlias, &ForgeConfig)) -> Self {
Self {
forge_alias: forge.0.clone(),
forge_type: forge.1.forge_type(),
hostname: forge.1.hostname(),
user: forge.1.user(),
token: forge.1.token(),
forge_alias: forge_alias.clone(),
forge_type: forge_config.forge_type(),
hostname: forge_config.hostname(),
user: forge_config.user(),
token: forge_config.token(),
max_dev_commits: forge_config.max_dev_commits(),
}
}
}

View file

@ -1,6 +1,7 @@
//
mod api_token;
mod branch_name;
mod commit_count;
pub mod common;
mod forge_alias;
mod forge_config;
@ -26,6 +27,7 @@ mod tests;
pub use api_token::ApiToken;
pub use branch_name::BranchName;
pub use commit_count::CommitCount;
pub use forge_alias::ForgeAlias;
#[allow(clippy::module_name_repetitions)]
pub use forge_config::ForgeConfig;

View file

@ -149,6 +149,8 @@ mod repo_config {
}
}
mod forge_config {
use given::maybe_a_number;
use super::*;
#[test]
@ -166,7 +168,7 @@ mod forge_config {
let mut repos = BTreeMap::new();
repos.insert(red_name.clone(), red.clone());
repos.insert(blue_name.clone(), blue.clone());
let fc = ForgeConfig::new(forge_type, hostname, user, token, repos);
let fc = ForgeConfig::new(forge_type, hostname, user, token, maybe_a_number(), repos);
let returned_repos = fc.repos().collect::<Vec<_>>();
@ -186,7 +188,7 @@ mod forge_config {
let user = given::a_name();
let token = given::a_name();
let repos = BTreeMap::new();
let fc = ForgeConfig::new(forge_type, hostname, user, token, repos);
let fc = ForgeConfig::new(forge_type, hostname, user, token, maybe_a_number(), repos);
assert_eq!(fc.forge_type(), ForgeType::MockForge);
}
@ -197,7 +199,14 @@ mod forge_config {
let user = given::a_name();
let token = given::a_name();
let repos = BTreeMap::new();
let fc = ForgeConfig::new(forge_type, hostname.clone(), user, token, repos);
let fc = ForgeConfig::new(
forge_type,
hostname.clone(),
user,
token,
maybe_a_number(),
repos,
);
assert_eq!(fc.hostname(), Hostname::new(hostname));
}
@ -208,7 +217,14 @@ mod forge_config {
let user = given::a_name();
let token = given::a_name();
let repos = BTreeMap::new();
let fc = ForgeConfig::new(forge_type, hostname, user.clone(), token, repos);
let fc = ForgeConfig::new(
forge_type,
hostname,
user.clone(),
token,
maybe_a_number(),
repos,
);
assert_eq!(fc.user(), User::new(user));
}
@ -219,7 +235,14 @@ mod forge_config {
let user = given::a_name();
let token = given::a_name();
let repos = BTreeMap::new();
let fc = ForgeConfig::new(forge_type, hostname, user, token.clone(), repos);
let fc = ForgeConfig::new(
forge_type,
hostname,
user,
token.clone(),
maybe_a_number(),
repos,
);
assert_eq!(fc.token().expose_secret(), token.as_str());
}
@ -237,7 +260,7 @@ mod forge_config {
let mut repos = BTreeMap::new();
repos.insert(red_name.clone(), red.clone());
repos.insert(blue_name, blue);
let fc = ForgeConfig::new(forge_type, hostname, user, token, repos);
let fc = ForgeConfig::new(forge_type, hostname, user, token, maybe_a_number(), repos);
let returned_repo = fc.get_repo(red_name.as_str());
@ -255,8 +278,14 @@ mod forge_details {
let user = User::new(given::a_name());
let token = ApiToken::new(given::a_name().into());
let forge_alias = ForgeAlias::new(given::a_name());
let forge_details =
ForgeDetails::new(forge_alias.clone(), forge_type, hostname, user, token);
let forge_details = ForgeDetails::new(
forge_alias.clone(),
forge_type,
hostname,
user,
token,
given::maybe_a_number().map(CommitCount::from),
);
let result = forge_details.forge_alias();
@ -269,7 +298,14 @@ mod forge_details {
let user = User::new(given::a_name());
let token = ApiToken::new(given::a_name().into());
let forge_name = ForgeAlias::new(given::a_name());
let forge_details = ForgeDetails::new(forge_name, forge_type, hostname, user, token);
let forge_details = ForgeDetails::new(
forge_name,
forge_type,
hostname,
user,
token,
given::maybe_a_number().map(CommitCount::from),
);
let result = forge_details.forge_type();
@ -282,8 +318,14 @@ mod forge_details {
let user = User::new(given::a_name());
let token = ApiToken::new(given::a_name().into());
let forge_name = ForgeAlias::new(given::a_name());
let forge_details =
ForgeDetails::new(forge_name, forge_type, hostname.clone(), user, token);
let forge_details = ForgeDetails::new(
forge_name,
forge_type,
hostname.clone(),
user,
token,
given::maybe_a_number().map(CommitCount::from),
);
let result = forge_details.hostname();
@ -296,8 +338,14 @@ mod forge_details {
let user = User::new(given::a_name());
let token = ApiToken::new(given::a_name().into());
let forge_name = ForgeAlias::new(given::a_name());
let forge_details =
ForgeDetails::new(forge_name, forge_type, hostname, user.clone(), token);
let forge_details = ForgeDetails::new(
forge_name,
forge_type,
hostname,
user.clone(),
token,
given::maybe_a_number().map(CommitCount::from),
);
let result = forge_details.user();
@ -310,8 +358,14 @@ mod forge_details {
let user = User::new(given::a_name());
let token = ApiToken::new(given::a_name().into());
let forge_name = ForgeAlias::new(given::a_name());
let forge_details =
ForgeDetails::new(forge_name, forge_type, hostname, user, token.clone());
let forge_details = ForgeDetails::new(
forge_name,
forge_type,
hostname,
user,
token.clone(),
given::maybe_a_number().map(CommitCount::from),
);
let result = forge_details.token();
@ -325,7 +379,14 @@ mod forge_details {
let user = User::new(given::a_name());
let token = ApiToken::new(given::a_name().into());
let forge_name = ForgeAlias::new(given::a_name());
let forge_details = ForgeDetails::new(forge_name, forge_type, hostname, user, token);
let forge_details = ForgeDetails::new(
forge_name,
forge_type,
hostname,
user,
token,
given::maybe_a_number().map(CommitCount::from),
);
let result = forge_details.with_hostname(other_hostname.clone());
@ -340,12 +401,14 @@ mod forge_details {
let user = User::new(user_value.clone());
let token_value = given::a_name();
let token = ApiToken::new(token_value.clone().into());
let max_dev_commits = given::maybe_a_number();
let forge_alias = ForgeAlias::new(given::a_name());
let forge_config = ForgeConfig::new(
forge_type,
hostname_value,
user_value,
token_value,
max_dev_commits,
BTreeMap::new(),
);
@ -355,6 +418,12 @@ mod forge_details {
assert_eq!(forge_details.hostname(), &hostname);
assert_eq!(forge_details.user(), &user);
assert_eq!(forge_details.token().expose_secret(), token.expose_secret());
assert_eq!(
forge_details
.max_dev_commits()
.map(|commit_count| commit_count.clone().peel()),
max_dev_commits
);
}
}
mod forge_name {
@ -492,6 +561,12 @@ mod server {
let forge_hostname = forge_default.hostname();
let forge_user = forge_default.user();
let forge_token = forge_default.token().expose_secret().to_string();
let optional_max_dev_commits = forge_default
.max_dev_commits()
.map(CommitCount::peel)
.map_or_else(String::new, |max_dev_commits| {
format!("max_dev_commits = {max_dev_commits}")
});
let mut repos: Vec<String> = vec![];
for (repo_alias, server_repo_config) in forge_default.repos() {
let repo_path = server_repo_config.repo();
@ -542,6 +617,7 @@ forge_type = "{forge_type}"
hostname = "{forge_hostname}"
user = "{forge_user}"
token = "{forge_token}"
{optional_max_dev_commits}
[forge.{forge_alias}.repos]
{repos}
@ -726,6 +802,23 @@ mod given {
}
generate(5)
}
pub fn a_number() -> u32 {
use rand::Rng;
let mut rng = rand::thread_rng();
rng.gen_range(0..100)
}
pub fn maybe_a_number() -> Option<u32> {
use rand::Rng;
let mut rng = rand::thread_rng();
if Rng::gen_ratio(&mut rng, 1, 2) {
Some(a_number())
} else {
None
}
}
pub fn an_app_config() -> AppConfig {
AppConfig::new(
a_listen(),
@ -785,6 +878,7 @@ mod given {
a_name(), // hostname
a_name(), // user
a_name(), // token
maybe_a_number(),
some_server_repo_configs(),
)
}

View file

@ -49,6 +49,7 @@ impl RepoDetails {
forge_config.hostname(),
forge_config.user(),
forge_config.token(),
forge_config.max_dev_commits(),
),
}
}
@ -94,12 +95,7 @@ impl RepoDetails {
|> GitDir::pathbuf
|> gix::ThreadSafeRepository::open
}?;
let repo = pike! {
gix_repo
|> RwLock::new
|> Arc::new
|> RealOpenRepository::new
};
let repo = RealOpenRepository::new(Arc::new(RwLock::new(gix_repo)), self.forge.clone());
Ok(repo)
}

View file

@ -66,7 +66,10 @@ impl RepositoryFactory for RealRepositoryFactory {
)?
.fetch_only(gix::progress::Discard, &AtomicBool::new(false))?;
tracing::info!("created");
let repo = RealOpenRepository::new(Arc::new(RwLock::new(gix_repo.into())));
let repo = RealOpenRepository::new(
Arc::new(RwLock::new(gix_repo.into())),
repo_details.forge.clone(),
);
Ok(Box::new(repo))
}

View file

@ -31,8 +31,11 @@ pub enum Repository {
}
#[cfg(test)]
pub(crate) const fn test(fs: kxio::fs::FileSystem) -> TestRepository {
TestRepository::new(fs, vec![], vec![])
pub(crate) const fn test(
fs: kxio::fs::FileSystem,
forge_details: crate::ForgeDetails,
) -> TestRepository {
TestRepository::new(fs, vec![], vec![], forge_details)
}
/// Opens a repository, cloning if necessary

View file

@ -37,10 +37,11 @@ pub enum OpenRepository {
}
#[cfg(not(tarpaulin_include))]
pub fn real(gix_repo: gix::Repository) -> OpenRepository {
OpenRepository::Real(oreal::RealOpenRepository::new(Arc::new(RwLock::new(
gix_repo.into(),
))))
pub fn real(gix_repo: gix::Repository, forge_details: crate::ForgeDetails) -> OpenRepository {
OpenRepository::Real(oreal::RealOpenRepository::new(
Arc::new(RwLock::new(gix_repo.into())),
forge_details,
))
}
#[cfg(not(tarpaulin_include))] // don't test mocks
@ -49,8 +50,15 @@ pub(crate) fn test(
fs: &kxio::fs::FileSystem,
on_fetch: Vec<otest::OnFetch>,
on_push: Vec<otest::OnPush>,
forge_details: crate::ForgeDetails,
) -> OpenRepository {
OpenRepository::Test(TestOpenRepository::new(gitdir, fs, on_fetch, on_push))
OpenRepository::Test(TestOpenRepository::new(
gitdir,
fs,
on_fetch,
on_push,
forge_details,
))
}
#[allow(clippy::module_name_repetitions)]

View file

@ -1,7 +1,7 @@
//
use crate::{
git::{self, repository::OpenRepositoryLike},
BranchName, Hostname, RemoteUrl, RepoPath,
BranchName, ForgeDetails, Hostname, RemoteUrl, RepoPath,
};
use derive_more::Constructor;
@ -16,11 +16,14 @@ use std::{
};
#[derive(Clone, Debug, Constructor)]
pub struct RealOpenRepository(Arc<RwLock<gix::ThreadSafeRepository>>);
pub struct RealOpenRepository {
inner: Arc<RwLock<gix::ThreadSafeRepository>>,
forge_details: ForgeDetails,
}
impl super::OpenRepositoryLike for RealOpenRepository {
fn remote_branches(&self) -> git::push::Result<Vec<BranchName>> {
let refs = self
.0
.inner
.read()
.map_err(|_| git::push::Error::Lock)
.and_then(|repo| {
@ -44,7 +47,7 @@ impl super::OpenRepositoryLike for RealOpenRepository {
#[tracing::instrument]
fn find_default_remote(&self, direction: git::repository::Direction) -> Option<RemoteUrl> {
let Ok(repository) = self.0.read() else {
let Ok(repository) = self.inner.read() else {
#[cfg(not(tarpaulin_include))] // don't test mutex lock failure
tracing::debug!("no repository");
return None;
@ -66,7 +69,7 @@ impl super::OpenRepositoryLike for RealOpenRepository {
fn fetch(&self) -> Result<(), git::fetch::Error> {
use std::sync::atomic::AtomicBool;
let Ok(repository) = self.0.read() else {
let Ok(repository) = self.inner.read() else {
#[cfg(not(tarpaulin_include))] // don't test mutex lock failure
return Err(git::fetch::Error::Lock);
};
@ -117,7 +120,7 @@ impl super::OpenRepositoryLike for RealOpenRepository {
)
.into();
let git_dir = self
.0
.inner
.read()
.map_err(|_| git::push::Error::Lock)
.map(|r| r.git_dir().to_path_buf())?;
@ -140,8 +143,14 @@ impl super::OpenRepositoryLike for RealOpenRepository {
branch_name: &BranchName,
find_commits: &[git::Commit],
) -> Result<Vec<git::Commit>, git::commit::log::Error> {
let limit = if find_commits.is_empty() { 1 } else { 25 };
self.0
let limit: usize = if find_commits.is_empty() {
1
} else {
self.forge_details
.max_dev_commits()
.map_or(25, |commit_count| commit_count.clone().peel() as usize)
};
self.inner
.read()
.map_err(|_| git::commit::log::Error::Lock)
.map(|repo| {
@ -196,7 +205,7 @@ impl super::OpenRepositoryLike for RealOpenRepository {
#[tracing::instrument(skip_all, fields(%branch_name, ?file_name))]
fn read_file(&self, branch_name: &BranchName, file_name: &Path) -> git::file::Result<String> {
self.0
self.inner
.read()
.map_err(|_| git::file::Error::Lock)
.and_then(|repo| {

View file

@ -4,7 +4,7 @@ use crate::{
self,
repository::open::{OpenRepositoryLike, RealOpenRepository},
},
BranchName, GitDir, RemoteUrl, RepoBranches,
BranchName, ForgeDetails, GitDir, RemoteUrl, RepoBranches,
};
use derive_more::Constructor;
@ -155,6 +155,7 @@ impl TestOpenRepository {
fs: &kxio::fs::FileSystem,
on_fetch: Vec<OnFetch>,
on_push: Vec<OnPush>,
forge_details: ForgeDetails,
) -> Self {
let pathbuf = fs.base().join(gitdir.to_path_buf());
#[allow(clippy::expect_used)]
@ -165,7 +166,7 @@ impl TestOpenRepository {
fetch_counter: Arc::new(RwLock::new(0)),
on_push,
push_counter: Arc::new(RwLock::new(0)),
real: RealOpenRepository::new(Arc::new(RwLock::new(gix.into()))),
real: RealOpenRepository::new(Arc::new(RwLock::new(gix.into())), forge_details),
}
}

View file

@ -1,3 +1,5 @@
use crate::CommitCount;
//
use super::*;
@ -6,7 +8,8 @@ use super::*;
fn should_return_single_item_in_commit_log_when_not_searching() -> TestResult {
let_assert!(Ok(fs) = kxio::fs::temp());
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
let test_repository = git::repository::test(fs.clone());
let forge_details = given::forge_details();
let test_repository = git::repository::test(fs.clone(), forge_details);
let_assert!(Ok(open_repository) = test_repository.open(&gitdir));
let repo_config = &given::a_repo_config();
let branches = repo_config.branches();
@ -23,7 +26,10 @@ fn should_return_capacity_25_in_commit_log_when_searching_for_garbage() -> TestR
let_assert!(Ok(fs) = kxio::fs::temp());
let branch_name = given::a_branch_name();
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
let test_repository = git::repository::test(fs.clone());
let forge_details = given::forge_details().with_max_dev_commits(Some(CommitCount::from(25)));
let_assert!(Some(max_dev_commits) = forge_details.max_dev_commits());
assert!(**max_dev_commits >= 25);
let test_repository = git::repository::test(fs.clone(), forge_details);
let_assert!(Ok(open_repository) = test_repository.open(&gitdir));
for _ in [0; 25] {
then::create_a_commit_on_branch(&fs, &gitdir, &branch_name)?;
@ -39,7 +45,10 @@ fn should_return_5_in_commit_log_when_searching_for_5th_item() -> TestResult {
let_assert!(Ok(fs) = kxio::fs::temp(), "create temp directory");
let branch_name = given::a_branch_name();
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
let test_repository = git::repository::test(fs.clone());
let forge_details = given::forge_details().with_max_dev_commits(Some(CommitCount::from(10)));
let_assert!(Some(max_dev_commits) = forge_details.max_dev_commits());
assert!(**max_dev_commits > 5);
let test_repository = git::repository::test(fs.clone(), forge_details);
let_assert!(
Ok(open_repository) = test_repository.open(&gitdir),
"open repository"

View file

@ -14,7 +14,14 @@ fn should_return_repos() {
let mut repos = BTreeMap::new();
repos.insert(red_name.clone(), red.clone());
repos.insert(blue_name.clone(), blue.clone());
let fc = ForgeConfig::new(forge_type, hostname, user, token, repos);
let fc = ForgeConfig::new(
forge_type,
hostname,
user,
token,
given::maybe_a_number(),
repos,
);
let returned_repos = fc.repos().collect::<Vec<_>>();
@ -35,7 +42,14 @@ fn should_return_forge_type() {
let user = given::a_name();
let token = given::a_name();
let repos = BTreeMap::new();
let fc = ForgeConfig::new(forge_type, hostname, user, token, repos);
let fc = ForgeConfig::new(
forge_type,
hostname,
user,
token,
given::maybe_a_number(),
repos,
);
assert_eq!(fc.forge_type(), ForgeType::MockForge);
}
@ -47,7 +61,14 @@ fn should_return_hostname() {
let user = given::a_name();
let token = given::a_name();
let repos = BTreeMap::new();
let fc = ForgeConfig::new(forge_type, hostname.clone(), user, token, repos);
let fc = ForgeConfig::new(
forge_type,
hostname.clone(),
user,
token,
given::maybe_a_number(),
repos,
);
assert_eq!(fc.hostname(), Hostname::new(hostname));
}
@ -59,7 +80,14 @@ fn should_return_user() {
let user = given::a_name();
let token = given::a_name();
let repos = BTreeMap::new();
let fc = ForgeConfig::new(forge_type, hostname, user.clone(), token, repos);
let fc = ForgeConfig::new(
forge_type,
hostname,
user.clone(),
token,
given::maybe_a_number(),
repos,
);
assert_eq!(fc.user(), User::new(user));
}
@ -71,7 +99,14 @@ fn should_return_token() {
let user = given::a_name();
let token = given::a_name();
let repos = BTreeMap::new();
let fc = ForgeConfig::new(forge_type, hostname, user, token.clone(), repos);
let fc = ForgeConfig::new(
forge_type,
hostname,
user,
token.clone(),
given::maybe_a_number(),
repos,
);
assert_eq!(fc.token().expose_secret(), token.as_str());
}
@ -90,7 +125,14 @@ fn should_return_repo() {
let mut repos = BTreeMap::new();
repos.insert(red_name.clone(), red.clone());
repos.insert(blue_name, blue);
let fc = ForgeConfig::new(forge_type, hostname, user, token, repos);
let fc = ForgeConfig::new(
forge_type,
hostname,
user,
token,
given::maybe_a_number(),
repos,
);
let returned_repo = fc.get_repo(red_name.as_str());

View file

@ -9,8 +9,9 @@ fn should_return_file() -> TestResult {
let file_name = given::a_pathbuf();
let contents = given::a_name();
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
let forge_details = given::forge_details();
let test_repository = git::repository::test(fs.clone());
let test_repository = git::repository::test(fs.clone(), forge_details);
let_assert!(Ok(open_repository) = test_repository.open(&gitdir));
then::commit_named_file_to_branch(
&file_name,
@ -33,7 +34,8 @@ fn should_return_file() -> TestResult {
fn should_error_on_missing_file() -> TestResult {
let_assert!(Ok(fs) = kxio::fs::temp());
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
let test_repository = git::repository::test(fs.clone());
let forge_details = given::forge_details();
let test_repository = git::repository::test(fs.clone(), forge_details);
let_assert!(Ok(open_repository) = test_repository.open(&gitdir));
let repo_config = &given::a_repo_config();
let branches = repo_config.branches();

View file

@ -13,7 +13,7 @@ use crate::{
},
RepoDetails,
},
GitDir,
ForgeDetails, GitDir,
};
#[allow(clippy::module_name_repetitions)]
@ -22,6 +22,7 @@ pub struct TestRepository {
fs: kxio::fs::FileSystem,
on_fetch: Vec<git::repository::open::otest::OnFetch>,
on_push: Vec<git::repository::open::otest::OnPush>,
forge_details: ForgeDetails,
}
impl TestRepository {
pub fn on_fetch(&mut self, on_fetch: OnFetch) {
@ -39,6 +40,7 @@ impl RepositoryLike for TestRepository {
&self.fs,
self.on_fetch.clone(),
self.on_push.clone(),
self.forge_details.clone(),
))
}

View file

@ -172,6 +172,7 @@ mod repo_details {
"host".to_string(),
"user".to_string(),
"token".to_string(),
given::maybe_a_number(), // max dev commits
BTreeMap::new(),
),
GitDir::new(PathBuf::default().join("foo"), StoragePathType::Internal),
@ -184,6 +185,8 @@ mod repo_details {
}
}
pub mod given {
use crate::ForgeDetails;
use super::*;
pub fn repo_branches() -> RepoBranches {
@ -219,6 +222,22 @@ pub mod given {
generate(5)
}
pub fn maybe_a_number() -> Option<u32> {
use rand::Rng;
let mut rng = rand::thread_rng();
if Rng::gen_ratio(&mut rng, 1, 2) {
Some(a_number())
} else {
None
}
}
pub fn a_number() -> u32 {
use rand::Rng;
let mut rng = rand::thread_rng();
rng.gen_range(5..100)
}
pub fn a_branch_name() -> BranchName {
BranchName::new(a_name())
}
@ -235,10 +254,15 @@ pub mod given {
format!("hostname-{}", a_name()),
format!("user-{}", a_name()),
format!("token-{}", a_name()),
BTreeMap::default(), // no repos
given::maybe_a_number(), // max dev commits
BTreeMap::default(), // no repos
)
}
pub fn forge_details() -> ForgeDetails {
(&a_forge_alias(), &a_forge_config()).into()
}
pub fn a_server_repo_config() -> ServerRepoConfig {
let main = a_branch_name().peel();
let next = a_branch_name().peel();

View file

@ -207,7 +207,8 @@ mod positions {
//given
let fs = given::a_filesystem();
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
let mut test_repository = git::repository::test(fs.clone());
let forge_details = given::forge_details();
let mut test_repository = git::repository::test(fs.clone(), forge_details);
let repo_config = given::a_repo_config();
test_repository.on_fetch(OnFetch::new(
repo_config.branches().clone(),
@ -257,7 +258,8 @@ mod positions {
//given
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
let mut test_repository = git::repository::test(fs.clone());
let forge_details = given::forge_details();
let mut test_repository = git::repository::test(fs.clone(), forge_details);
let repo_config = given::a_repo_config();
test_repository.on_fetch(OnFetch::new(
repo_config.branches().clone(),
@ -343,7 +345,8 @@ mod positions {
//given
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
let mut test_repository = git::repository::test(fs.clone());
let forge_details = given::forge_details();
let mut test_repository = git::repository::test(fs.clone(), forge_details);
let repo_config = given::a_repo_config();
test_repository.on_fetch(OnFetch::new(
repo_config.branches().clone(),
@ -416,7 +419,8 @@ mod positions {
//given
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
let mut test_repository = git::repository::test(fs.clone());
let forge_details = given::forge_details();
let mut test_repository = git::repository::test(fs.clone(), forge_details);
let repo_config = given::a_repo_config();
test_repository.on_fetch(OnFetch::new(
repo_config.branches().clone(),
@ -501,7 +505,8 @@ mod positions {
//given
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
let mut test_repository = git::repository::test(fs.clone());
let forge_details = given::forge_details();
let mut test_repository = git::repository::test(fs.clone(), forge_details);
let repo_config = given::a_repo_config();
test_repository.on_fetch(OnFetch::new(
repo_config.branches().clone(),
@ -598,7 +603,8 @@ mod positions {
//given
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
let mut test_repository = git::repository::test(fs.clone());
let forge_details = given::forge_details();
let mut test_repository = git::repository::test(fs.clone(), forge_details);
let repo_config = given::a_repo_config();
test_repository.on_fetch(OnFetch::new(
repo_config.branches().clone(),

View file

@ -691,6 +691,22 @@ mod forgejo {
generate(5)
}
pub fn maybe_a_number() -> Option<u32> {
use rand::Rng;
let mut rng = rand::thread_rng();
if Rng::gen_ratio(&mut rng, 1, 2) {
Some(a_number())
} else {
None
}
}
pub fn a_number() -> u32 {
use rand::Rng;
let mut rng = rand::thread_rng();
rng.gen_range(0..100)
}
pub fn a_webhook_id() -> WebhookId {
WebhookId::new(a_name())
}
@ -711,6 +727,7 @@ mod forgejo {
a_name(),
a_name(),
a_name(),
maybe_a_number(),
BTreeMap::default(), // no repos
)
}

View file

@ -600,6 +600,7 @@ mod github {
a_name(),
a_name(),
a_name(),
maybe_a_number(),
BTreeMap::default(),
),
GitDir::new(PathBuf::default(), StoragePathType::External),
@ -641,6 +642,22 @@ mod github {
generate(5)
}
pub fn maybe_a_number() -> Option<u32> {
use rand::Rng;
let mut rng = rand::thread_rng();
if Rng::gen_ratio(&mut rng, 1, 2) {
Some(a_number())
} else {
None
}
}
pub fn a_number() -> u32 {
use rand::Rng;
let mut rng = rand::thread_rng();
rng.gen_range(0..100)
}
pub fn a_webhook_id() -> WebhookId {
WebhookId::new(given::a_name())
}