Skip to content

Commit f847c14

Browse files
committed
Write .cargo_ok after submodule checkout completes successfully
1 parent 14a646e commit f847c14

File tree

1 file changed

+30
-10
lines changed

1 file changed

+30
-10
lines changed

src/cargo/sources/git/utils.rs

Lines changed: 30 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,25 @@ pub struct GitCheckout<'a> {
8080
repo: git2::Repository,
8181
}
8282

83+
/// See [`GitCheckout::reset`] for rationale on this type.
84+
struct CheckoutGuard {
85+
ok_file: PathBuf,
86+
}
87+
88+
impl CheckoutGuard {
89+
#[must_use]
90+
fn guard(path: &Path) -> Self {
91+
let ok_file = path.join(CHECKOUT_READY_LOCK);
92+
let _ = paths::remove_file(&ok_file);
93+
Self { ok_file }
94+
}
95+
96+
fn mark_ok(self) -> CargoResult<()> {
97+
let _ = paths::create(self.ok_file)?;
98+
Ok(())
99+
}
100+
}
101+
83102
impl GitRemote {
84103
/// Creates an instance for a remote repository URL.
85104
pub fn new(url: &Url) -> GitRemote {
@@ -182,8 +201,9 @@ impl GitDatabase {
182201
{
183202
Some(co) => co,
184203
None => {
185-
let checkout = GitCheckout::clone_into(dest, self, rev, gctx)?;
204+
let (checkout, guard) = GitCheckout::clone_into(dest, self, rev, gctx)?;
186205
checkout.update_submodules(gctx)?;
206+
guard.mark_ok()?;
187207
checkout
188208
}
189209
};
@@ -284,7 +304,7 @@ impl<'a> GitCheckout<'a> {
284304
database: &'a GitDatabase,
285305
revision: git2::Oid,
286306
gctx: &GlobalContext,
287-
) -> CargoResult<GitCheckout<'a>> {
307+
) -> CargoResult<(GitCheckout<'a>, CheckoutGuard)> {
288308
let dirname = into.parent().unwrap();
289309
paths::create_dir_all(&dirname)?;
290310
if into.exists() {
@@ -333,8 +353,8 @@ impl<'a> GitCheckout<'a> {
333353
let repo = repo.unwrap();
334354

335355
let checkout = GitCheckout::new(database, revision, repo);
336-
checkout.reset(gctx)?;
337-
Ok(checkout)
356+
let guard = checkout.reset(gctx)?;
357+
Ok((checkout, guard))
338358
}
339359

340360
/// Checks if the `HEAD` of this checkout points to the expected revision.
@@ -359,12 +379,12 @@ impl<'a> GitCheckout<'a> {
359379
/// To enable this we have a dummy file in our checkout, [`.cargo-ok`],
360380
/// which if present means that the repo has been successfully reset and is
361381
/// ready to go. Hence if we start to do a reset, we make sure this file
362-
/// *doesn't* exist, and then once we're done we create the file.
382+
/// *doesn't* exist. The caller of [`reset`] has an option to perform additional operations
383+
/// (e.g. submodule update) before marking the check-out as ready.
363384
///
364385
/// [`.cargo-ok`]: CHECKOUT_READY_LOCK
365-
fn reset(&self, gctx: &GlobalContext) -> CargoResult<()> {
366-
let ok_file = self.path.join(CHECKOUT_READY_LOCK);
367-
let _ = paths::remove_file(&ok_file);
386+
fn reset(&self, gctx: &GlobalContext) -> CargoResult<CheckoutGuard> {
387+
let guard = CheckoutGuard::guard(&self.path);
368388
info!("reset {} to {}", self.repo.path().display(), self.revision);
369389

370390
// Ensure libgit2 won't mess with newlines when we vendor.
@@ -374,8 +394,8 @@ impl<'a> GitCheckout<'a> {
374394

375395
let object = self.repo.find_object(self.revision, None)?;
376396
reset(&self.repo, &object, gctx)?;
377-
paths::create(ok_file)?;
378-
Ok(())
397+
398+
Ok(guard)
379399
}
380400

381401
/// Like `git submodule update --recursive` but for this git checkout.

0 commit comments

Comments
 (0)