Skip to content

Commit

Permalink
change: Print info/error output to stderr
Browse files Browse the repository at this point in the history
  • Loading branch information
Nukesor committed Feb 4, 2025
1 parent 0e53d6a commit 1b1a5ea
Show file tree
Hide file tree
Showing 20 changed files with 64 additions and 59 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ Upon updating Pueue and restarting the daemon, the previous state will be wiped,
- **Breaking**: Redesigned task editing process [#553](https://github.com/Nukesor/pueue/issues/553).
Pueue now allows editing all properties a task in one editor session. There're two modes to do so: `toml` and `files`.
- Revisited, fixed and cleaned up CLI help texts.
- Print most of Pueue's info/log messages to `stderr`. Only keep useful stuff like json and task log output on `stdout`.

### Add

Expand Down
4 changes: 2 additions & 2 deletions pueue/src/bin/pueued.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ async fn main() -> Result<()> {
// subcommand to install the service
#[cfg(target_os = "windows")]
if opt.service.is_some() {
println!("daemonize flag cannot be used with service subcommand");
eprintln!("daemonize flag cannot be used with service subcommand");
return Ok(());
}

Expand Down Expand Up @@ -120,7 +120,7 @@ fn fork_daemon(opt: &CliArguments) -> Result<()> {
let current_exe = if let Ok(path) = std::env::current_exe() {
path.to_string_lossy().clone().to_string()
} else {
println!("Couldn't detect path of current binary. Falling back to 'pueue' in $PATH");
eprintln!("Couldn't detect path of current binary. Falling back to 'pueue' in $PATH");

Check warning on line 123 in pueue/src/bin/pueued.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/bin/pueued.rs#L123

Added line #L123 was not covered by tests
"pueued".to_string()
};

Expand Down
4 changes: 2 additions & 2 deletions pueue/src/client/client.rs
Original file line number Diff line number Diff line change
Expand Up @@ -352,7 +352,7 @@ impl Client {
.map(|t| format!("task{t}"))
.collect::<Vec<String>>()
.join(", ");
println!("You are trying to {action}: {task_ids}",);
eprintln!("You are trying to {action}: {task_ids}",);

Check warning on line 355 in pueue/src/client/client.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/client.rs#L355

Added line #L355 was not covered by tests

let mut input = String::new();

Expand All @@ -364,7 +364,7 @@ impl Client {

match input.chars().next().unwrap() {
'N' | 'n' => {
println!("Aborted!");
eprintln!("Aborted!");

Check warning on line 367 in pueue/src/client/client.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/client.rs#L367

Added line #L367 was not covered by tests
std::process::exit(1);
}
'\n' | 'Y' | 'y' => {
Expand Down
2 changes: 1 addition & 1 deletion pueue/src/client/commands/restart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,7 @@ pub async fn restart(
println!("Restarted tasks: {:?}", filtered_tasks.matching_ids);
}
if !filtered_tasks.non_matching_ids.is_empty() {
println!(
eprintln!(

Check warning on line 168 in pueue/src/client/commands/restart.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/commands/restart.rs#L168

Added line #L168 was not covered by tests
"Couldn't restart tasks: {:?}",
filtered_tasks.non_matching_ids
);
Expand Down
2 changes: 1 addition & 1 deletion pueue/src/client/commands/wait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ pub async fn wait(
let tasks = get_tasks(&state, &selection);

if tasks.is_empty() {
println!("No tasks found for selection {selection:?}");
eprintln!("No tasks found for selection {selection:?}");

Check warning on line 61 in pueue/src/client/commands/wait.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/commands/wait.rs#L61

Added line #L61 was not covered by tests
return Ok(());
}

Expand Down
14 changes: 7 additions & 7 deletions pueue/src/client/display/follow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub async fn follow_local_task_logs(
// Ensure that it exists and is started.
loop {
let Some(task) = get_task(stream, task_id).await? else {
println!("Pueue: The task to be followed doesn't exist.");
eprintln!("Pueue: The task to be followed doesn't exist.");
std::process::exit(1);
};
// Task started up, we can start to follow.
Expand All @@ -42,7 +42,7 @@ pub async fn follow_local_task_logs(
let mut handle = match get_log_file_handle(task_id, pueue_directory) {
Ok(stdout) => stdout,
Err(err) => {
println!("Failed to get log file handles: {err}");
eprintln!("Failed to get log file handles: {err}");

Check warning on line 45 in pueue/src/client/display/follow.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/follow.rs#L45

Added line #L45 was not covered by tests
return Ok(());
}
};
Expand All @@ -58,7 +58,7 @@ pub async fn follow_local_task_logs(
// The loop following this section will then only copy those last lines to stdout.
if let Some(lines) = lines {
if let Err(err) = seek_to_last_lines(&mut handle, lines) {
println!("Error seeking to last lines from log: {err}");
eprintln!("Error seeking to last lines from log: {err}");

Check warning on line 61 in pueue/src/client/display/follow.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/follow.rs#L61

Added line #L61 was not covered by tests
}
}

Expand All @@ -73,17 +73,17 @@ pub async fn follow_local_task_logs(
loop {
// Check whether the file still exists. Exit if it doesn't.
if !path.exists() {
println!("Pueue: Log file has gone away. Has the task been removed?");
eprintln!("Pueue: Log file has gone away. Has the task been removed?");

Check warning on line 76 in pueue/src/client/display/follow.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/follow.rs#L76

Added line #L76 was not covered by tests
return Ok(());
}
// Read the next chunk of text from the last position.
if let Err(err) = io::copy(&mut handle, &mut stdout) {
println!("Pueue: Error while reading file: {err}");
eprintln!("Pueue: Error while reading file: {err}");

Check warning on line 81 in pueue/src/client/display/follow.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/follow.rs#L81

Added line #L81 was not covered by tests
return Ok(());
};
// Flush the stdout buffer to actually print the output.
if let Err(err) = stdout.flush() {
println!("Pueue: Error while flushing stdout: {err}");
eprintln!("Pueue: Error while flushing stdout: {err}");

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

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/follow.rs#L86

Added line #L86 was not covered by tests
return Ok(());
};

Expand All @@ -94,7 +94,7 @@ pub async fn follow_local_task_logs(
// In case either is not, exit.
if (last_check % task_check_interval) == 0 {
let Some(task) = get_task(stream, task_id).await? else {
println!("Pueue: The followed task has been removed.");
eprintln!("Pueue: The followed task has been removed.");

Check warning on line 97 in pueue/src/client/display/follow.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/follow.rs#L97

Added line #L97 was not covered by tests
std::process::exit(1);
};
// Task exited by itself. We can stop following.
Expand Down
8 changes: 4 additions & 4 deletions pueue/src/client/display/log/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ pub fn print_local_log(
let mut file = match get_log_file_handle(task_id, &settings.shared.pueue_directory()) {
Ok(file) => file,
Err(err) => {
println!("Failed to get log file handle: {err}");
eprintln!("Failed to get log file handle: {err}");

Check warning on line 22 in pueue/src/client/display/log/local.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/log/local.rs#L22

Added line #L22 was not covered by tests
return;
}
};
Expand Down Expand Up @@ -47,7 +47,7 @@ fn print_local_file(stdout: &mut Stdout, file: &mut File, lines: &Option<usize>,
match seek_to_last_lines(file, *lines) {
Ok(complete) => output_complete = complete,
Err(err) => {
println!("Failed reading local log file: {err}");
eprintln!("Failed reading local log file: {err}");

Check warning on line 50 in pueue/src/client/display/log/local.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/log/local.rs#L50

Added line #L50 was not covered by tests
return;
}
}
Expand All @@ -61,11 +61,11 @@ fn print_local_file(stdout: &mut Stdout, file: &mut File, lines: &Option<usize>,
}

// Print a newline between the task information and the first output.
println!("\n{header}{line_info}");
eprintln!("\n{header}{line_info}");

// Print everything
if let Err(err) = io::copy(file, stdout) {
println!("Failed reading local log file: {err}");
eprintln!("Failed reading local log file: {err}");

Check warning on line 68 in pueue/src/client/display/log/local.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/log/local.rs#L68

Added line #L68 was not covered by tests
};
}
}
Expand Down
10 changes: 5 additions & 5 deletions pueue/src/client/display/log/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,15 +74,15 @@ pub fn print_logs(
if task_logs.is_empty() {
match selection {
TaskSelection::TaskIds(_) => {
println!("There are no finished tasks for your specified ids");
eprintln!("There are no finished tasks for your specified ids");

Check warning on line 77 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

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

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

View check run for this annotation

Codecov / codecov/patch

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

Added line #L81 was not covered by tests
return;
}
TaskSelection::All => {
println!("There are no finished tasks");
eprintln!("There are no finished tasks");

Check warning on line 85 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

Added line #L85 was not covered by tests
return;
}
}
Expand Down Expand Up @@ -174,7 +174,7 @@ fn print_task_info(task: &Task, style: &OutputStyle) {
if style.enabled {
table.enforce_styling();
}
println!("{table}");
eprintln!("{table}");

// All other information is aligned and styled by using a separate table.
let mut table = Table::new();
Expand Down Expand Up @@ -218,5 +218,5 @@ fn print_task_info(task: &Task, style: &OutputStyle) {
first_column.set_cell_alignment(CellAlignment::Right);
first_column.set_padding((0, 0));

println!("{table}");
eprintln!("{table}");
}
2 changes: 1 addition & 1 deletion pueue/src/client/display/log/remote.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ pub fn print_remote_log(task_log: &TaskLogMessage, style: &OutputStyle, lines: O
println!("\n{header}{line_info}");

if let Err(err) = decompress_and_print_remote_log(bytes) {
println!("Error while parsing stdout: {err}");
eprintln!("Error while parsing stdout: {err}");

Check warning on line 29 in pueue/src/client/display/log/remote.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/client/display/log/remote.rs#L29

Added line #L29 was not covered by tests
}
}
}
Expand Down
2 changes: 1 addition & 1 deletion pueue/src/client/display/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,5 @@ pub fn print_success(_style: &OutputStyle, message: &str) {
/// Used to style any generic failure message from the daemon.
pub fn print_error(style: &OutputStyle, message: &str) {
let styled = style.style_text(message, Some(Color::Red), None);
println!("{styled}");
eprintln!("{styled}");
}
8 changes: 4 additions & 4 deletions pueue/src/daemon/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,14 +155,14 @@ fn setup_signal_panic_handling(settings: &Settings, state: SharedState) -> Resul

// Cleanup the pid file
if let Err(error) = pid::cleanup_pid_file(&settings_clone.shared.pid_path()) {
println!("Failed to cleanup pid after panic.");
println!("{error}");
eprintln!("Failed to cleanup pid after panic.");
eprintln!("{error}");

Check warning on line 159 in pueue/src/daemon/mod.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/daemon/mod.rs#L158-L159

Added lines #L158 - L159 were not covered by tests
}

// Remove the unix socket.
if let Err(error) = socket_cleanup(&settings_clone.shared) {
println!("Failed to cleanup socket after panic.");
println!("{error}");
eprintln!("Failed to cleanup socket after panic.");
eprintln!("{error}");

Check warning on line 165 in pueue/src/daemon/mod.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/daemon/mod.rs#L164-L165

Added lines #L164 - L165 were not covered by tests
}

std::process::exit(1);
Expand Down
2 changes: 1 addition & 1 deletion pueue/src/daemon/network/message_handler/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,7 @@ pub async fn follow_log(
// The loop following this section will then only copy those last lines to stdout.
if let Some(lines) = message.lines {
if let Err(err) = seek_to_last_lines(&mut handle, lines) {
println!("Error seeking to last lines from log: {err}");
eprintln!("Error seeking to last lines from log: {err}");

Check warning on line 143 in pueue/src/daemon/network/message_handler/log.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/daemon/network/message_handler/log.rs#L143

Added line #L143 was not covered by tests
}
}

Expand Down
8 changes: 4 additions & 4 deletions pueue/src/daemon/service.rs
Original file line number Diff line number Diff line change
Expand Up @@ -191,8 +191,8 @@ pub fn start_service() -> Result<()> {
service.start::<String>(&[])?;
println!("Successfully started service");
}
ServiceState::StartPending => println!("Service is already starting"),
ServiceState::Running => println!("Service is already running"),
ServiceState::StartPending => eprintln!("Service is already starting"),
ServiceState::Running => eprintln!("Service is already running"),

_ => (),
}
Expand All @@ -211,8 +211,8 @@ pub fn stop_service() -> Result<()> {
let service = service_manager.open_service(SERVICE_NAME, service_access)?;

match service.query_status()?.current_state {
ServiceState::Stopped => println!("Service is already stopped"),
ServiceState::StartPending => println!("Service cannot stop because it is starting (please wait until it fully started to stop it)"),
ServiceState::Stopped => eprintln!("Service is already stopped"),
ServiceState::StartPending => eprintln!("Service cannot stop because it is starting (please wait until it fully started to stop it)"),
ServiceState::Running => {
service.stop()?;
println!("Successfully stopped service");
Expand Down
8 changes: 4 additions & 4 deletions pueue/src/daemon/task_handler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,14 +80,14 @@ fn handle_shutdown(settings: &Settings, state: &mut LockedState) {

// Remove the unix socket.
if let Err(error) = socket_cleanup(&settings.shared) {
println!("Failed to cleanup socket during shutdown.");
println!("{error}");
eprintln!("Failed to cleanup socket during shutdown.");
eprintln!("{error}");

Check warning on line 84 in pueue/src/daemon/task_handler.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/daemon/task_handler.rs#L83-L84

Added lines #L83 - L84 were not covered by tests
}

// Cleanup the pid file
if let Err(error) = cleanup_pid_file(&settings.shared.pid_path()) {
println!("Failed to cleanup pid during shutdown.");
println!("{error}");
eprintln!("Failed to cleanup pid during shutdown.");
eprintln!("{error}");

Check warning on line 90 in pueue/src/daemon/task_handler.rs

View check run for this annotation

Codecov / codecov/patch

pueue/src/daemon/task_handler.rs#L89-L90

Added lines #L89 - L90 were not covered by tests
}

// Actually exit the program the way we're supposed to.
Expand Down
10 changes: 7 additions & 3 deletions pueue/tests/client/helper/compare_output.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
use std::collections::HashMap;
use std::process::Output;

use anyhow::{bail, Context, Result};
use chrono::Local;
Expand Down Expand Up @@ -84,16 +85,19 @@ pub async fn get_task_context(settings: &Settings) -> Result<HashMap<String, Str
/// and compares it with a given process's `stdout`.
pub fn assert_template_matches(
name: &str,
stdout: Vec<u8>,
output: Output,
context: HashMap<String, String>,
) -> Result<()> {
let mut combined_output = output.stderr.clone();
combined_output.append(&mut output.stdout.clone());

let path = PathBuf::from(env!("CARGO_MANIFEST_DIR"))
.join("tests")
.join("client")
.join("_templates")
.join(name);

let actual = String::from_utf8(stdout).context("Got invalid utf8 as stdout!")?;
let actual = String::from_utf8(combined_output).context("Got invalid utf8 as output!")?;

let Ok(mut expected) = read_to_string(&path) else {
println!("Actual output:\n{actual}");
Expand All @@ -119,7 +123,7 @@ pub fn assert_template_matches(
}

/// Convenience wrapper to compare process stdout with snapshots.
pub fn assert_snapshot_matches_stdout(name: &str, stdout: Vec<u8>) -> Result<()> {
pub fn assert_snapshot_matches_output(name: &str, stdout: Vec<u8>) -> Result<()> {
let actual = String::from_utf8(stdout).context("Got invalid utf8 as stdout!")?;
assert_snapshot_matches(name, actual)
}
Expand Down
8 changes: 4 additions & 4 deletions pueue/tests/client/integration/follow.rs
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ async fn default(#[case] read_local_logs: bool) -> Result<()> {
// This will result in the client receiving the streamed output until the task finished.
let output = run_client_command(shared, &["follow"])?;

assert_snapshot_matches_stdout("follow__default", output.stdout)?;
assert_snapshot_matches_output("follow__default", output.stdout)?;

Ok(())
}
Expand All @@ -58,7 +58,7 @@ async fn last_lines(#[case] read_local_logs: bool) -> Result<()> {
// Follow the task, but only print the last 4 lines of the output.
let output = run_client_command(shared, &["follow", "--lines=4"])?;

assert_snapshot_matches_stdout("follow__last_lines", output.stdout)?;
assert_snapshot_matches_output("follow__last_lines", output.stdout)?;

Ok(())
}
Expand All @@ -79,7 +79,7 @@ async fn wait_for_task(#[case] read_local_logs: bool) -> Result<()> {
// Wait for the task to start and follow until it finisheds.
let output = run_client_command(shared, &["follow", "0"])?;

assert_snapshot_matches_stdout("follow__default", output.stdout)?;
assert_snapshot_matches_output("follow__default", output.stdout)?;

Ok(())
}
Expand All @@ -98,7 +98,7 @@ async fn fail_on_non_existing(#[case] read_local_logs: bool) -> Result<()> {
// The client should exit with exit code `1`.
let output = run_client_command(shared, &["follow", "0"])?;
assert!(!output.status.success(), "follow got an unexpected exit 0");
assert_snapshot_matches_stdout("follow__fail_on_non_existing", output.stdout)?;
assert_snapshot_matches_output("follow__fail_on_non_existing", output.stderr)?;

Ok(())
}
Expand Down
4 changes: 2 additions & 2 deletions pueue/tests/client/integration/group.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ async fn default() -> Result<()> {
// Get the group status output
let output = run_client_command(shared, &["group"])?;

assert_snapshot_matches_stdout("group__default", output.stdout)?;
assert_snapshot_matches_output("group__default", output.stdout)?;

Ok(())
}
Expand Down Expand Up @@ -48,7 +48,7 @@ async fn colored() -> Result<()> {
// Get the group status output
let output = run_client_command(shared, &["--color", "always", "group"])?;

assert_snapshot_matches_stdout("group__colored", output.stdout)?;
assert_snapshot_matches_output("group__colored", output.stdout)?;

Ok(())
}
Expand Down
8 changes: 4 additions & 4 deletions pueue/tests/client/integration/log.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ async fn read(#[case] read_local_logs: bool) -> Result<()> {
let output = run_client_command(shared, &["log"])?;

let context = get_task_context(&daemon.settings).await?;
assert_template_matches("log__default", output.stdout, context)?;
assert_template_matches("log__default", output, context)?;

Ok(())
}
Expand Down Expand Up @@ -65,7 +65,7 @@ async fn read_truncated(#[case] read_local_logs: bool) -> Result<()> {
let output = run_client_command(shared, &["log", "--lines=5"])?;

let context = get_task_context(&daemon.settings).await?;
assert_template_matches("log__last_lines", output.stdout, context)?;
assert_template_matches("log__last_lines", output, context)?;

Ok(())
}
Expand All @@ -83,7 +83,7 @@ async fn task_with_label() -> Result<()> {
let output = run_client_command(shared, &["log"])?;

let context = get_task_context(&daemon.settings).await?;
assert_template_matches("log__with_label", output.stdout, context)?;
assert_template_matches("log__with_label", output, context)?;

Ok(())
}
Expand All @@ -101,7 +101,7 @@ async fn colored() -> Result<()> {
let output = run_client_command(shared, &["--color", "always", "log"])?;

let context = get_task_context(&daemon.settings).await?;
assert_template_matches("log__colored", output.stdout, context)?;
assert_template_matches("log__colored", output, context)?;

Ok(())
}
Expand Down
Loading

0 comments on commit 1b1a5ea

Please sign in to comment.