use crate::config::{UpdateStrategy, UpdateType, parse_update_strategy};
pub fn determine_update_strategy(
cli_default: UpdateType,
config_update: Option<&str>,
gitmodules_strategy: &UpdateStrategy,
just_cloned: bool,
) -> Result<UpdateStrategy, String> {
let mut out = if cli_default != UpdateType::Unspecified {
UpdateStrategy {
kind: cli_default,
command: None,
}
} else if let Some(val) = config_update {
match parse_update_strategy(val) {
Some(strategy) => strategy,
None => return Err(val.to_string()),
}
} else if gitmodules_strategy.kind != UpdateType::Unspecified {
gitmodules_strategy.clone()
} else {
UpdateStrategy {
kind: UpdateType::Checkout,
command: None,
}
};
if just_cloned
&& matches!(
out.kind,
UpdateType::Merge | UpdateType::Rebase | UpdateType::None
)
{
out.kind = UpdateType::Checkout;
out.command = None;
}
Ok(out)
}
#[cfg(test)]
mod tests {
use super::*;
fn checkout() -> UpdateStrategy {
UpdateStrategy {
kind: UpdateType::Checkout,
command: None,
}
}
fn unspec() -> UpdateStrategy {
UpdateStrategy::default()
}
#[test]
fn cli_flag_wins() {
let got = determine_update_strategy(
UpdateType::Rebase,
Some("merge"),
&UpdateStrategy {
kind: UpdateType::None,
command: None,
},
false,
)
.expect("CLI update strategy should be accepted");
assert_eq!(got.kind, UpdateType::Rebase);
}
#[test]
fn config_beats_gitmodules() {
let got = determine_update_strategy(
UpdateType::Unspecified,
Some("rebase"),
&UpdateStrategy {
kind: UpdateType::Merge,
command: None,
},
false,
)
.expect("configured update strategy should be accepted");
assert_eq!(got.kind, UpdateType::Rebase);
}
#[test]
fn gitmodules_used_when_no_config() {
let got = determine_update_strategy(
UpdateType::Unspecified,
None,
&UpdateStrategy {
kind: UpdateType::Merge,
command: None,
},
false,
)
.expect("gitmodules update strategy should be accepted");
assert_eq!(got.kind, UpdateType::Merge);
}
#[test]
fn default_is_checkout() {
let got = determine_update_strategy(UpdateType::Unspecified, None, &unspec(), false)
.expect("default update strategy should be accepted");
assert_eq!(got, checkout());
}
#[test]
fn command_from_config_carries_string() {
let got =
determine_update_strategy(UpdateType::Unspecified, Some("!false"), &unspec(), false)
.expect("custom update command should be accepted");
assert_eq!(got.kind, UpdateType::Command);
assert_eq!(got.command.as_deref(), Some("false"));
}
#[test]
fn just_cloned_downgrades_to_checkout() {
for kind in [UpdateType::Merge, UpdateType::Rebase, UpdateType::None] {
let got = determine_update_strategy(
UpdateType::Unspecified,
None,
&UpdateStrategy {
kind,
command: None,
},
true,
)
.expect("just-cloned strategy should be accepted");
assert_eq!(got.kind, UpdateType::Checkout, "downgrade {kind:?}");
}
let got =
determine_update_strategy(UpdateType::Unspecified, Some("!true"), &unspec(), true)
.expect("custom update command should not be downgraded");
assert_eq!(got.kind, UpdateType::Command);
}
#[test]
fn invalid_config_value_errors() {
let err =
determine_update_strategy(UpdateType::Unspecified, Some("bogus"), &unspec(), false)
.expect_err("invalid update strategy should error");
assert_eq!(err, "bogus");
}
}