sley_submodule/
update_strategy.rs1use crate::config::{UpdateStrategy, UpdateType, parse_update_strategy};
26
27pub fn determine_update_strategy(
41 cli_default: UpdateType,
42 config_update: Option<&str>,
43 gitmodules_strategy: &UpdateStrategy,
44 just_cloned: bool,
45) -> Result<UpdateStrategy, String> {
46 let mut out = if cli_default != UpdateType::Unspecified {
47 UpdateStrategy {
48 kind: cli_default,
49 command: None,
50 }
51 } else if let Some(val) = config_update {
52 match parse_update_strategy(val) {
54 Some(strategy) => strategy,
55 None => return Err(val.to_string()),
56 }
57 } else if gitmodules_strategy.kind != UpdateType::Unspecified {
58 gitmodules_strategy.clone()
62 } else {
63 UpdateStrategy {
64 kind: UpdateType::Checkout,
65 command: None,
66 }
67 };
68
69 if just_cloned
70 && matches!(
71 out.kind,
72 UpdateType::Merge | UpdateType::Rebase | UpdateType::None
73 )
74 {
75 out.kind = UpdateType::Checkout;
76 out.command = None;
77 }
78
79 Ok(out)
80}
81
82#[cfg(test)]
83mod tests {
84 use super::*;
85
86 fn checkout() -> UpdateStrategy {
87 UpdateStrategy {
88 kind: UpdateType::Checkout,
89 command: None,
90 }
91 }
92
93 fn unspec() -> UpdateStrategy {
94 UpdateStrategy::default()
95 }
96
97 #[test]
98 fn cli_flag_wins() {
99 let got = determine_update_strategy(
101 UpdateType::Rebase,
102 Some("merge"),
103 &UpdateStrategy {
104 kind: UpdateType::None,
105 command: None,
106 },
107 false,
108 )
109 .expect("CLI update strategy should be accepted");
110 assert_eq!(got.kind, UpdateType::Rebase);
111 }
112
113 #[test]
114 fn config_beats_gitmodules() {
115 let got = determine_update_strategy(
116 UpdateType::Unspecified,
117 Some("rebase"),
118 &UpdateStrategy {
119 kind: UpdateType::Merge,
120 command: None,
121 },
122 false,
123 )
124 .expect("configured update strategy should be accepted");
125 assert_eq!(got.kind, UpdateType::Rebase);
126 }
127
128 #[test]
129 fn gitmodules_used_when_no_config() {
130 let got = determine_update_strategy(
131 UpdateType::Unspecified,
132 None,
133 &UpdateStrategy {
134 kind: UpdateType::Merge,
135 command: None,
136 },
137 false,
138 )
139 .expect("gitmodules update strategy should be accepted");
140 assert_eq!(got.kind, UpdateType::Merge);
141 }
142
143 #[test]
144 fn default_is_checkout() {
145 let got = determine_update_strategy(UpdateType::Unspecified, None, &unspec(), false)
146 .expect("default update strategy should be accepted");
147 assert_eq!(got, checkout());
148 }
149
150 #[test]
151 fn command_from_config_carries_string() {
152 let got =
153 determine_update_strategy(UpdateType::Unspecified, Some("!false"), &unspec(), false)
154 .expect("custom update command should be accepted");
155 assert_eq!(got.kind, UpdateType::Command);
156 assert_eq!(got.command.as_deref(), Some("false"));
157 }
158
159 #[test]
160 fn just_cloned_downgrades_to_checkout() {
161 for kind in [UpdateType::Merge, UpdateType::Rebase, UpdateType::None] {
162 let got = determine_update_strategy(
163 UpdateType::Unspecified,
164 None,
165 &UpdateStrategy {
166 kind,
167 command: None,
168 },
169 true,
170 )
171 .expect("just-cloned strategy should be accepted");
172 assert_eq!(got.kind, UpdateType::Checkout, "downgrade {kind:?}");
173 }
174 let got =
176 determine_update_strategy(UpdateType::Unspecified, Some("!true"), &unspec(), true)
177 .expect("custom update command should not be downgraded");
178 assert_eq!(got.kind, UpdateType::Command);
179 }
180
181 #[test]
182 fn invalid_config_value_errors() {
183 let err =
184 determine_update_strategy(UpdateType::Unspecified, Some("bogus"), &unspec(), false)
185 .expect_err("invalid update strategy should error");
186 assert_eq!(err, "bogus");
187 }
188}