2024-06-09 10:21:09 +01:00
|
|
|
//
|
2024-07-25 09:02:43 +01:00
|
|
|
use crate::{
|
2024-07-26 06:49:09 +01:00
|
|
|
git::{
|
|
|
|
self,
|
|
|
|
repository::{
|
|
|
|
factory::RepositoryFactory as _,
|
|
|
|
open::otest::{OnFetch, OnPush},
|
|
|
|
Direction, RepositoryLike as _,
|
|
|
|
},
|
|
|
|
tests::{given, then},
|
2024-08-06 07:43:28 +01:00
|
|
|
validation::positions::validate,
|
2024-07-25 09:02:43 +01:00
|
|
|
},
|
2024-07-26 06:49:09 +01:00
|
|
|
GitDir, StoragePathType,
|
2024-07-25 09:02:43 +01:00
|
|
|
};
|
2024-06-09 10:21:09 +01:00
|
|
|
|
|
|
|
use assert2::let_assert;
|
|
|
|
|
|
|
|
mod repos {
|
2024-06-19 16:40:10 +01:00
|
|
|
|
2024-06-09 10:21:09 +01:00
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn where_repo_has_no_push_remote() {
|
|
|
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
2024-07-06 14:25:43 +01:00
|
|
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
2024-07-06 19:55:39 +01:00
|
|
|
let repo_details = given::repo_details(&fs).with_gitdir(gitdir);
|
2024-06-19 16:40:10 +01:00
|
|
|
let mut mock_open_repository = git::repository::open::mock();
|
|
|
|
mock_open_repository
|
|
|
|
.expect_find_default_remote()
|
|
|
|
.with(mockall::predicate::eq(Direction::Push))
|
|
|
|
.return_once(|_| None);
|
2024-07-05 20:31:16 +01:00
|
|
|
let mut repository_factory = git::repository::factory::mock();
|
2024-06-19 16:40:10 +01:00
|
|
|
repository_factory
|
|
|
|
.expect_open()
|
|
|
|
.return_once(move |_| Ok(mock_open_repository));
|
|
|
|
let_assert!(
|
2024-07-06 19:55:39 +01:00
|
|
|
Ok(open_repository) = repository_factory.open(&repo_details),
|
2024-06-19 16:40:10 +01:00
|
|
|
"open repo"
|
|
|
|
);
|
|
|
|
|
2024-06-19 07:03:08 +01:00
|
|
|
let result =
|
|
|
|
git::validation::remotes::validate_default_remotes(&*open_repository, &repo_details);
|
2024-06-19 16:40:10 +01:00
|
|
|
print!("{result:?}");
|
|
|
|
let_assert!(Err(err) = result);
|
2024-06-09 10:21:09 +01:00
|
|
|
assert!(matches!(
|
|
|
|
err,
|
2024-06-19 07:03:08 +01:00
|
|
|
git::validation::remotes::Error::NoDefaultPushRemote
|
2024-06-09 10:21:09 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
2024-06-19 16:40:10 +01:00
|
|
|
|
2024-06-09 10:21:09 +01:00
|
|
|
mod positions {
|
|
|
|
use super::*;
|
|
|
|
|
2024-08-06 07:43:28 +01:00
|
|
|
mod validate {
|
2024-06-09 10:21:09 +01:00
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn where_fetch_fails_should_error() {
|
2024-06-19 16:40:10 +01:00
|
|
|
let fs = given::a_filesystem();
|
2024-07-06 14:25:43 +01:00
|
|
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
2024-07-06 19:55:39 +01:00
|
|
|
let repo_details = given::repo_details(&fs).with_gitdir(gitdir);
|
2024-06-19 16:40:10 +01:00
|
|
|
let mut mock_open_repository = git::repository::open::mock();
|
|
|
|
mock_open_repository
|
|
|
|
.expect_fetch()
|
|
|
|
.return_once(|| Err(git::fetch::Error::TestFailureExpected));
|
2024-07-05 20:31:16 +01:00
|
|
|
let mut repository_factory = git::repository::factory::mock();
|
2024-06-19 16:40:10 +01:00
|
|
|
repository_factory
|
|
|
|
.expect_open()
|
|
|
|
.return_once(move |_| Ok(mock_open_repository));
|
2024-06-09 10:21:09 +01:00
|
|
|
let_assert!(
|
2024-07-06 19:55:39 +01:00
|
|
|
Ok(repository) = repository_factory.open(&repo_details),
|
2024-06-19 16:40:10 +01:00
|
|
|
"open repo"
|
2024-06-09 10:21:09 +01:00
|
|
|
);
|
2024-06-19 16:40:10 +01:00
|
|
|
let repo_config = given::a_repo_config();
|
|
|
|
|
2024-08-30 07:49:43 +01:00
|
|
|
let result = validate(&*repository, &repo_details, &repo_config);
|
2024-06-19 16:40:10 +01:00
|
|
|
println!("{result:?}");
|
|
|
|
let_assert!(Err(err) = result, "validate");
|
2024-06-09 10:21:09 +01:00
|
|
|
|
|
|
|
assert!(matches!(
|
|
|
|
err,
|
2024-06-30 18:39:43 +01:00
|
|
|
git::validation::positions::Error::Retryable(_)
|
2024-06-09 10:21:09 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn where_main_branch_is_missing_or_commit_log_is_empty_should_error() {
|
2024-06-19 16:40:10 +01:00
|
|
|
let fs = given::a_filesystem();
|
2024-07-06 14:25:43 +01:00
|
|
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
2024-07-06 19:55:39 +01:00
|
|
|
let repo_details = given::repo_details(&fs).with_gitdir(gitdir);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_config = given::a_repo_config();
|
2024-06-19 16:40:10 +01:00
|
|
|
let main_branch = repo_config.branches().main();
|
|
|
|
let mut mock_open_repository = git::repository::open::mock();
|
|
|
|
mock_open_repository.expect_fetch().return_once(|| Ok(()));
|
|
|
|
mock_open_repository
|
|
|
|
.expect_commit_log()
|
|
|
|
.returning(move |branch_name, _| {
|
|
|
|
if branch_name == &main_branch {
|
|
|
|
Err(git::commit::log::Error::Gix {
|
|
|
|
branch: branch_name.clone(),
|
|
|
|
error: "foo".to_string(),
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
Ok(vec![])
|
|
|
|
}
|
|
|
|
});
|
2024-07-05 20:31:16 +01:00
|
|
|
let mut repository_factory = git::repository::factory::mock();
|
2024-06-19 16:40:10 +01:00
|
|
|
repository_factory
|
|
|
|
.expect_open()
|
|
|
|
.return_once(move |_| Ok(mock_open_repository));
|
2024-06-09 10:21:09 +01:00
|
|
|
let_assert!(
|
2024-07-06 19:55:39 +01:00
|
|
|
Ok(open_repository) = repository_factory.open(&repo_details),
|
2024-06-19 16:40:10 +01:00
|
|
|
"open repo"
|
2024-06-09 10:21:09 +01:00
|
|
|
);
|
2024-06-19 16:40:10 +01:00
|
|
|
|
2024-08-30 07:49:43 +01:00
|
|
|
let result = validate(&*open_repository, &repo_details, &repo_config);
|
2024-06-19 16:40:10 +01:00
|
|
|
println!("{result:?}");
|
|
|
|
|
2024-06-09 10:21:09 +01:00
|
|
|
assert!(matches!(
|
2024-06-19 16:40:10 +01:00
|
|
|
result,
|
2024-06-30 18:39:43 +01:00
|
|
|
Err(git::validation::positions::Error::Retryable(_))
|
2024-06-09 10:21:09 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn where_next_branch_is_missing_or_commit_log_is_empty_should_error() {
|
2024-06-19 16:40:10 +01:00
|
|
|
let fs = given::a_filesystem();
|
2024-07-06 14:25:43 +01:00
|
|
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
2024-07-06 19:55:39 +01:00
|
|
|
let repo_details = given::repo_details(&fs).with_gitdir(gitdir);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_config = given::a_repo_config();
|
2024-06-19 16:40:10 +01:00
|
|
|
let next_branch = repo_config.branches().next();
|
|
|
|
let mut mock_open_repository = git::repository::open::mock();
|
|
|
|
mock_open_repository.expect_fetch().return_once(|| Ok(()));
|
|
|
|
mock_open_repository
|
|
|
|
.expect_commit_log()
|
|
|
|
.returning(move |branch_name, _| {
|
|
|
|
if branch_name == &next_branch {
|
|
|
|
Err(git::commit::log::Error::Gix {
|
|
|
|
branch: branch_name.clone(),
|
|
|
|
error: "foo".to_string(),
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
Ok(vec![given::a_commit()])
|
|
|
|
}
|
|
|
|
});
|
2024-07-05 20:31:16 +01:00
|
|
|
let mut repository_factory = git::repository::factory::mock();
|
2024-06-19 16:40:10 +01:00
|
|
|
repository_factory
|
|
|
|
.expect_open()
|
|
|
|
.return_once(move |_| Ok(mock_open_repository));
|
2024-06-09 10:21:09 +01:00
|
|
|
let_assert!(
|
2024-07-06 19:55:39 +01:00
|
|
|
Ok(open_repository) = repository_factory.open(&repo_details),
|
2024-06-19 16:40:10 +01:00
|
|
|
"open repo"
|
2024-06-09 10:21:09 +01:00
|
|
|
);
|
2024-06-19 16:40:10 +01:00
|
|
|
|
2024-08-30 07:49:43 +01:00
|
|
|
let result = validate(&*open_repository, &repo_details, &repo_config);
|
2024-06-19 16:40:10 +01:00
|
|
|
println!("{result:?}");
|
2024-06-09 10:21:09 +01:00
|
|
|
|
|
|
|
assert!(matches!(
|
2024-06-19 16:40:10 +01:00
|
|
|
result,
|
2024-06-30 18:39:43 +01:00
|
|
|
Err(git::validation::positions::Error::Retryable(_))
|
2024-06-09 10:21:09 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn where_dev_branch_is_missing_or_commit_log_is_empty_should_error() {
|
2024-06-19 16:40:10 +01:00
|
|
|
let fs = given::a_filesystem();
|
2024-07-06 14:25:43 +01:00
|
|
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
2024-07-06 19:55:39 +01:00
|
|
|
let repo_details = given::repo_details(&fs).with_gitdir(gitdir);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_config = given::a_repo_config();
|
2024-06-19 16:40:10 +01:00
|
|
|
let dev_branch = repo_config.branches().dev();
|
|
|
|
let mut mock_open_repository = git::repository::open::mock();
|
|
|
|
mock_open_repository.expect_fetch().return_once(|| Ok(()));
|
|
|
|
mock_open_repository
|
|
|
|
.expect_commit_log()
|
|
|
|
.returning(move |branch_name, _| {
|
|
|
|
if branch_name == &dev_branch {
|
|
|
|
Err(git::commit::log::Error::Gix {
|
|
|
|
branch: branch_name.clone(),
|
|
|
|
error: "foo".to_string(),
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
Ok(vec![given::a_commit()])
|
|
|
|
}
|
|
|
|
});
|
2024-07-05 20:31:16 +01:00
|
|
|
let mut repository_factory = git::repository::factory::mock();
|
2024-06-19 16:40:10 +01:00
|
|
|
repository_factory
|
|
|
|
.expect_open()
|
|
|
|
.return_once(move |_| Ok(mock_open_repository));
|
2024-06-09 10:21:09 +01:00
|
|
|
let_assert!(
|
2024-07-06 19:55:39 +01:00
|
|
|
Ok(open_repository) = repository_factory.open(&repo_details),
|
2024-06-19 16:40:10 +01:00
|
|
|
"open repo"
|
2024-06-09 10:21:09 +01:00
|
|
|
);
|
2024-06-19 16:40:10 +01:00
|
|
|
|
2024-08-30 07:49:43 +01:00
|
|
|
let result = validate(&*open_repository, &repo_details, &repo_config);
|
2024-06-19 16:40:10 +01:00
|
|
|
println!("{result:?}");
|
2024-06-09 10:21:09 +01:00
|
|
|
|
|
|
|
assert!(matches!(
|
2024-06-19 16:40:10 +01:00
|
|
|
result,
|
2024-06-30 18:39:43 +01:00
|
|
|
Err(git::validation::positions::Error::Retryable(_))
|
2024-06-09 10:21:09 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn where_dev_branch_is_not_based_on_main_should_error() {
|
|
|
|
//given
|
2024-06-19 16:40:10 +01:00
|
|
|
let fs = given::a_filesystem();
|
2024-07-06 14:25:43 +01:00
|
|
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
2024-09-05 09:41:17 +01:00
|
|
|
let forge_details = given::forge_details();
|
|
|
|
let mut test_repository = git::repository::test(fs.clone(), forge_details);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_config = given::a_repo_config();
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_fetch(OnFetch::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|branches, gitdir, fs| {
|
|
|
|
// /--- 4 next
|
|
|
|
// 0 --- 1 --- 3 main
|
|
|
|
// \--- 2 dev
|
|
|
|
// add a commit to main (0 -> 1)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.main())?;
|
|
|
|
// add a commit to dev ( 1 -> 2)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.dev())?;
|
|
|
|
// switch back to main
|
|
|
|
then::git_switch(&branches.main(), gitdir)?;
|
|
|
|
// add a second commit to main (1 -> 3)
|
|
|
|
then::git_log_all(gitdir)?;
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.main())?;
|
|
|
|
// add a commit to next 1 -> 4
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.next())?;
|
|
|
|
then::git_log_all(gitdir)?;
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
2024-06-19 16:40:10 +01:00
|
|
|
let_assert!(
|
|
|
|
Ok(open_repository) = test_repository.open(&gitdir),
|
|
|
|
"open repo"
|
|
|
|
);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_details = given::repo_details(&fs).with_gitdir(gitdir);
|
|
|
|
|
|
|
|
//when
|
|
|
|
let_assert!(
|
2024-08-30 07:49:43 +01:00
|
|
|
Err(err) = validate(&*open_repository, &repo_details, &repo_config),
|
2024-06-09 10:21:09 +01:00
|
|
|
"validate"
|
|
|
|
);
|
|
|
|
|
|
|
|
//then
|
|
|
|
assert!(matches!(
|
|
|
|
err,
|
2024-07-16 20:00:29 +01:00
|
|
|
git::validation::positions::Error::UserIntervention(_)
|
2024-06-09 10:21:09 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn where_next_branch_is_not_based_on_main_should_reset_next_branch_to_main_and_then_error()
|
|
|
|
{
|
|
|
|
//given
|
|
|
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
2024-07-06 14:25:43 +01:00
|
|
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
2024-09-05 09:41:17 +01:00
|
|
|
let forge_details = given::forge_details();
|
|
|
|
let mut test_repository = git::repository::test(fs.clone(), forge_details);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_config = given::a_repo_config();
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_fetch(OnFetch::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|branches, gitdir, fs| {
|
|
|
|
// /--- 4 dev
|
|
|
|
// 0 --- 1 --- 3 main
|
|
|
|
// \--- 2 next
|
|
|
|
// add a commit to main (0 -> 1)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.main())?;
|
|
|
|
// add a commit to next (1 -> 2)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.next())?;
|
|
|
|
// switch back to main (1)
|
|
|
|
then::git_switch(&branches.main(), gitdir)?;
|
|
|
|
// add a second commit to main (1 -> 3)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.main())?;
|
|
|
|
// add a commit to dev (3 -> 4)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.dev())?;
|
|
|
|
|
|
|
|
then::git_log_all(gitdir)?;
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
|
|
|
// second fetch as prep to push
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_fetch(OnFetch::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|_branches, _gitdir, _fs| {
|
|
|
|
// don't change anything
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_push(OnPush::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|_repo_details, branch_name, gitref, force, repo_branches, gitdir, fs| {
|
|
|
|
assert_eq!(
|
|
|
|
branch_name,
|
|
|
|
&repo_branches.next(),
|
|
|
|
"branch to reset should be 'next'"
|
|
|
|
);
|
|
|
|
let sha_main = then::get_sha_for_branch(fs, gitdir, &repo_branches.main())?;
|
|
|
|
assert_eq!(
|
|
|
|
gitref,
|
|
|
|
&git::GitRef::from(sha_main),
|
|
|
|
"should reset to the sha of the 'main' branch"
|
|
|
|
);
|
|
|
|
let sha_next = then::get_sha_for_branch(fs, gitdir, &repo_branches.next())?;
|
|
|
|
assert_eq!(
|
|
|
|
force,
|
|
|
|
&git::push::Force::From(sha_next.into()),
|
|
|
|
"should force push only if next is on expected sha"
|
|
|
|
);
|
|
|
|
git::push::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
2024-06-19 16:40:10 +01:00
|
|
|
let_assert!(
|
|
|
|
Ok(open_repository) = test_repository.open(&gitdir),
|
|
|
|
"open repo"
|
|
|
|
);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_details = given::repo_details(&fs).with_gitdir(gitdir);
|
|
|
|
|
|
|
|
//when
|
|
|
|
let_assert!(
|
2024-08-30 07:49:43 +01:00
|
|
|
Err(err) = validate(&*open_repository, &repo_details, &repo_config),
|
2024-06-09 10:21:09 +01:00
|
|
|
"validate"
|
|
|
|
);
|
|
|
|
|
|
|
|
//then
|
2024-06-20 18:54:01 +01:00
|
|
|
println!("Got: {err:?}");
|
2024-06-09 10:21:09 +01:00
|
|
|
// NOTE: assertions for correct push are in on_push above
|
|
|
|
assert!(matches!(
|
|
|
|
err,
|
2024-06-30 18:39:43 +01:00
|
|
|
git::validation::positions::Error::Retryable(_)
|
2024-06-09 10:21:09 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn where_next_branch_is_not_based_on_main_and_reset_of_next_fails_should_error() {
|
|
|
|
//given
|
|
|
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
2024-07-06 14:25:43 +01:00
|
|
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
2024-09-05 09:41:17 +01:00
|
|
|
let forge_details = given::forge_details();
|
|
|
|
let mut test_repository = git::repository::test(fs.clone(), forge_details);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_config = given::a_repo_config();
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_fetch(OnFetch::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|branches, gitdir, fs| {
|
|
|
|
// /--- 4 dev
|
|
|
|
// 0 --- 1 --- 3 main
|
|
|
|
// \--- 2 next
|
|
|
|
// add a commit to main (0 -> 1)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.main())?;
|
|
|
|
// add a commit to next (1 -> 2)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.next())?;
|
|
|
|
// switch back to main (1)
|
|
|
|
then::git_switch(&branches.main(), gitdir)?;
|
|
|
|
// add a second commit to main (1 -> 3)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.main())?;
|
|
|
|
// add a commit to dev (3 -> 4)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.dev())?;
|
|
|
|
|
|
|
|
then::git_log_all(gitdir)?;
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
|
|
|
// second fetch as prep to push
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_fetch(OnFetch::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|_branches, _gitdir, _fs| {
|
|
|
|
// don't change anything
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_push(OnPush::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|_repo_details, _branch_name, _gitref, _force, _repo_branches, _gitdir, _fs| {
|
|
|
|
git::push::Result::Err(git::push::Error::Lock)
|
|
|
|
},
|
|
|
|
));
|
2024-06-19 16:40:10 +01:00
|
|
|
let_assert!(
|
|
|
|
Ok(open_repository) = test_repository.open(&gitdir),
|
|
|
|
"open repo"
|
|
|
|
);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_details = given::repo_details(&fs).with_gitdir(gitdir.clone());
|
|
|
|
|
|
|
|
//when
|
|
|
|
let_assert!(
|
2024-08-30 07:49:43 +01:00
|
|
|
Err(err) = validate(&*open_repository, &repo_details, &repo_config),
|
2024-06-09 10:21:09 +01:00
|
|
|
"validate"
|
|
|
|
);
|
|
|
|
|
|
|
|
//then
|
2024-06-20 18:54:01 +01:00
|
|
|
println!("Got: {err:?}");
|
2024-06-09 10:21:09 +01:00
|
|
|
let_assert!(
|
2024-06-30 18:39:43 +01:00
|
|
|
Ok(_) = then::get_sha_for_branch(&fs, &gitdir, &repo_config.branches().next()),
|
2024-06-09 10:21:09 +01:00
|
|
|
"load next branch sha"
|
|
|
|
);
|
|
|
|
assert!(matches!(
|
|
|
|
err,
|
2024-06-30 18:39:43 +01:00
|
|
|
git::validation::positions::Error::NonRetryable(_)
|
2024-06-09 10:21:09 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
#[test]
|
2024-07-28 18:50:27 +01:00
|
|
|
#[allow(clippy::expect_used)]
|
|
|
|
fn where_dev_branch_is_on_main_and_next_is_not_should_reset_next_branch_to_main_and_retryable_error(
|
|
|
|
) {
|
2024-06-09 10:21:09 +01:00
|
|
|
//given
|
|
|
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
2024-07-06 14:25:43 +01:00
|
|
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
2024-09-05 09:41:17 +01:00
|
|
|
let forge_details = given::forge_details();
|
|
|
|
let mut test_repository = git::repository::test(fs.clone(), forge_details);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_config = given::a_repo_config();
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_fetch(OnFetch::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|branches, gitdir, fs| {
|
|
|
|
// /--- 3 next
|
2024-07-28 18:50:27 +01:00
|
|
|
// 0 --- 1 main & dev
|
2024-06-09 10:21:09 +01:00
|
|
|
// add a commit to main (0 -> 1)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.main())?;
|
2024-07-28 18:50:27 +01:00
|
|
|
// create dev branch on main (1)
|
|
|
|
then::git_switch(&branches.dev(), gitdir)?;
|
2024-06-09 10:21:09 +01:00
|
|
|
// switch back to main (1)
|
|
|
|
then::git_switch(&branches.main(), gitdir)?;
|
|
|
|
// add a commit to next (1 -> 3)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.next())?;
|
|
|
|
|
|
|
|
then::git_log_all(gitdir)?;
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
|
|
|
// second fetch as prep to push
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_fetch(OnFetch::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|_branches, _gitdir, _fs| {
|
|
|
|
// don't change anything
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_push(OnPush::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|_repo_details, branch_name, gitref, force, repo_branches, gitdir, fs| {
|
|
|
|
assert_eq!(
|
|
|
|
branch_name,
|
|
|
|
&repo_branches.next(),
|
|
|
|
"branch to reset should be 'next'"
|
|
|
|
);
|
|
|
|
let sha_main = then::get_sha_for_branch(fs, gitdir, &repo_branches.main())?;
|
|
|
|
assert_eq!(
|
|
|
|
gitref,
|
|
|
|
&git::GitRef::from(sha_main),
|
|
|
|
"should reset to the sha of the 'main' branch"
|
|
|
|
);
|
|
|
|
let sha_next = then::get_sha_for_branch(fs, gitdir, &repo_branches.next())?;
|
|
|
|
assert_eq!(
|
|
|
|
force,
|
|
|
|
&git::push::Force::From(sha_next.into()),
|
|
|
|
"should force push only if next is on expected sha"
|
|
|
|
);
|
|
|
|
git::push::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
2024-06-19 16:40:10 +01:00
|
|
|
let_assert!(
|
|
|
|
Ok(open_repository) = test_repository.open(&gitdir),
|
|
|
|
"open repo"
|
|
|
|
);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_details = given::repo_details(&fs).with_gitdir(gitdir);
|
|
|
|
|
|
|
|
//when
|
|
|
|
let_assert!(
|
2024-08-30 07:49:43 +01:00
|
|
|
Err(err) = validate(&*open_repository, &repo_details, &repo_config),
|
2024-06-09 10:21:09 +01:00
|
|
|
"validate"
|
|
|
|
);
|
|
|
|
|
|
|
|
//then
|
2024-06-20 18:54:01 +01:00
|
|
|
println!("Got: {err:?}");
|
2024-06-09 10:21:09 +01:00
|
|
|
// NOTE: assertions for correct push are in on_push above
|
|
|
|
assert!(matches!(
|
|
|
|
err,
|
2024-06-30 18:39:43 +01:00
|
|
|
git::validation::positions::Error::Retryable(_)
|
2024-06-09 10:21:09 +01:00
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
2024-07-28 18:50:27 +01:00
|
|
|
#[allow(clippy::expect_used)]
|
|
|
|
fn where_dev_branch_is_not_based_on_next_should_reset_next_branch_to_next_commit_on_dev_and_retryable_error(
|
|
|
|
) {
|
2024-06-09 10:21:09 +01:00
|
|
|
//given
|
|
|
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
2024-07-06 14:25:43 +01:00
|
|
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
2024-09-05 09:41:17 +01:00
|
|
|
let forge_details = given::forge_details();
|
|
|
|
let mut test_repository = git::repository::test(fs.clone(), forge_details);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_config = given::a_repo_config();
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_fetch(OnFetch::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|branches, gitdir, fs| {
|
|
|
|
// /--- 3 next
|
|
|
|
// 0 --- 1 main
|
|
|
|
// \--- 2 dev
|
|
|
|
// add a commit to main (0 -> 1)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.main())?;
|
|
|
|
// add a commit to dev (1 -> 2)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.dev())?;
|
|
|
|
// switch back to main (1)
|
|
|
|
then::git_switch(&branches.main(), gitdir)?;
|
|
|
|
// add a commit to next (1 -> 3)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.next())?;
|
|
|
|
|
|
|
|
then::git_log_all(gitdir)?;
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
|
|
|
// second fetch as prep to push
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_fetch(OnFetch::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|_branches, _gitdir, _fs| {
|
|
|
|
// don't change anything
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_push(OnPush::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
2024-07-28 18:50:27 +01:00
|
|
|
|_repo_details, branch_name, gitref, force, repo_branches, gitdir, fs| {
|
|
|
|
assert_eq!(
|
|
|
|
branch_name,
|
|
|
|
&repo_branches.next(),
|
|
|
|
"branch to reset should be 'next'"
|
|
|
|
);
|
|
|
|
let sha_dev = then::get_sha_for_branch(fs, gitdir, &repo_branches.dev())?;
|
|
|
|
assert_eq!(
|
|
|
|
gitref,
|
|
|
|
&git::GitRef::from(sha_dev),
|
|
|
|
"should reset to the sha of the next commit on 'dev' branch"
|
|
|
|
);
|
|
|
|
let sha_next = then::get_sha_for_branch(fs, gitdir, &repo_branches.next())?;
|
|
|
|
assert_eq!(
|
|
|
|
force,
|
|
|
|
&git::push::Force::From(sha_next.into()),
|
|
|
|
"should force push only if next is on expected sha"
|
|
|
|
);
|
|
|
|
git::push::Result::Ok(())
|
2024-06-09 10:21:09 +01:00
|
|
|
},
|
|
|
|
));
|
2024-06-19 16:40:10 +01:00
|
|
|
let_assert!(
|
|
|
|
Ok(open_repository) = test_repository.open(&gitdir),
|
|
|
|
"open repo"
|
|
|
|
);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_details = given::repo_details(&fs).with_gitdir(gitdir.clone());
|
|
|
|
|
|
|
|
//when
|
|
|
|
let_assert!(
|
2024-08-30 07:49:43 +01:00
|
|
|
Ok((positions, _git_log)) =
|
|
|
|
validate(&*open_repository, &repo_details, &repo_config),
|
2024-06-09 10:21:09 +01:00
|
|
|
"validate"
|
|
|
|
);
|
|
|
|
|
|
|
|
//then
|
2024-07-28 18:50:27 +01:00
|
|
|
println!("positions: {positions:#?}");
|
|
|
|
|
2024-06-09 10:21:09 +01:00
|
|
|
let_assert!(
|
2024-07-28 18:50:27 +01:00
|
|
|
Ok(main_sha) =
|
|
|
|
then::get_sha_for_branch(&fs, &gitdir, &repo_config.branches().main())
|
2024-06-09 10:21:09 +01:00
|
|
|
);
|
2024-07-28 18:50:27 +01:00
|
|
|
assert_eq!(positions.main.sha(), &main_sha);
|
|
|
|
|
|
|
|
let_assert!(
|
|
|
|
Ok(next_sha) =
|
|
|
|
then::get_sha_for_branch(&fs, &gitdir, &repo_config.branches().next())
|
|
|
|
);
|
|
|
|
assert_eq!(positions.next.sha(), &next_sha);
|
|
|
|
|
|
|
|
let_assert!(
|
|
|
|
Ok(dev_sha) = then::get_sha_for_branch(&fs, &gitdir, &repo_config.branches().dev())
|
|
|
|
);
|
|
|
|
assert_eq!(positions.dev.sha(), &dev_sha);
|
2024-06-09 10:21:09 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn where_branches_are_all_valid_should_return_positions() {
|
|
|
|
//given
|
|
|
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
2024-07-06 14:25:43 +01:00
|
|
|
let gitdir = GitDir::new(fs.base().to_path_buf(), StoragePathType::Internal);
|
2024-09-05 09:41:17 +01:00
|
|
|
let forge_details = given::forge_details();
|
|
|
|
let mut test_repository = git::repository::test(fs.clone(), forge_details);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_config = given::a_repo_config();
|
2024-07-25 09:02:43 +01:00
|
|
|
test_repository.on_fetch(OnFetch::new(
|
2024-06-09 10:21:09 +01:00
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|branches, gitdir, fs| {
|
|
|
|
// 0 --- 1 main
|
|
|
|
// \--- 2 next
|
|
|
|
// \--- dev
|
|
|
|
// add a commit to main (0 -> 1)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.main())?;
|
|
|
|
// add a commit to next (1 -> 2)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.next())?;
|
|
|
|
// add a commit to dev (2 -> 3)
|
|
|
|
then::create_a_commit_on_branch(fs, gitdir, &branches.dev())?;
|
|
|
|
|
|
|
|
then::git_log_all(gitdir)?;
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
2024-06-19 16:40:10 +01:00
|
|
|
let_assert!(
|
|
|
|
Ok(open_repository) = test_repository.open(&gitdir),
|
|
|
|
"open repo"
|
|
|
|
);
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_details = given::repo_details(&fs).with_gitdir(gitdir.clone());
|
|
|
|
|
|
|
|
//when
|
|
|
|
let_assert!(
|
2024-08-30 07:49:43 +01:00
|
|
|
Ok((positions, _git_log)) =
|
|
|
|
validate(&*open_repository, &repo_details, &repo_config),
|
2024-06-09 10:21:09 +01:00
|
|
|
"validate"
|
|
|
|
);
|
|
|
|
|
|
|
|
//then
|
2024-06-20 18:54:01 +01:00
|
|
|
println!("positions: {positions:#?}");
|
2024-06-09 10:21:09 +01:00
|
|
|
|
|
|
|
let_assert!(
|
|
|
|
Ok(main_sha) =
|
|
|
|
then::get_sha_for_branch(&fs, &gitdir, &repo_config.branches().main())
|
|
|
|
);
|
|
|
|
assert_eq!(positions.main.sha(), &main_sha);
|
|
|
|
|
|
|
|
let_assert!(
|
|
|
|
Ok(next_sha) =
|
|
|
|
then::get_sha_for_branch(&fs, &gitdir, &repo_config.branches().next())
|
|
|
|
);
|
|
|
|
assert_eq!(positions.next.sha(), &next_sha);
|
|
|
|
|
|
|
|
let_assert!(
|
|
|
|
Ok(dev_sha) = then::get_sha_for_branch(&fs, &gitdir, &repo_config.branches().dev())
|
|
|
|
);
|
|
|
|
assert_eq!(positions.dev.sha(), &dev_sha);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|