// use crate::repo::messages::MessageToken; use git_next_core::{ git::{ commit::Message, push::{reset, Force}, repository::open::OpenRepositoryLike, Commit, GitRef, RepoDetails, }, RepoConfig, }; use derive_more::Display; use tracing::{info, instrument, warn}; // advance next to the next commit towards the head of the dev branch #[instrument(fields(next), skip_all)] pub fn advance_next( commit: Option, force: git_next_core::git::push::Force, repo_details: &RepoDetails, repo_config: &RepoConfig, open_repository: &dyn OpenRepositoryLike, message_token: MessageToken, ) -> Result { let commit = commit.ok_or_else(|| Error::NextAtDev)?; validate_commit_message(commit.message())?; info!("Advancing next to commit '{}'", commit); reset( open_repository, repo_details, &repo_config.branches().next(), &commit.into(), &force, )?; Ok(message_token) } #[instrument] fn validate_commit_message(message: &Message) -> Result<()> { let message = &message.to_string(); if message.to_ascii_lowercase().starts_with("wip") { return Err(Error::IsWorkInProgress); } match ::git_conventional::Commit::parse(message) { Ok(commit) => { info!(?commit, "Pass"); Ok(()) } Err(err) => { warn!(?err, "Fail"); Err(Error::InvalidCommitMessage { reason: err.kind().to_string(), }) } } } pub fn find_next_commit_on_dev( next: &Commit, main: &Commit, dev_commit_history: &[Commit], ) -> (Option, Force) { let mut next_commit: Option<&Commit> = None; let mut force = Force::No; for commit in dev_commit_history { if commit == next { break; }; if commit == main { force = Force::From(GitRef::from(next.sha().clone())); break; }; next_commit.replace(commit); } (next_commit.cloned(), force) } // advance main branch to the commit 'next' #[instrument(fields(next), skip_all)] pub fn advance_main( next: Commit, repo_details: &RepoDetails, repo_config: &RepoConfig, open_repository: &dyn OpenRepositoryLike, ) -> Result<()> { info!("Advancing main to next"); reset( open_repository, repo_details, &repo_config.branches().main(), &next.into(), &Force::No, )?; Ok(()) } pub type Result = std::result::Result; #[derive(Debug, thiserror::Error, Display)] pub enum Error { #[display("push: {}", 0)] Push(#[from] crate::git::push::Error), #[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 }, }