diff --git a/CHANGELOG.md b/CHANGELOG.md index a2c28f91..071c8b22 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -24,7 +24,13 @@ So even though this is technically not a breaking change, I'll treat it as one t - Fixed delay after sending process related commands from client. [#540](https://github.com/Nukesor/pueue/pull/540) -### Added +### Change + +- **Breaking**: Streamlined `pueue log` parameters to behave the same way was `start`, `pause` or `kill`. [#509](https://github.com/Nukesor/pueue/issues/509) + +### Add + +- Add `--all` and `--group` to `pueue log`. [#509](https://github.com/Nukesor/pueue/issues/509) ## \[3.4.1\] - 2024-06-04 diff --git a/pueue/src/client/cli.rs b/pueue/src/client/cli.rs index cc7f26da..266e6f15 100644 --- a/pueue/src/client/cli.rs +++ b/pueue/src/client/cli.rs @@ -389,6 +389,14 @@ https://github.com/Nukesor/pueue/issues/350#issue-1359083118" /// View the task output of these specific tasks. task_ids: Vec, + /// View the outputs of this specific group's tasks. + #[arg(short, long)] + group: Option, + + /// Show the logs of all groups' tasks. + #[arg(short, long)] + all: bool, + /// Print the resulting tasks and output as json. /// By default only the last lines will be returned unless --full is provided. /// Take care, as the json cannot be streamed! diff --git a/pueue/src/client/client.rs b/pueue/src/client/client.rs index fad5a22c..b62886b6 100644 --- a/pueue/src/client/client.rs +++ b/pueue/src/client/client.rs @@ -517,13 +517,16 @@ impl Client { SubCommand::Log { task_ids, lines, + group, full, + all, .. } => { let lines = determine_log_line_amount(*full, lines); + let selection = selection_from_params(*all, group, task_ids); let message = LogRequestMessage { - task_ids: task_ids.clone(), + tasks: selection, send_logs: !self.settings.client.read_local_logs, lines, }; diff --git a/pueue/src/client/display/log/mod.rs b/pueue/src/client/display/log/mod.rs index b8655a82..92819235 100644 --- a/pueue/src/client/display/log/mod.rs +++ b/pueue/src/client/display/log/mod.rs @@ -3,12 +3,13 @@ use std::collections::BTreeMap; use comfy_table::{Attribute as ComfyAttribute, Cell, CellAlignment, Table}; use crossterm::style::Color; -use pueue_lib::network::message::TaskLogMessage; +use pueue_lib::network::message::{TaskLogMessage, TaskSelection}; use pueue_lib::settings::Settings; use pueue_lib::task::{Task, TaskResult, TaskStatus}; use super::OutputStyle; use crate::client::cli::SubCommand; +use crate::client::client::selection_from_params; mod json; mod local; @@ -52,8 +53,10 @@ pub fn print_logs( let SubCommand::Log { json, task_ids, + group, lines, full, + all, } = cli_command else { panic!("Got wrong Subcommand {cli_command:?} in print_log. This shouldn't happen"); @@ -67,15 +70,22 @@ pub fn print_logs( return; } - // Check some early return conditions - if task_ids.is_empty() && task_logs.is_empty() { - println!("There are no finished tasks"); - return; - } - - if !task_ids.is_empty() && task_logs.is_empty() { - println!("There are no finished tasks for your specified ids"); - return; + let selection = selection_from_params(*all, group, task_ids); + if task_logs.is_empty() { + match selection { + TaskSelection::TaskIds(_) => { + println!("There are no finished tasks for your specified ids"); + return; + } + TaskSelection::Group(group) => { + println!("There are no finished tasks for group '{group}'"); + return; + } + TaskSelection::All => { + println!("There are no finished tasks"); + return; + } + } } // Iterate over each task and print the respective log. diff --git a/pueue/src/daemon/network/message_handler/log.rs b/pueue/src/daemon/network/message_handler/log.rs index 01bd994f..17dd3acf 100644 --- a/pueue/src/daemon/network/message_handler/log.rs +++ b/pueue/src/daemon/network/message_handler/log.rs @@ -10,11 +10,11 @@ use pueue_lib::state::SharedState; /// Return tasks and their output to the client. pub fn get_log(settings: &Settings, state: &SharedState, message: LogRequestMessage) -> Message { let state = { state.lock().unwrap().clone() }; - // Return all logs, if no specific task id is specified. - let task_ids = if message.task_ids.is_empty() { - state.tasks.keys().cloned().collect() - } else { - message.task_ids + + let task_ids = match message.tasks { + TaskSelection::All => state.tasks.keys().cloned().collect(), + TaskSelection::TaskIds(task_ids) => task_ids, + TaskSelection::Group(group) => state.task_ids_in_group(&group), }; let mut tasks = BTreeMap::new(); diff --git a/pueue/tests/daemon/integration/log.rs b/pueue/tests/daemon/integration/log.rs index 037caee1..8ca55722 100644 --- a/pueue/tests/daemon/integration/log.rs +++ b/pueue/tests/daemon/integration/log.rs @@ -95,7 +95,7 @@ async fn test_partial_log() -> Result<()> { // Request a partial log for task 0 let log_message = LogRequestMessage { - task_ids: vec![0], + tasks: TaskSelection::TaskIds(vec![0]), send_logs: true, lines: Some(5), }; @@ -132,7 +132,7 @@ async fn test_correct_log_order() -> Result<()> { // Request all log lines let log_message = LogRequestMessage { - task_ids: vec![0], + tasks: TaskSelection::TaskIds(vec![0]), send_logs: true, lines: None, }; @@ -155,3 +155,71 @@ async fn test_correct_log_order() -> Result<()> { Ok(()) } + +/// Make sure that it's possible to get only logs of a specific group +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn logs_of_group() -> Result<()> { + let daemon = daemon().await?; + let shared = &daemon.settings.shared; + + // Add one task on the default group. + let command = "echo 'default group'"; + assert_success(add_task(shared, command).await?); + + // Add one task on the test group. + let command = "echo 'testgroup'"; + assert_success(add_task_to_group(shared, command, "test_2").await?); + + // Wait for both to finish + wait_for_task_condition(shared, 1, |task| task.is_done()).await?; + + // Request the task's logs. + let message = LogRequestMessage { + tasks: TaskSelection::Group("test_2".to_string()), + send_logs: true, + lines: None, + }; + let response = send_message(shared, message).await?; + let logs = match response { + Message::LogResponse(logs) => logs, + _ => bail!("Didn't get log response response in get_state"), + }; + + assert_eq!(logs.len(), 1, "Sould only receive a single log entry."); + + Ok(()) +} + +/// Make sure that it's possible to get logs across groups. +#[tokio::test(flavor = "multi_thread", worker_threads = 2)] +async fn logs_for_all() -> Result<()> { + let daemon = daemon().await?; + let shared = &daemon.settings.shared; + + // Add one task on the default group. + let command = "echo 'default group'"; + assert_success(add_task(shared, command).await?); + + // Add one task on the test group. + let command = "echo 'testgroup'"; + assert_success(add_task_to_group(shared, command, "test_2").await?); + + // Wait for both to finish + wait_for_task_condition(shared, 1, |task| task.is_done()).await?; + + // Request the task's logs. + let message = LogRequestMessage { + tasks: TaskSelection::All, + send_logs: true, + lines: None, + }; + let response = send_message(shared, message).await?; + let logs = match response { + Message::LogResponse(logs) => logs, + _ => bail!("Didn't get log response response in get_state"), + }; + + assert_eq!(logs.len(), 2, "Sould receive all log entries."); + + Ok(()) +} diff --git a/pueue/tests/helper/asserts.rs b/pueue/tests/helper/asserts.rs index 25de4a58..5b83ae4f 100644 --- a/pueue/tests/helper/asserts.rs +++ b/pueue/tests/helper/asserts.rs @@ -49,7 +49,7 @@ pub async fn assert_worker_envs( let response = send_message( shared, LogRequestMessage { - task_ids: vec![task_id], + tasks: TaskSelection::TaskIds(vec![task_id]), send_logs: true, lines: None, }, diff --git a/pueue/tests/helper/log.rs b/pueue/tests/helper/log.rs index 69971bb8..22b21e93 100644 --- a/pueue/tests/helper/log.rs +++ b/pueue/tests/helper/log.rs @@ -23,7 +23,7 @@ pub fn decompress_log(bytes: Vec) -> Result { /// `lines: None` requests all log lines. pub async fn get_task_log(shared: &Shared, task_id: usize, lines: Option) -> Result { let message = LogRequestMessage { - task_ids: vec![task_id], + tasks: TaskSelection::TaskIds(vec![task_id]), send_logs: true, lines, }; diff --git a/pueue_lib/src/network/message.rs b/pueue_lib/src/network/message.rs index 2c962786..507b490c 100644 --- a/pueue_lib/src/network/message.rs +++ b/pueue_lib/src/network/message.rs @@ -316,12 +316,12 @@ impl_into_message!(StreamRequestMessage, Message::StreamRequest); /// Request logs for specific tasks. /// -/// `task_ids` specifies the requested tasks. If none are given, all tasks are selected. +/// `tasks` specifies the requested tasks. /// `send_logs` Determines whether logs should be sent at all. /// `lines` Determines whether only a few lines of log should be returned. #[derive(PartialEq, Eq, Clone, Debug, Deserialize, Serialize)] pub struct LogRequestMessage { - pub task_ids: Vec, + pub tasks: TaskSelection, pub send_logs: bool, pub lines: Option, }