diff options
| author | 魏曹先生 <1992414357@qq.com> | 2026-08-18 12:19:09 +0800 |
|---|---|---|
| committer | 魏曹先生 <1992414357@qq.com> | 2026-08-18 12:23:03 +0800 |
| commit | 5de5d5d72a9021125272977a6ca2ab865043bf67 (patch) | |
| tree | b106c15f3e722de94bd555589a94828b1aafd641 /mingling_ci/src/cmd | |
| parent | b1694827328dcbf061b9b502e51830176b4f42df (diff) | |
chore: show diff on git-unlock in CI
Pass `--show-diff` to `git-unlock` and restructure CI steps as
(command, args) pairs to support per-step arguments. The diff prints
tracked workspace changes before they are discarded.
Diffstat (limited to 'mingling_ci/src/cmd')
| -rw-r--r-- | mingling_ci/src/cmd/cmd_git_unlock.rs | 29 |
1 files changed, 25 insertions, 4 deletions
diff --git a/mingling_ci/src/cmd/cmd_git_unlock.rs b/mingling_ci/src/cmd/cmd_git_unlock.rs index 6d7389d..41efefc 100644 --- a/mingling_ci/src/cmd/cmd_git_unlock.rs +++ b/mingling_ci/src/cmd/cmd_git_unlock.rs @@ -1,12 +1,13 @@ use mingling::{ Grouped, RenderResult, Routable, - macros::{buffer, command, r_println, renderer}, + macros::{arg, buffer, command, r_println, renderer}, + picker::{EntryPicker, value::Flag}, res::ResExitCode, }; -use crate::Next; use crate::git::{LOCK_FILE, TEMP_COMMIT_MARK, head_message, run_git, worktree_clean}; use crate::res::{CargoError, MessagePrinter}; +use crate::{Entry, Next}; /// Undoes a CI temporary commit created by [`crate::cmd::cmd_git_lock`]. /// @@ -21,9 +22,13 @@ use crate::res::{CargoError, MessagePrinter}; /// /// 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. +/// caller knows the CI phase contaminated the repository. With `--show-diff` +/// the diff of those changes is printed before they are discarded. #[command(node = "git-unlock")] -pub fn git_unlock() -> Next { +// `#[command]` rewrites an owned first param into the entry type, so the args +// must be passed by value even though the body only reads them. +#[allow(clippy::needless_pass_by_value)] +pub fn git_unlock(args: Entry) -> Next { let head = head_message().unwrap_or_default(); if !head.contains(TEMP_COMMIT_MARK) { return ErrorGitUnlock(format!("HEAD is not a CI temporary commit: `{head}`")).to_chain(); @@ -37,6 +42,10 @@ pub fn git_unlock() -> Next { let based_on_dirty = std::fs::read_to_string(LOCK_FILE).is_ok_and(|content| content.trim() == "true"); + if dirty && *args.pick(&arg![show_diff: Flag]).unwrap() { + show_diff(); + } + if let Err(e) = undo_ci_phase(based_on_dirty) { return ErrorGitUnlock(e).to_chain(); } @@ -44,6 +53,18 @@ pub fn git_unlock() -> Next { ResultGitUnlock { dirty }.to_chain() } +/// Prints the tracked changes the CI run left behind, before the restore +/// discards them. Untracked files are not shown (they are removed by clean). +fn show_diff() { + let Ok(diff) = run_git(["diff", "HEAD"]) else { + return; + }; + if diff.is_empty() { + return; + } + println!("{diff}"); +} + /// Restores the workspace, keeping the user's pre-lock changes. /// /// With a base `TEMP` commit (`true`) the marker commit is dropped by a hard |
