mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-07-07 20:06:36 +02:00
Add confirmation prompts for modifications of lots of tasks
This commit is contained in:
parent
31ff46bee6
commit
0de4fc1dee
7 changed files with 170 additions and 24 deletions
|
@ -1,15 +1,58 @@
|
|||
use crate::argparse::{Filter, Modification};
|
||||
use crate::invocation::{apply_modification, filtered_tasks, summarize_task};
|
||||
use crate::invocation::util::{confirm, summarize_task};
|
||||
use crate::invocation::{apply_modification, filtered_tasks};
|
||||
use crate::settings::Settings;
|
||||
use taskchampion::Replica;
|
||||
use termcolor::WriteColor;
|
||||
|
||||
/// confirm modification of more than `modificationt_count_prompt` tasks, defaulting to 3
|
||||
fn check_modification<W: WriteColor>(
|
||||
w: &mut W,
|
||||
settings: &Settings,
|
||||
affected_tasks: usize,
|
||||
) -> Result<bool, crate::Error> {
|
||||
let setting = settings.modification_count_prompt.unwrap_or(3);
|
||||
if setting == 0 || affected_tasks <= setting as usize {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
let prompt = format!("Operation will modify {} tasks; continue?", affected_tasks,);
|
||||
if confirm(&prompt)? {
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
writeln!(w, "Cancelled")?;
|
||||
|
||||
// only show this help if the setting is not set
|
||||
if settings.modification_count_prompt.is_none() {
|
||||
writeln!(
|
||||
w,
|
||||
"Set the `modification_count_prompt` setting to avoid this prompt:"
|
||||
)?;
|
||||
writeln!(
|
||||
w,
|
||||
" ta config set modification_count_prompt {}",
|
||||
affected_tasks + 1
|
||||
)?;
|
||||
writeln!(w, "Set it to 0 to disable the prompt entirely")?;
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
|
||||
pub(crate) fn execute<W: WriteColor>(
|
||||
w: &mut W,
|
||||
replica: &mut Replica,
|
||||
settings: &Settings,
|
||||
filter: Filter,
|
||||
modification: Modification,
|
||||
) -> Result<(), crate::Error> {
|
||||
for task in filtered_tasks(replica, &filter)? {
|
||||
let tasks = filtered_tasks(replica, &filter)?;
|
||||
|
||||
if !check_modification(w, settings, tasks.size_hint().0)? {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
for task in tasks {
|
||||
let mut task = task.into_mut(replica);
|
||||
|
||||
apply_modification(&mut task, &modification)?;
|
||||
|
@ -34,6 +77,7 @@ mod test {
|
|||
fn test_modify() {
|
||||
let mut w = test_writer();
|
||||
let mut replica = test_replica();
|
||||
let settings = Settings::default();
|
||||
|
||||
let task = replica
|
||||
.new_task(Status::Pending, s!("old description"))
|
||||
|
@ -46,7 +90,7 @@ mod test {
|
|||
description: DescriptionMod::Set(s!("new description")),
|
||||
..Default::default()
|
||||
};
|
||||
execute(&mut w, &mut replica, filter, modification).unwrap();
|
||||
execute(&mut w, &mut replica, &settings, filter, modification).unwrap();
|
||||
|
||||
// check that the task appeared..
|
||||
let task = replica.get_task(task.get_uuid()).unwrap().unwrap();
|
||||
|
|
|
@ -2,13 +2,14 @@
|
|||
|
||||
use crate::argparse::{Command, Subcommand};
|
||||
use crate::settings::Settings;
|
||||
use taskchampion::{Replica, Server, ServerConfig, StorageConfig, Task, Uuid};
|
||||
use taskchampion::{Replica, Server, ServerConfig, StorageConfig, Uuid};
|
||||
use termcolor::{ColorChoice, StandardStream};
|
||||
|
||||
mod cmd;
|
||||
mod filter;
|
||||
mod modify;
|
||||
mod report;
|
||||
mod util;
|
||||
|
||||
#[cfg(test)]
|
||||
mod test;
|
||||
|
@ -60,7 +61,7 @@ pub(crate) fn invoke(command: Command, settings: Settings) -> Result<(), crate::
|
|||
modification,
|
||||
},
|
||||
..
|
||||
} => return cmd::modify::execute(&mut w, &mut replica, filter, modification),
|
||||
} => return cmd::modify::execute(&mut w, &mut replica, &settings, filter, modification),
|
||||
|
||||
Command {
|
||||
subcommand:
|
||||
|
@ -149,14 +150,3 @@ fn get_writer() -> StandardStream {
|
|||
ColorChoice::Never
|
||||
})
|
||||
}
|
||||
|
||||
/// Summarize a task in a single line
|
||||
fn summarize_task(replica: &mut Replica, task: &Task) -> anyhow::Result<String> {
|
||||
let ws = replica.working_set()?;
|
||||
let uuid = task.get_uuid();
|
||||
if let Some(id) = ws.by_uuid(uuid) {
|
||||
Ok(format!("{} - {}", id, task.get_description()))
|
||||
} else {
|
||||
Ok(format!("{} - {}", uuid, task.get_description()))
|
||||
}
|
||||
}
|
||||
|
|
22
cli/src/invocation/util.rs
Normal file
22
cli/src/invocation/util.rs
Normal file
|
@ -0,0 +1,22 @@
|
|||
use dialoguer::Confirm;
|
||||
use taskchampion::{Replica, Task};
|
||||
|
||||
/// Print the prompt and ask the user to answer yes or no. If input is not from a terminal, the
|
||||
/// answer is assumed to be true.
|
||||
pub(super) fn confirm<S: Into<String>>(prompt: S) -> anyhow::Result<bool> {
|
||||
if !atty::is(atty::Stream::Stdin) {
|
||||
return Ok(true);
|
||||
}
|
||||
Ok(Confirm::new().with_prompt(prompt).interact()?)
|
||||
}
|
||||
|
||||
/// Summarize a task in a single line
|
||||
pub(super) fn summarize_task(replica: &mut Replica, task: &Task) -> anyhow::Result<String> {
|
||||
let ws = replica.working_set()?;
|
||||
let uuid = task.get_uuid();
|
||||
if let Some(id) = ws.by_uuid(uuid) {
|
||||
Ok(format!("{} - {}", id, task.get_description()))
|
||||
} else {
|
||||
Ok(format!("{} - {}", uuid, task.get_description()))
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue