Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

change: Allow pueue log to filter by group and --all #549

Merged
merged 1 commit into from
Jun 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,13 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),

## \[Unreleased\]

### 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

Expand Down
8 changes: 8 additions & 0 deletions pueue/src/client/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -389,6 +389,14 @@
/// View the task output of these specific tasks.
task_ids: Vec<usize>,

/// View the outputs of this specific group's tasks.
#[arg(short, long)]
group: Option<String>,

/// Show the logs of all groups' tasks.
#[arg(short, long)]
all: bool,

Check warning on line 398 in pueue/src/client/cli.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/cli.rs#L398

Added line #L398 was not covered by tests

/// 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!
Expand Down
5 changes: 4 additions & 1 deletion pueue/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
};
Expand Down
30 changes: 20 additions & 10 deletions pueue/src/client/display/log/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,13 @@
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;
Expand Down Expand Up @@ -52,8 +53,10 @@
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");
Expand All @@ -67,15 +70,22 @@
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 {

Check warning on line 75 in pueue/src/client/display/log/mod.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/log/mod.rs#L75

Added line #L75 was not covered by tests
TaskSelection::TaskIds(_) => {
println!("There are no finished tasks for your specified ids");
return;

Check warning on line 78 in pueue/src/client/display/log/mod.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/log/mod.rs#L77-L78

Added lines #L77 - L78 were not covered by tests
}
TaskSelection::Group(group) => {
println!("There are no finished tasks for group '{group}'");
return;

Check warning on line 82 in pueue/src/client/display/log/mod.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/log/mod.rs#L80-L82

Added lines #L80 - L82 were not covered by tests
}
TaskSelection::All => {
println!("There are no finished tasks");
return;

Check warning on line 86 in pueue/src/client/display/log/mod.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/log/mod.rs#L85-L86

Added lines #L85 - L86 were not covered by tests
}
}
}

// Iterate over each task and print the respective log.
Expand Down
10 changes: 5 additions & 5 deletions pueue/src/daemon/network/message_handler/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,11 @@ use pueue_lib::state::SharedState;
/// Return tasks and their output to the client.
pub fn get_log(message: LogRequestMessage, state: &SharedState, settings: &Settings) -> 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();
Expand Down
72 changes: 70 additions & 2 deletions pueue/tests/daemon/integration/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
};
Expand Down Expand Up @@ -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,
};
Expand All @@ -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(())
}
2 changes: 1 addition & 1 deletion pueue/tests/helper/asserts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
},
Expand Down
2 changes: 1 addition & 1 deletion pueue/tests/helper/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ pub fn decompress_log(bytes: Vec<u8>) -> Result<String> {
/// `lines: None` requests all log lines.
pub async fn get_task_log(shared: &Shared, task_id: usize, lines: Option<usize>) -> Result<String> {
let message = LogRequestMessage {
task_ids: vec![task_id],
tasks: TaskSelection::TaskIds(vec![task_id]),
send_logs: true,
lines,
};
Expand Down
4 changes: 2 additions & 2 deletions pueue_lib/src/network/message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -300,12 +300,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<usize>,
pub tasks: TaskSelection,
pub send_logs: bool,
pub lines: Option<usize>,
}
Expand Down
Loading