2024-06-09 10:21:09 +01:00
|
|
|
//
|
|
|
|
use crate as git;
|
|
|
|
|
2024-06-19 16:40:10 +01:00
|
|
|
use git::repository::RepositoryFactory as _;
|
|
|
|
use git::repository::RepositoryLike as _;
|
2024-06-09 10:21:09 +01:00
|
|
|
use git::tests::given;
|
|
|
|
use git_next_config as config;
|
|
|
|
|
|
|
|
use assert2::let_assert;
|
|
|
|
|
|
|
|
mod repos {
|
2024-06-19 16:40:10 +01:00
|
|
|
|
|
|
|
use crate::repository::Direction;
|
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");
|
|
|
|
let gitdir: config::GitDir = fs.base().to_path_buf().into();
|
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);
|
|
|
|
let mut repository_factory = git::repository::mock();
|
|
|
|
repository_factory
|
|
|
|
.expect_open()
|
|
|
|
.return_once(move |_| Ok(mock_open_repository));
|
2024-06-09 10:21:09 +01:00
|
|
|
let repo_details = given::repo_details(&fs);
|
2024-06-19 16:40:10 +01:00
|
|
|
let_assert!(
|
|
|
|
Ok(open_repository) = repository_factory.open(&gitdir),
|
|
|
|
"open repo"
|
|
|
|
);
|
|
|
|
|
|
|
|
let result = git::validation::repo::validate_repo(&*open_repository, &repo_details);
|
|
|
|
print!("{result:?}");
|
|
|
|
let_assert!(Err(err) = result);
|
2024-06-09 10:21:09 +01:00
|
|
|
assert!(matches!(
|
|
|
|
err,
|
|
|
|
git::validation::repo::Error::NoDefaultPushRemote
|
|
|
|
));
|
|
|
|
}
|
|
|
|
}
|
2024-06-19 16:40:10 +01:00
|
|
|
|
2024-06-09 10:21:09 +01:00
|
|
|
mod positions {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
mod validate_positions {
|
|
|
|
|
|
|
|
use git::validation::positions::validate_positions;
|
|
|
|
|
|
|
|
use git::tests::then;
|
|
|
|
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn where_fetch_fails_should_error() {
|
2024-06-19 16:40:10 +01:00
|
|
|
let fs = given::a_filesystem();
|
2024-06-09 10:21:09 +01:00
|
|
|
let gitdir: config::GitDir = fs.base().to_path_buf().into();
|
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));
|
|
|
|
let mut repository_factory = git::repository::mock();
|
|
|
|
repository_factory
|
|
|
|
.expect_open()
|
|
|
|
.return_once(move |_| Ok(mock_open_repository));
|
2024-06-09 10:21:09 +01:00
|
|
|
let_assert!(
|
2024-06-19 16:40:10 +01:00
|
|
|
Ok(repository) = repository_factory.open(&gitdir),
|
|
|
|
"open repo"
|
2024-06-09 10:21:09 +01:00
|
|
|
);
|
2024-06-19 16:40:10 +01:00
|
|
|
let repo_details = given::repo_details(&fs); //.with_gitdir(gitdir);
|
|
|
|
let repo_config = given::a_repo_config();
|
|
|
|
|
|
|
|
let result = validate_positions(&*repository, &repo_details, repo_config);
|
|
|
|
println!("{result:?}");
|
|
|
|
let_assert!(Err(err) = result, "validate");
|
2024-06-09 10:21:09 +01:00
|
|
|
|
|
|
|
assert!(matches!(
|
|
|
|
err,
|
|
|
|
git::validation::positions::Error::Fetch(git::fetch::Error::TestFailureExpected)
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[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-06-09 10:21:09 +01:00
|
|
|
let gitdir: config::GitDir = fs.base().to_path_buf().into();
|
|
|
|
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![])
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let mut repository_factory = git::repository::mock();
|
|
|
|
repository_factory
|
|
|
|
.expect_open()
|
|
|
|
.return_once(move |_| Ok(mock_open_repository));
|
2024-06-09 10:21:09 +01:00
|
|
|
let_assert!(
|
2024-06-19 16:40:10 +01:00
|
|
|
Ok(open_repository) = repository_factory.open(&gitdir),
|
|
|
|
"open repo"
|
2024-06-09 10:21:09 +01:00
|
|
|
);
|
2024-06-19 16:40:10 +01:00
|
|
|
let repo_details = given::repo_details(&fs);
|
|
|
|
let main_branch = repo_config.branches().main();
|
|
|
|
|
|
|
|
let result = validate_positions(&*open_repository, &repo_details, repo_config);
|
|
|
|
println!("{result:?}");
|
|
|
|
|
2024-06-09 10:21:09 +01:00
|
|
|
assert!(matches!(
|
2024-06-19 16:40:10 +01:00
|
|
|
result,
|
|
|
|
Err(git::validation::positions::Error::CommitLog(git::commit::log::Error::Gix {
|
2024-06-09 10:21:09 +01:00
|
|
|
branch,
|
|
|
|
error
|
2024-06-19 16:40:10 +01:00
|
|
|
})) if branch == main_branch && error == "foo"
|
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-06-09 10:21:09 +01:00
|
|
|
let gitdir: config::GitDir = fs.base().to_path_buf().into();
|
|
|
|
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()])
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let mut repository_factory = git::repository::mock();
|
|
|
|
repository_factory
|
|
|
|
.expect_open()
|
|
|
|
.return_once(move |_| Ok(mock_open_repository));
|
2024-06-09 10:21:09 +01:00
|
|
|
let_assert!(
|
2024-06-19 16:40:10 +01:00
|
|
|
Ok(open_repository) = repository_factory.open(&gitdir),
|
|
|
|
"open repo"
|
2024-06-09 10:21:09 +01:00
|
|
|
);
|
2024-06-19 16:40:10 +01:00
|
|
|
let repo_details = given::repo_details(&fs);
|
|
|
|
let next_branch = repo_config.branches().next();
|
|
|
|
|
|
|
|
let result = validate_positions(&*open_repository, &repo_details, repo_config);
|
|
|
|
println!("{result:?}");
|
2024-06-09 10:21:09 +01:00
|
|
|
|
|
|
|
assert!(matches!(
|
2024-06-19 16:40:10 +01:00
|
|
|
result,
|
|
|
|
Err(git::validation::positions::Error::CommitLog(git::commit::log::Error::Gix {
|
2024-06-09 10:21:09 +01:00
|
|
|
branch,
|
|
|
|
error
|
2024-06-19 16:40:10 +01:00
|
|
|
})) if branch == next_branch && error == "foo"
|
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-06-09 10:21:09 +01:00
|
|
|
let gitdir: config::GitDir = fs.base().to_path_buf().into();
|
|
|
|
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()])
|
|
|
|
}
|
|
|
|
});
|
|
|
|
let mut repository_factory = git::repository::mock();
|
|
|
|
repository_factory
|
|
|
|
.expect_open()
|
|
|
|
.return_once(move |_| Ok(mock_open_repository));
|
2024-06-09 10:21:09 +01:00
|
|
|
let_assert!(
|
2024-06-19 16:40:10 +01:00
|
|
|
Ok(open_repository) = repository_factory.open(&gitdir),
|
|
|
|
"open repo"
|
2024-06-09 10:21:09 +01:00
|
|
|
);
|
2024-06-19 16:40:10 +01:00
|
|
|
let repo_details = given::repo_details(&fs);
|
|
|
|
let dev_branch = repo_config.branches().dev();
|
|
|
|
|
|
|
|
let result = validate_positions(&*open_repository, &repo_details, repo_config);
|
|
|
|
println!("{result:?}");
|
2024-06-09 10:21:09 +01:00
|
|
|
|
|
|
|
assert!(matches!(
|
2024-06-19 16:40:10 +01:00
|
|
|
result,
|
|
|
|
Err(git::validation::positions::Error::CommitLog(git::commit::log::Error::Gix {
|
2024-06-09 10:21:09 +01:00
|
|
|
branch,
|
|
|
|
error
|
2024-06-19 16:40:10 +01:00
|
|
|
})) if branch == dev_branch && error == "foo"
|
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-06-09 10:21:09 +01:00
|
|
|
let gitdir: config::GitDir = fs.base().to_path_buf().into();
|
|
|
|
let mut test_repository = git::repository::test(fs.clone());
|
|
|
|
let repo_config = given::a_repo_config();
|
|
|
|
test_repository.on_fetch(git::repository::OnFetch::new(
|
|
|
|
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-06-19 16:40:10 +01:00
|
|
|
Err(err) =
|
|
|
|
validate_positions(&*open_repository, &repo_details, repo_config.clone()),
|
2024-06-09 10:21:09 +01:00
|
|
|
"validate"
|
|
|
|
);
|
|
|
|
|
|
|
|
//then
|
|
|
|
assert!(matches!(
|
|
|
|
err,
|
|
|
|
git::validation::positions::Error::DevBranchNotBasedOn { dev, other }
|
|
|
|
if dev == repo_config.branches().dev() && other == repo_config.branches().main()
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[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");
|
|
|
|
let gitdir: config::GitDir = fs.base().to_path_buf().into();
|
|
|
|
let mut test_repository = git::repository::test(fs.clone());
|
|
|
|
let repo_config = given::a_repo_config();
|
|
|
|
test_repository.on_fetch(git::repository::OnFetch::new(
|
|
|
|
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
|
|
|
|
test_repository.on_fetch(git::repository::OnFetch::new(
|
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|_branches, _gitdir, _fs| {
|
|
|
|
// don't change anything
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
|
|
|
test_repository.on_push(git::repository::OnPush::new(
|
|
|
|
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-06-19 16:40:10 +01:00
|
|
|
Err(err) =
|
|
|
|
validate_positions(&*open_repository, &repo_details, repo_config.clone()),
|
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,
|
|
|
|
git::validation::positions::Error::NextBranchResetRequired(branch)
|
|
|
|
if branch == repo_config.branches().next()
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[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");
|
|
|
|
let gitdir: config::GitDir = fs.base().to_path_buf().into();
|
|
|
|
let mut test_repository = git::repository::test(fs.clone());
|
|
|
|
let repo_config = given::a_repo_config();
|
|
|
|
test_repository.on_fetch(git::repository::OnFetch::new(
|
|
|
|
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
|
|
|
|
test_repository.on_fetch(git::repository::OnFetch::new(
|
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|_branches, _gitdir, _fs| {
|
|
|
|
// don't change anything
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
|
|
|
test_repository.on_push(git::repository::OnPush::new(
|
|
|
|
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-06-19 16:40:10 +01:00
|
|
|
Err(err) =
|
|
|
|
validate_positions(&*open_repository, &repo_details, repo_config.clone()),
|
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!(
|
|
|
|
Ok(sha_next) =
|
|
|
|
then::get_sha_for_branch(&fs, &gitdir, &repo_config.branches().next()),
|
|
|
|
"load next branch sha"
|
|
|
|
);
|
|
|
|
assert!(matches!(
|
|
|
|
err,
|
|
|
|
git::validation::positions::Error::FailedToResetBranch{branch, commit}
|
|
|
|
if branch == repo_config.branches().next() && commit.sha() == &sha_next
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn where_dev_branch_is_not_based_on_next_should_reset_next_branch_to_main_and_then_error() {
|
|
|
|
//given
|
|
|
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
|
|
|
let gitdir: config::GitDir = fs.base().to_path_buf().into();
|
|
|
|
let mut test_repository = git::repository::test(fs.clone());
|
|
|
|
let repo_config = given::a_repo_config();
|
|
|
|
test_repository.on_fetch(git::repository::OnFetch::new(
|
|
|
|
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
|
|
|
|
test_repository.on_fetch(git::repository::OnFetch::new(
|
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|_branches, _gitdir, _fs| {
|
|
|
|
// don't change anything
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
|
|
|
test_repository.on_push(git::repository::OnPush::new(
|
|
|
|
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-06-19 16:40:10 +01:00
|
|
|
Err(err) =
|
|
|
|
validate_positions(&*open_repository, &repo_details, repo_config.clone()),
|
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,
|
|
|
|
git::validation::positions::Error::NextBranchResetRequired(branch)
|
|
|
|
if branch == repo_config.branches().next()
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn where_dev_branch_is_not_based_on_next_and_reset_of_next_fails_should_error() {
|
|
|
|
//given
|
|
|
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
|
|
|
let gitdir: config::GitDir = fs.base().to_path_buf().into();
|
|
|
|
let mut test_repository = git::repository::test(fs.clone());
|
|
|
|
let repo_config = given::a_repo_config();
|
|
|
|
test_repository.on_fetch(git::repository::OnFetch::new(
|
|
|
|
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
|
|
|
|
test_repository.on_fetch(git::repository::OnFetch::new(
|
|
|
|
repo_config.branches().clone(),
|
|
|
|
gitdir.clone(),
|
|
|
|
fs.clone(),
|
|
|
|
|_branches, _gitdir, _fs| {
|
|
|
|
// don't change anything
|
|
|
|
git::fetch::Result::Ok(())
|
|
|
|
},
|
|
|
|
));
|
|
|
|
test_repository.on_push(git::repository::OnPush::new(
|
|
|
|
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-06-19 16:40:10 +01:00
|
|
|
Err(err) =
|
|
|
|
validate_positions(&*open_repository, &repo_details, repo_config.clone()),
|
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!(
|
|
|
|
Ok(sha_next) =
|
|
|
|
then::get_sha_for_branch(&fs, &gitdir, &repo_config.branches().next()),
|
|
|
|
"load next branch sha"
|
|
|
|
);
|
|
|
|
assert!(matches!(
|
|
|
|
err,
|
|
|
|
git::validation::positions::Error::FailedToResetBranch{branch, commit}
|
|
|
|
if branch == repo_config.branches().next() && commit.sha() == &sha_next
|
|
|
|
));
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn where_branches_are_all_valid_should_return_positions() {
|
|
|
|
//given
|
|
|
|
let_assert!(Ok(fs) = kxio::fs::temp(), "temp fs");
|
|
|
|
let gitdir: config::GitDir = fs.base().to_path_buf().into();
|
|
|
|
let mut test_repository = git::repository::test(fs.clone());
|
|
|
|
let repo_config = given::a_repo_config();
|
|
|
|
test_repository.on_fetch(git::repository::OnFetch::new(
|
|
|
|
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-06-19 16:40:10 +01:00
|
|
|
Ok(positions) =
|
|
|
|
validate_positions(&*open_repository, &repo_details, repo_config.clone()),
|
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);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|