git-gamble 2.12.1

blend TDD + TCR to make sure to develop the right thing 😌, baby step by baby step πŸ‘ΆπŸ¦Ά
Documentation
use crate::message::Message;

use super::cli::Cli;
use super::gamble_result::GambleError;
use super::gamble_result::GambleResult;
use super::repository::Repository;

pub(crate) fn commit(opt: &Cli, repository: &Repository) -> GambleResult {
	log::info!("commit");

	let post_hook_gambled = if opt.pass { "pass" } else { "fail" };
	let post_hook_actual = post_hook_gambled;

	if repository.is_clean() {
		log::warn!("There is nothing to commit");
		Message::Warn("There is nothing to commit".to_string()).display();

		repository
			.run_hook("post-gamble", &[post_hook_gambled, post_hook_actual])
			.map_err(|error| {
				error.add_message(Message::Warn(
					"The post-gamble hook failed to execute".to_string(),
				))
			})
			.and_then(|()| {
				Err(GambleError {
					messages: vec![],
					code: 1, // post-gamble hook may succeed but this not the happy path
				})
			})
	} else {
		let base_options = vec!["commit", "--allow-empty-message"];

		let mut message_options = if let Some(commit) = &opt.fixup {
			vec!["--fixup", commit]
		} else if opt.message.is_empty() && repository.head_is_failing_ref() {
			vec!["--reuse-message", "HEAD"]
		} else {
			vec![]
		};

		if !opt.message.is_empty() {
			message_options.extend_from_slice(&["--message", &opt.message]);
		}

		let edit_options = if opt.edit {
			vec!["--edit"]
		} else {
			vec!["--no-edit"]
		};

		let squash_options = if let Some(commit) = &opt.squash {
			vec!["--squash", commit]
		} else {
			vec![]
		};

		let amend_options = if repository.head_is_failing_ref() {
			vec!["--amend"]
		} else {
			vec![]
		};

		let no_verify_options = if opt.no_verify {
			vec!["--no-verify"]
		} else {
			vec![]
		};

		repository
			.command(
				&[
					base_options,
					message_options,
					edit_options,
					squash_options,
					amend_options,
					no_verify_options,
				]
				.concat(),
			)
			.and_then(|()| {
				if opt.fail {
					repository.command(&["update-ref", "refs/gamble-is-failing", "HEAD"])
				} else {
					Ok(())
				}
			})
			.and_then(|()| {
				log::info!("committed");
				Message::Info("Committed!".to_string()).display();

				repository
					.run_hook("post-gamble", &[post_hook_gambled, post_hook_actual])
					.map_err(|error| -> GambleError {
						error.add_message(Message::Warn(
							"It has been committed but the post-gamble hook failed to execute"
								.to_string(),
						))
					})
			})
	}
}