2024-05-26 08:35:45 +01:00
|
|
|
//
|
2024-07-28 08:58:32 +01:00
|
|
|
use crate::repo::messages::MessageToken;
|
|
|
|
|
2024-07-26 06:49:09 +01:00
|
|
|
use git_next_core::{
|
2024-07-28 08:58:32 +01:00
|
|
|
git::{
|
|
|
|
commit::Message,
|
|
|
|
push::{reset, Force},
|
|
|
|
repository::open::OpenRepositoryLike,
|
2024-07-28 18:50:27 +01:00
|
|
|
Commit, GitRef, RepoDetails,
|
2024-07-28 08:58:32 +01:00
|
|
|
},
|
2024-07-26 06:49:09 +01:00
|
|
|
RepoConfig,
|
|
|
|
};
|
2024-04-09 18:18:19 +01:00
|
|
|
|
2024-06-19 07:03:08 +01:00
|
|
|
use derive_more::Display;
|
2024-07-28 08:58:32 +01:00
|
|
|
use tracing::{info, instrument, warn};
|
2024-05-26 08:35:45 +01:00
|
|
|
|
2024-04-09 22:43:23 +01:00
|
|
|
// advance next to the next commit towards the head of the dev branch
|
2024-07-28 08:58:32 +01:00
|
|
|
#[instrument(fields(next), skip_all)]
|
2024-06-19 07:03:08 +01:00
|
|
|
pub fn advance_next(
|
2024-08-12 21:25:24 +01:00
|
|
|
commit: Option<Commit>,
|
|
|
|
force: git_next_core::git::push::Force,
|
2024-07-28 08:58:32 +01:00
|
|
|
repo_details: RepoDetails,
|
2024-07-25 09:02:43 +01:00
|
|
|
repo_config: RepoConfig,
|
|
|
|
open_repository: &dyn OpenRepositoryLike,
|
2024-05-23 08:30:58 +01:00
|
|
|
message_token: MessageToken,
|
2024-06-19 07:03:08 +01:00
|
|
|
) -> Result<MessageToken> {
|
2024-07-28 18:50:27 +01:00
|
|
|
let commit = commit.ok_or_else(|| Error::NextAtDev)?;
|
2024-06-19 07:03:08 +01:00
|
|
|
validate_commit_message(commit.message())?;
|
2024-04-12 17:41:09 +01:00
|
|
|
info!("Advancing next to commit '{}'", commit);
|
2024-07-28 08:58:32 +01:00
|
|
|
reset(
|
2024-06-19 16:40:10 +01:00
|
|
|
open_repository,
|
2024-05-26 08:35:45 +01:00
|
|
|
&repo_details,
|
2024-06-08 21:13:31 +01:00
|
|
|
&repo_config.branches().next(),
|
|
|
|
&commit.into(),
|
2024-07-28 18:50:27 +01:00
|
|
|
&force,
|
2024-06-19 07:03:08 +01:00
|
|
|
)?;
|
|
|
|
Ok(message_token)
|
2024-04-10 15:18:48 +01:00
|
|
|
}
|
|
|
|
|
2024-07-28 08:58:32 +01:00
|
|
|
#[instrument]
|
|
|
|
fn validate_commit_message(message: &Message) -> Result<()> {
|
2024-04-12 16:21:45 +01:00
|
|
|
let message = &message.to_string();
|
|
|
|
if message.to_ascii_lowercase().starts_with("wip") {
|
2024-06-19 07:03:08 +01:00
|
|
|
return Err(Error::IsWorkInProgress);
|
2024-04-12 16:21:45 +01:00
|
|
|
}
|
2024-07-28 08:58:32 +01:00
|
|
|
match ::git_conventional::Commit::parse(message) {
|
2024-04-12 16:21:45 +01:00
|
|
|
Ok(commit) => {
|
|
|
|
info!(?commit, "Pass");
|
2024-06-19 07:03:08 +01:00
|
|
|
Ok(())
|
2024-04-12 16:21:45 +01:00
|
|
|
}
|
|
|
|
Err(err) => {
|
|
|
|
warn!(?err, "Fail");
|
2024-06-19 07:03:08 +01:00
|
|
|
Err(Error::InvalidCommitMessage {
|
|
|
|
reason: err.kind().to_string(),
|
|
|
|
})
|
2024-04-12 16:21:45 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-07-28 18:50:27 +01:00
|
|
|
pub fn find_next_commit_on_dev(
|
|
|
|
next: &Commit,
|
|
|
|
main: &Commit,
|
|
|
|
dev_commit_history: &[Commit],
|
|
|
|
) -> (Option<Commit>, Force) {
|
2024-07-28 08:58:32 +01:00
|
|
|
let mut next_commit: Option<&Commit> = None;
|
2024-07-28 18:50:27 +01:00
|
|
|
let mut force = Force::No;
|
2024-08-05 07:39:38 +01:00
|
|
|
for commit in dev_commit_history {
|
2024-04-10 15:18:48 +01:00
|
|
|
if commit == next {
|
|
|
|
break;
|
|
|
|
};
|
2024-07-28 18:50:27 +01:00
|
|
|
if commit == main {
|
|
|
|
force = Force::From(GitRef::from(next.sha().clone()));
|
|
|
|
break;
|
|
|
|
};
|
2024-04-10 15:18:48 +01:00
|
|
|
next_commit.replace(commit);
|
|
|
|
}
|
2024-07-28 18:50:27 +01:00
|
|
|
(next_commit.cloned(), force)
|
2024-04-09 22:43:23 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
// advance main branch to the commit 'next'
|
2024-07-28 08:58:32 +01:00
|
|
|
#[instrument(fields(next), skip_all)]
|
2024-06-19 07:03:08 +01:00
|
|
|
pub fn advance_main(
|
2024-07-28 08:58:32 +01:00
|
|
|
next: Commit,
|
|
|
|
repo_details: &RepoDetails,
|
2024-07-25 09:02:43 +01:00
|
|
|
repo_config: &RepoConfig,
|
|
|
|
open_repository: &dyn OpenRepositoryLike,
|
2024-06-19 07:03:08 +01:00
|
|
|
) -> Result<()> {
|
2024-04-12 17:41:09 +01:00
|
|
|
info!("Advancing main to next");
|
2024-07-28 08:58:32 +01:00
|
|
|
reset(
|
2024-06-19 16:40:10 +01:00
|
|
|
open_repository,
|
2024-05-26 08:35:45 +01:00
|
|
|
repo_details,
|
2024-06-08 21:13:31 +01:00
|
|
|
&repo_config.branches().main(),
|
|
|
|
&next.into(),
|
2024-07-28 08:58:32 +01:00
|
|
|
&Force::No,
|
2024-06-19 07:03:08 +01:00
|
|
|
)?;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
2024-07-28 08:58:32 +01:00
|
|
|
pub type Result<T> = std::result::Result<T, Error>;
|
|
|
|
|
2024-06-19 07:03:08 +01:00
|
|
|
#[derive(Debug, thiserror::Error, Display)]
|
|
|
|
pub enum Error {
|
|
|
|
#[display("push: {}", 0)]
|
2024-07-28 08:58:32 +01:00
|
|
|
Push(#[from] crate::git::push::Error),
|
2024-06-19 07:03:08 +01:00
|
|
|
|
|
|
|
#[display("no commits to advance next to")]
|
|
|
|
NextAtDev,
|
|
|
|
|
|
|
|
#[display("commit is a Work-in-progress")]
|
|
|
|
IsWorkInProgress,
|
|
|
|
|
|
|
|
#[display("commit message is not in conventional commit format: {reason}")]
|
|
|
|
InvalidCommitMessage { reason: String },
|
2024-04-09 19:30:05 +01:00
|
|
|
}
|