diff options
| -rw-r--r-- | mingling_ci/src/cmd/cmd_git_unlock.rs | 25 |
1 files changed, 20 insertions, 5 deletions
diff --git a/mingling_ci/src/cmd/cmd_git_unlock.rs b/mingling_ci/src/cmd/cmd_git_unlock.rs index dadc318..4d9ee80 100644 --- a/mingling_ci/src/cmd/cmd_git_unlock.rs +++ b/mingling_ci/src/cmd/cmd_git_unlock.rs @@ -5,7 +5,7 @@ use mingling::{ }; use crate::Next; -use crate::git::{LOCK_FILE, TEMP_COMMIT_MARK, head_message, run_git}; +use crate::git::{LOCK_FILE, TEMP_COMMIT_MARK, head_message, run_git, worktree_clean}; use crate::res::{CargoError, MessagePrinter}; /// Undoes a CI temporary commit created by [`crate::cmd::cmd_git_lock`]. @@ -15,6 +15,10 @@ use crate::res::{CargoError, MessagePrinter}; /// is in a CI phase and all uncommitted state may be discarded. Restores the /// tree in five steps: unstage, restore tracked files, delete untracked files, /// roll back the temporary commit, and remove the marker file. +/// +/// When the working tree is dirty (e.g. CI left tracked changes behind) the +/// restore still runs, but the command reports a non-zero exit code so the +/// caller knows the CI phase contaminated the repository. #[command(node = "git-unlock")] pub fn git_unlock() -> Next { let head = head_message().unwrap_or_default(); @@ -22,11 +26,14 @@ pub fn git_unlock() -> Next { return ErrorGitUnlock(format!("HEAD is not a CI temporary commit: `{head}`")).to_chain(); } + // Record dirtiness before restoring: the restore discards those changes. + let dirty = !worktree_clean(); + if let Err(e) = undo_ci_phase() { return ErrorGitUnlock(e).to_chain(); } - ResultGitUnlock {}.to_chain() + ResultGitUnlock { dirty }.to_chain() } /// The five-step restoration sequence of `git-unlock`. @@ -39,15 +46,23 @@ fn undo_ci_phase() -> Result<(), String> { Ok(()) } +/// Whether the working tree was dirty when the unlock started. #[derive(Grouped)] -pub struct ResultGitUnlock; +pub struct ResultGitUnlock { + dirty: bool, +} #[derive(Grouped, Default)] pub struct ErrorGitUnlock(pub String); #[renderer(buffer)] -pub fn render_git_unlock(_: ResultGitUnlock) { - r_println!("Unlocked: workspace restored"); +pub fn render_git_unlock(r: ResultGitUnlock, exit_code: &mut ResExitCode) { + if r.dirty { + r_println!("Unlocked: workspace restored (working tree was dirty)"); + exit_code.exit_code = 1; + } else { + r_println!("Unlocked: workspace restored"); + } } #[renderer] |
