Skip to content

Commit

Permalink
feat(record): warn when quitting with unsaved commit messages
Browse files Browse the repository at this point in the history
  • Loading branch information
arxanas committed Oct 15, 2023
1 parent 13afef4 commit 4de5517
Show file tree
Hide file tree
Showing 3 changed files with 141 additions and 8 deletions.
1 change: 1 addition & 0 deletions git-branchless-record/tests/test_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ fn test_record_unstaged_changes_interactive() -> eyre::Result<()> {
PtyAction::Write("f"), // expand files
PtyAction::WaitUntilContains("contents1"),
PtyAction::Write("q"),
PtyAction::Write(" "), // confirm quit dialog
],
)?;
}
Expand Down
62 changes: 54 additions & 8 deletions scm-record/src/ui.rs
Original file line number Diff line number Diff line change
Expand Up @@ -999,9 +999,11 @@ impl<'state, 'input> Recorder<'state, 'input> {

// Render quit dialog if the user made changes.
(None, Event::QuitCancel | Event::QuitInterrupt) => {
let num_commit_messages = self.num_user_commit_messages()?;
let num_changed_files = self.num_user_file_changes()?;
if num_changed_files > 0 {
if num_commit_messages > 0 || num_changed_files > 0 {
StateUpdate::SetQuitDialog(Some(QuitDialog {
num_commit_messages,
num_changed_files,
focused_button: QuitDialogButtonId::Quit,
}))
Expand Down Expand Up @@ -1030,6 +1032,7 @@ impl<'state, 'input> Recorder<'state, 'input> {
// Press the appropriate dialog button.
(Some(quit_dialog), Event::ToggleItem | Event::ToggleItemAndAdvance) => {
let QuitDialog {
num_commit_messages: _,
num_changed_files: _,
focused_button,
} = quit_dialog;
Expand Down Expand Up @@ -1144,6 +1147,24 @@ impl<'state, 'input> Recorder<'state, 'input> {
}
}

fn num_user_commit_messages(&self) -> Result<usize, RecordError> {
let RecordState {
files: _,
commits,
is_read_only: _,
} = &self.state;
Ok(commits
.iter()
.map(|commit| {
let Commit { message } = commit;
match message {
Some(message) if !message.is_empty() => 1,
_ => 0,
}
})
.sum())
}

fn num_user_file_changes(&self) -> Result<usize, RecordError> {
let RecordState {
files,
Expand Down Expand Up @@ -3033,6 +3054,7 @@ impl Component for SectionLineView<'_> {

#[derive(Clone, Debug, PartialEq, Eq)]
struct QuitDialog {
num_commit_messages: usize,
num_changed_files: usize,
focused_button: QuitDialogButtonId,
}
Expand All @@ -3046,18 +3068,42 @@ impl Component for QuitDialog {

fn draw(&self, viewport: &mut Viewport<Self::Id>, _x: isize, _y: isize) {
let Self {
num_commit_messages,
num_changed_files,
focused_button,
} = self;
let title = "Quit";
let body = format!(
"You have changes to {num_changed_files} {}. Are you sure you want to quit?",
if *num_changed_files == 1 {
"file"
} else {
"files"
let alert_items = {
let mut result = Vec::new();
if *num_commit_messages > 0 {
result.push(format!(
"{num_commit_messages} {}",
if *num_commit_messages == 1 {
"message"
} else {
"messages"
}
));
}
);
if *num_changed_files > 0 {
result.push(format!(
"{num_changed_files} {}",
if *num_changed_files == 1 {
"file"
} else {
"files"
}
));
}
result
};
let alert = if alert_items.is_empty() {
// Shouldn't happen.
"".to_string()
} else {
format!("You have changes to {}. ", alert_items.join(" and "))
};
let body = format!("{alert}Are you sure you want to quit?",);

let quit_button = Button {
id: ComponentId::QuitDialogButton(QuitDialogButtonId::Quit),
Expand Down
86 changes: 86 additions & 0 deletions scm-record/tests/test_scm_record.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2548,3 +2548,89 @@ fn test_commit_message_view() -> eyre::Result<()> {

Ok(())
}

#[test]
fn test_quit_dialog_when_commit_message_provided() -> eyre::Result<()> {
let mut state = example_contents();
state.commits = vec![Commit {
message: Some("hello".to_string()),
}];

let changed_message_and_files = TestingScreenshot::default();
let changed_message_only = TestingScreenshot::default();
let mut input = TestingInput {
width: 80,
height: 24,
events: Box::new(
[
Event::QuitInterrupt,
changed_message_and_files.event(),
Event::QuitCancel,
Event::ToggleAllUniform, // toggle all
Event::ToggleAllUniform, // toggle none
Event::QuitInterrupt,
changed_message_only.event(),
Event::QuitInterrupt,
]
.into_iter(),
),
commit_messages: [].into_iter().collect(),
};
let recorder = Recorder::new(state, &mut input);
assert_matches!(recorder.run(), Err(RecordError::Cancelled));

insta::assert_display_snapshot!(changed_message_and_files, @r###"
"[File] [Edit] [Select] [View] "
" "
"[Edit message] • hello "
" "
"(~) foo/bar (+)"
"[×] baz [+]"
" "
" "
" "
" ┌Quit─────────────────────────────────────────────────────────────────────┐ "
" │You have changes to 1 message and 2 files. Are you sure you want to quit?│ "
" │ │ "
" └─────────────────────────────────────────────────────────[Go Back]─(Quit)┘ "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
"###);
insta::assert_display_snapshot!(changed_message_only, @r###"
"[File] [Edit] [Select] [View] "
" "
"[Edit message] • hello "
" "
"( ) foo/bar (+)"
"[ ] baz [+]"
" "
" "
" "
" ┌Quit─────────────────────────────────────────────────────────┐ "
" │You have changes to 1 message. Are you sure you want to quit?│ "
" │ │ "
" └─────────────────────────────────────────────[Go Back]─(Quit)┘ "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
" "
"###);

Ok(())
}

0 comments on commit 4de5517

Please sign in to comment.