git_policy_cli/
commit_landing_lock.rs1use super::capture_invocation::InvocationLayout;
14use super::diagnostic_log::debug;
15use super::owner_lock::{DEFAULT_POLL_DELAY, OwnerLock, SilentWait, acquire_owner_lock};
16use super::recovery_error::RecoveryError;
17use super::recovery_landing::RecoveryPlace;
18use super::recovery_scan::recover_dead_landings;
19use super::replay_reservation::{LandingReservation, ReservationError, acquire_reserved_landing_lock};
20use super::transaction_git::GitContext;
21use super::transaction_lease::{has_valid_landing_lease, landing_lease_token};
22use super::transaction_registry::LANDING_LOCK_NAME;
23use std::ffi::OsString;
24use std::path::{Path, PathBuf};
25
26const TAG: &str = "acquireLandingLock";
28
29pub fn landing_lock_directory(layout: &InvocationLayout) -> PathBuf {
39 return layout.registry_root.join(LANDING_LOCK_NAME);
40}
41
42pub fn landing_is_nested(layout: &InvocationLayout, environment: &[(OsString, OsString)]) -> bool {
52 return has_valid_landing_lease(environment, landing_lock_directory(layout).as_path());
53}
54
55pub fn acquire_landing_lock(
65 context: &GitContext,
66 cwd: &Path,
67 layout: &InvocationLayout,
68 environment: &[(OsString, OsString)],
69) -> Result<OwnerLock, RecoveryError> {
70 let directory: PathBuf = landing_lock_directory(layout);
71 let lock: OwnerLock = if landing_is_nested(layout, environment) {
72 let token: String = landing_lease_token(environment).unwrap_or_default();
73 debug(TAG, format!("leaving {} to the ancestor that holds it", directory.display()).as_str());
74 OwnerLock::inherited(directory.as_path(), token.as_str())
75 } else {
76 let mut silent: SilentWait = SilentWait;
77 acquire_owner_lock(directory.as_path(), DEFAULT_POLL_DELAY, &mut silent)
78 .map_err(|error| { return RecoveryError(error.to_string()); })?
79 };
80 let place: RecoveryPlace = RecoveryPlace {
81 git: context.clone(),
82 cwd: cwd.to_path_buf(),
83 common_dir: layout.common_dir.clone(),
84 };
85 recover_dead_landings(&place, layout.registry_root.as_path())?;
87 return Ok(lock);
88}
89
90pub fn acquire_reserved_lock(
100 context: &GitContext,
101 cwd: &Path,
102 layout: &InvocationLayout,
103 environment: &[(OsString, OsString)],
104 reservation: &LandingReservation,
105) -> Result<OwnerLock, ReservationError> {
106 return acquire_reserved_landing_lock(reservation, || {
107 return acquire_landing_lock(context, cwd, layout, environment).map_err(ReservationError::Registry);
108 });
109}
110
111#[cfg(test)]
113#[path = "commit_landing_lock_tests.rs"]
114mod tests;