Skip to content

Commit ceaf0dc

Browse files
authored
Merge pull request #5 from epage/transaction
feat(hook): Simplify transaction management
2 parents bad649b + 4918552 commit ceaf0dc

File tree

1 file changed

+81
-13
lines changed

1 file changed

+81
-13
lines changed

src/hooks.rs

Lines changed: 81 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ impl Hooks {
123123
&self,
124124
repo: &git2::Repository,
125125
changed_oids: &[(git2::Oid, git2::Oid)],
126-
) -> Result<(), std::io::Error> {
126+
) {
127127
let name = "post-rewrite";
128128
let command = "rebase";
129129
let args = [command];
@@ -133,10 +133,35 @@ impl Hooks {
133133
writeln!(stdin, "{} {}", old_oid, new_oid).expect("Always writeable");
134134
}
135135

136-
let code = self.run_hook(repo, name, &args, Some(stdin.as_bytes()), &[])?;
137-
log::trace!("Hook `{}` failed with code {}", name, code);
136+
match self.run_hook(repo, name, &args, Some(stdin.as_bytes()), &[]) {
137+
Ok(code) if code != 0 => {
138+
log::trace!("Hook `{}` failed with code {}", name, code);
139+
}
140+
Ok(_) => {}
141+
Err(err) => {
142+
log::trace!("Hook `{}` failed with {}", name, err);
143+
}
144+
}
145+
}
138146

139-
Ok(())
147+
/// Run `reference-transaction` hook to signal that all reference updates have been queued to the transaction.
148+
///
149+
/// **changed_refs (old, new, name):**
150+
/// - `name` is the full name of the ref
151+
/// - `old` is zeroed out when force updating the reference regardless of its current value or
152+
/// when the reference is to be created anew
153+
pub fn run_reference_transaction<'t>(
154+
&'t self,
155+
repo: &'t git2::Repository,
156+
changed_refs: &'t [(git2::Oid, git2::Oid, &'t str)],
157+
) -> Result<ReferenceTransaction<'_>, std::io::Error> {
158+
self.run_reference_transaction_prepare(repo, changed_refs)?;
159+
160+
Ok(ReferenceTransaction {
161+
hook: self,
162+
repo,
163+
changed_refs,
164+
})
140165
}
141166

142167
/// Run `reference-transaction` hook to signal that all reference updates have been queued to the transaction.
@@ -187,7 +212,7 @@ impl Hooks {
187212
&self,
188213
repo: &git2::Repository,
189214
changed_refs: &[(git2::Oid, git2::Oid, &str)],
190-
) -> Result<(), std::io::Error> {
215+
) {
191216
let name = "reference-transaction";
192217
let state = "committed";
193218
let args = [state];
@@ -197,10 +222,15 @@ impl Hooks {
197222
writeln!(stdin, "{} {} {}", old_oid, new_oid, ref_name).expect("Always writeable");
198223
}
199224

200-
let code = self.run_hook(repo, name, &args, Some(stdin.as_bytes()), &[])?;
201-
log::trace!("Hook `{}` failed with code {}", name, code);
202-
203-
Ok(())
225+
match self.run_hook(repo, name, &args, Some(stdin.as_bytes()), &[]) {
226+
Ok(code) if code != 0 => {
227+
log::trace!("Hook `{}` failed with code {}", name, code);
228+
}
229+
Ok(_) => {}
230+
Err(err) => {
231+
log::trace!("Hook `{}` failed with {}", name, err);
232+
}
233+
}
204234
}
205235

206236
/// Run `reference-transaction` hook to signal that no changes have been made
@@ -213,7 +243,7 @@ impl Hooks {
213243
&self,
214244
repo: &git2::Repository,
215245
changed_refs: &[(git2::Oid, git2::Oid, &str)],
216-
) -> Result<(), std::io::Error> {
246+
) {
217247
let name = "reference-transaction";
218248
let state = "aborted";
219249
let args = [state];
@@ -223,10 +253,48 @@ impl Hooks {
223253
writeln!(stdin, "{} {} {}", old_oid, new_oid, ref_name).expect("Always writeable");
224254
}
225255

226-
let code = self.run_hook(repo, name, &args, Some(stdin.as_bytes()), &[])?;
227-
log::trace!("Hook `{}` failed with code {}", name, code);
256+
match self.run_hook(repo, name, &args, Some(stdin.as_bytes()), &[]) {
257+
Ok(code) if code != 0 => {
258+
log::trace!("Hook `{}` failed with code {}", name, code);
259+
}
260+
Ok(_) => {}
261+
Err(err) => {
262+
log::trace!("Hook `{}` failed with {}", name, err);
263+
}
264+
}
265+
}
266+
}
267+
268+
pub struct ReferenceTransaction<'t> {
269+
hook: &'t Hooks,
270+
repo: &'t git2::Repository,
271+
changed_refs: &'t [(git2::Oid, git2::Oid, &'t str)],
272+
}
273+
274+
impl<'t> ReferenceTransaction<'t> {
275+
pub fn committed(self) {
276+
let Self {
277+
hook,
278+
repo,
279+
changed_refs,
280+
} = self;
281+
hook.run_reference_transaction_committed(repo, changed_refs);
282+
}
283+
284+
pub fn aborted(self) {
285+
let Self {
286+
hook,
287+
repo,
288+
changed_refs,
289+
} = self;
290+
hook.run_reference_transaction_aborted(repo, changed_refs);
291+
}
292+
}
228293

229-
Ok(())
294+
impl<'t> Drop for ReferenceTransaction<'t> {
295+
fn drop(&mut self) {
296+
self.hook
297+
.run_reference_transaction_aborted(self.repo, self.changed_refs);
230298
}
231299
}
232300

0 commit comments

Comments
 (0)