From d5801efd6e9d8c31dc86b13f3e5001d9d3207c51 Mon Sep 17 00:00:00 2001 From: Miles Johnson Date: Wed, 11 Sep 2024 16:25:27 -0700 Subject: [PATCH] new: Improve task output prefixing. --- CHANGELOG.md | 1 + crates/action-context/src/lib.rs | 9 ++++ crates/cli/tests/run_test.rs | 2 +- .../run_test__output_styles__buffer.snap | 4 +- .../run_test__output_styles__stream.snap | 4 +- .../console-reporter/src/default_reporter.rs | 54 +++++++------------ crates/console/src/buffer.rs | 15 ++++++ crates/console/src/reporter.rs | 1 + crates/process/src/async_command.rs | 12 ++--- crates/process/src/command.rs | 21 ++------ crates/process/src/command_inspector.rs | 4 +- crates/target/src/target.rs | 18 ++++++- crates/task-runner/src/command_executor.rs | 39 +++++--------- crates/task-runner/src/task_runner.rs | 53 +++++++++--------- .../tests/command_executor_test.rs | 30 ++++++----- crates/task-runner/tests/task_runner_test.rs | 42 +++++++-------- legacy/bun/lang/src/bun_lockb.rs | 2 +- legacy/node/lang/src/yarn/mod.rs | 2 +- 18 files changed, 154 insertions(+), 159 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ee59fa0cc89..cb8305e76d4 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ #### 🚀 Updates +- Updated cached task outputs to now be prefixed with the task target when printing to the console. - Updated Bun/Yarn lockfile parsing to temporarily log a warning on parse failure instead of exiting with an error. This change was made as there are currently no actionable or human-readable error messages. diff --git a/crates/action-context/src/lib.rs b/crates/action-context/src/lib.rs index f58ce3c1d88..9993f351629 100644 --- a/crates/action-context/src/lib.rs +++ b/crates/action-context/src/lib.rs @@ -81,6 +81,15 @@ impl ActionContext { mutex } + pub fn get_target_prefix>(&self, target: T) -> String { + target.as_ref().to_prefix( + self.primary_targets + .iter() + .map(|target| target.id.len()) + .max(), + ) + } + pub fn get_target_states(&self) -> FxHashMap { let mut map = FxHashMap::default(); self.target_states.scan(|k, v| { diff --git a/crates/cli/tests/run_test.rs b/crates/cli/tests/run_test.rs index a286fdc2275..2a08caa04c9 100644 --- a/crates/cli/tests/run_test.rs +++ b/crates/cli/tests/run_test.rs @@ -192,7 +192,7 @@ fn disambiguates_same_tasks_with_diff_args_envs() { // The order changes so we can't snapshot it assert!(predicate::str::contains("taskDeps:base") - .count(8) // 4 start + 4 end + .count(11) // 4 start + 4 end + 3 output prefixes .eval(&output)); assert!(predicate::str::contains("a b c").eval(&output)); assert!(predicate::str::contains("TEST_VAR=value").eval(&output)); diff --git a/crates/cli/tests/snapshots/run_test__output_styles__buffer.snap b/crates/cli/tests/snapshots/run_test__output_styles__buffer.snap index 217887c6d37..0707553431d 100644 --- a/crates/cli/tests/snapshots/run_test__output_styles__buffer.snap +++ b/crates/cli/tests/snapshots/run_test__output_styles__buffer.snap @@ -4,11 +4,11 @@ expression: assert.output() --- ▪▪▪▪ npm install ▪▪▪▪ outputStyles:buffer -stdout + outputStyles:buffer | stdout ▪▪▪▪ outputStyles:buffer (100ms) ▪▪▪▪ outputStyles:bufferPrimary (no op) Tasks: 2 completed Time: 100ms -stderr + outputStyles:buffer | stderr diff --git a/crates/cli/tests/snapshots/run_test__output_styles__stream.snap b/crates/cli/tests/snapshots/run_test__output_styles__stream.snap index 70381d15cad..6dde90fb130 100644 --- a/crates/cli/tests/snapshots/run_test__output_styles__stream.snap +++ b/crates/cli/tests/snapshots/run_test__output_styles__stream.snap @@ -4,11 +4,11 @@ expression: assert.output() --- ▪▪▪▪ npm install ▪▪▪▪ outputStyles:stream -outputStyles:stream | stdout + outputStyles:stream | stdout ▪▪▪▪ outputStyles:stream (100ms) ▪▪▪▪ outputStyles:streamPrimary (no op) Tasks: 2 completed Time: 100ms -outputStyles:stream | stderr + outputStyles:stream | stderr diff --git a/crates/console-reporter/src/default_reporter.rs b/crates/console-reporter/src/default_reporter.rs index 9c839e3403a..e8d49e38f06 100644 --- a/crates/console-reporter/src/default_reporter.rs +++ b/crates/console-reporter/src/default_reporter.rs @@ -102,20 +102,26 @@ impl DefaultReporter { operation: &Operation, item: &TaskReportItem, ) -> miette::Result<()> { - let print_stdout = || -> miette::Result<()> { + let print = || -> miette::Result<()> { if let Some(output) = operation.get_output() { if let Some(out) = &output.stdout { - self.out.write_line(out.trim())?; + if !out.is_empty() { + if let Some(prefix) = &item.output_prefix { + self.out.write_line_with_prefix(out.trim(), prefix)?; + } else { + self.out.write_line(out.trim())?; + } + } } - } - Ok(()) - }; - - let print_stderr = || -> miette::Result<()> { - if let Some(output) = operation.get_output() { - if let Some(out) = &output.stderr { - self.err.write_line(out.trim())?; + if let Some(err) = &output.stderr { + if !err.is_empty() { + if let Some(prefix) = &item.output_prefix { + self.err.write_line_with_prefix(err.trim(), prefix)?; + } else { + self.err.write_line(err.trim())?; + } + } } } @@ -126,8 +132,7 @@ impl DefaultReporter { // Only show output on failure Some(TaskOutputStyle::BufferOnlyFailure) => { if operation.has_failed() { - print_stdout()?; - print_stderr()?; + print()?; } } // Only show the hash @@ -141,8 +146,7 @@ impl DefaultReporter { Some(TaskOutputStyle::None) => {} // Show output on both success and failure _ => { - print_stdout()?; - print_stderr()?; + print()?; } }; @@ -157,26 +161,7 @@ impl DefaultReporter { if let Some(attempt) = action.operations.get_last_execution() { if attempt.has_failed() { - let mut has_stdout = false; - - if let Some(output) = attempt.get_output() { - if let Some(stdout) = &output.stdout { - if !stdout.is_empty() { - has_stdout = true; - self.out.write_line(stdout.trim())?; - } - } - - if let Some(stderr) = &output.stderr { - if has_stdout { - self.out.write_newline()?; - } - - if !stderr.is_empty() { - self.out.write_line(stderr.trim())?; - } - } - } + self.print_operation_output(attempt, &TaskReportItem::default())?; } } @@ -414,7 +399,6 @@ impl Reporter for DefaultReporter { // If cached, the finished event above is not fired, // so handle printing the captured logs here! if operation.is_cached() && operation.has_output() { - self.out.write_newline()?; self.print_operation_output(operation, item)?; } diff --git a/crates/console/src/buffer.rs b/crates/console/src/buffer.rs index 5989d675c31..bec3db5847e 100644 --- a/crates/console/src/buffer.rs +++ b/crates/console/src/buffer.rs @@ -153,6 +153,21 @@ impl ConsoleBuffer { }) } + pub fn write_line_with_prefix>( + &self, + data: T, + prefix: &str, + ) -> miette::Result<()> { + let data = data.as_ref(); + let lines = data + .lines() + .map(|line| format!("{prefix}{line}")) + .collect::>() + .join("\n"); + + self.write_line(lines) + } + pub fn write_newline(&self) -> miette::Result<()> { self.write("\n") } diff --git a/crates/console/src/reporter.rs b/crates/console/src/reporter.rs index dc10e5d4ac3..627a240cd63 100644 --- a/crates/console/src/reporter.rs +++ b/crates/console/src/reporter.rs @@ -18,6 +18,7 @@ pub struct TaskReportItem { pub attempt_current: u8, pub attempt_total: u8, pub hash: Option, + pub output_prefix: Option, pub output_streamed: bool, pub output_style: Option, } diff --git a/crates/process/src/async_command.rs b/crates/process/src/async_command.rs index 2cacfa3e62b..3e2a5e06bdf 100644 --- a/crates/process/src/async_command.rs +++ b/crates/process/src/async_command.rs @@ -158,10 +158,10 @@ impl<'cmd> AsyncCommand<'cmd> { let mut captured_lines = vec![]; while let Ok(Some(line)) = lines.next_line().await { - let _ = if stderr_prefix.is_empty() { - stderr_stream.write_line(&line) + let _ = if let Some(prefix) = &*stderr_prefix { + stderr_stream.write_line_with_prefix(&line, prefix) } else { - stderr_stream.write_line(format!("{stderr_prefix}{line}")) + stderr_stream.write_line(&line) }; captured_lines.push(line); @@ -178,10 +178,10 @@ impl<'cmd> AsyncCommand<'cmd> { let mut captured_lines = vec![]; while let Ok(Some(line)) = lines.next_line().await { - let _ = if stdout_prefix.is_empty() { - stdout_stream.write_line(&line) + let _ = if let Some(prefix) = &*stdout_prefix { + stdout_stream.write_line_with_prefix(&line, prefix) } else { - stdout_stream.write_line(format!("{stdout_prefix}{line}")) + stdout_stream.write_line(&line) }; captured_lines.push(line); diff --git a/crates/process/src/command.rs b/crates/process/src/command.rs index ee2ea1ff053..822bcdbe4c5 100644 --- a/crates/process/src/command.rs +++ b/crates/process/src/command.rs @@ -1,5 +1,5 @@ use crate::{async_command::AsyncCommand, command_inspector::CommandInspector, shell::Shell}; -use moon_common::{color, is_test_env}; +use moon_common::color; use moon_console::Console; use rustc_hash::FxHashMap; use std::{ @@ -187,23 +187,8 @@ impl Command { self } - pub fn set_prefix(&mut self, prefix: &str, width: Option) -> &mut Command { - let label = if let Some(width) = width { - format!("{: >width$}", prefix, width = width) - } else { - prefix.to_owned() - }; - - if is_test_env() { - self.prefix = Some(format!("{label} | ")); - } else { - self.prefix = Some(format!( - "{} {} ", - color::log_target(label), - color::muted("|") - )); - } - + pub fn set_prefix(&mut self, prefix: &str) -> &mut Command { + self.prefix = Some(prefix.to_owned()); self } diff --git a/crates/process/src/command_inspector.rs b/crates/process/src/command_inspector.rs index 5f1a245ce49..6514216e023 100644 --- a/crates/process/src/command_inspector.rs +++ b/crates/process/src/command_inspector.rs @@ -151,8 +151,8 @@ impl<'cmd> CommandInspector<'cmd> { .get_or_init(|| CommandLine::new(self.command)) } - pub fn get_prefix(&self) -> String { - self.command.prefix.clone().unwrap_or_default() + pub fn get_prefix(&self) -> Option { + self.command.prefix.clone() } pub fn get_workspace_root(&self) -> PathBuf { diff --git a/crates/target/src/target.rs b/crates/target/src/target.rs index c7746e2431a..42a168a7c3d 100644 --- a/crates/target/src/target.rs +++ b/crates/target/src/target.rs @@ -1,6 +1,6 @@ use crate::target_error::TargetError; use crate::target_scope::TargetScope; -use moon_common::{Id, ID_CHARS}; +use moon_common::{color, Id, ID_CHARS}; use once_cell::sync::Lazy; use regex::Regex; use schematic::{Schema, SchemaBuilder, Schematic}; @@ -112,6 +112,22 @@ impl Target { &self.id } + pub fn to_prefix(&self, width: Option) -> String { + let prefix = self.as_str(); + + let label = if let Some(width) = width { + format!("{: >width$}", prefix, width = width) + } else { + prefix.to_owned() + }; + + if color::no_color() { + format!("{label} | ") + } else { + format!("{} {} ", color::log_target(label), color::muted("|")) + } + } + pub fn is_all_task(&self, task_id: &str) -> bool { if matches!(&self.scope, TargetScope::All) { return if let Some(id) = task_id.strip_prefix(':') { diff --git a/crates/task-runner/src/command_executor.rs b/crates/task-runner/src/command_executor.rs index 5070e034bb5..3074b20e82e 100644 --- a/crates/task-runner/src/command_executor.rs +++ b/crates/task-runner/src/command_executor.rs @@ -21,7 +21,6 @@ fn is_ci_env() -> bool { pub struct CommandExecuteResult { pub attempts: OperationList, pub error: Option, - pub report_item: TaskReportItem, pub run_state: TargetState, } @@ -74,14 +73,12 @@ impl<'task> CommandExecutor<'task> { pub async fn execute( mut self, context: &ActionContext, - hash: Option<&str>, + report_item: &mut TaskReportItem, ) -> miette::Result { // Prepare state for the executor, and each attempt - let mut report_item = self.prepate_state(context); let mut run_state = TargetState::Failed; - // Hash is empty if cache is disabled - report_item.hash = hash.map(|h| h.to_string()); + self.prepate_state(context, report_item); // For long-running process, log a message on an interval to indicate it's still running self.start_monitoring(); @@ -148,7 +145,7 @@ impl<'task> CommandExecutor<'task> { "Task was successful, proceeding to next step", ); - run_state = TargetState::from_hash(hash); + run_state = TargetState::from_hash(report_item.hash.as_deref()); break None; } // Unsuccessful execution (maybe flaky), attempt again @@ -201,7 +198,6 @@ impl<'task> CommandExecutor<'task> { Ok(CommandExecuteResult { attempts: self.attempts.take(), error: execution_error, - report_item, run_state, }) } @@ -232,8 +228,9 @@ impl<'task> CommandExecutor<'task> { } } - fn prepate_state(&mut self, context: &ActionContext) -> TaskReportItem { + fn prepate_state(&mut self, context: &ActionContext, report_item: &mut TaskReportItem) { let is_primary = context.is_primary_target(&self.task.target); + let mut output_prefix = None; // When a task is configured as local (no caching), or the interactive flag is passed, // we don't "capture" stdout/stderr (which breaks stdin) and let it stream natively. @@ -251,27 +248,17 @@ impl<'task> CommandExecutor<'task> { // Transitive targets may run concurrently, so differentiate them with a prefix. if !is_primary || is_ci_env() || context.primary_targets.len() > 1 { - let prefix_max_width = if context.primary_targets.len() > 1 { - context - .primary_targets - .iter() - .map(|target| target.id.len()) - .max() - } else { - None - }; + let prefix = context.get_target_prefix(&self.task.target); - self.command - .set_prefix(&self.task.target.id, prefix_max_width); - } + self.command.set_prefix(&prefix); - TaskReportItem { - attempt_current: self.attempt_index, - attempt_total: self.attempt_total, - hash: None, - output_streamed: self.stream, - output_style: self.task.options.output_style, + output_prefix = Some(prefix); } + + report_item.attempt_current = self.attempt_index; + report_item.attempt_total = self.attempt_total; + report_item.output_prefix = output_prefix; + report_item.output_streamed = self.stream; } fn get_command_line(&self, context: &ActionContext) -> String { diff --git a/crates/task-runner/src/task_runner.rs b/crates/task-runner/src/task_runner.rs index 9048b92186e..07589dda9ff 100644 --- a/crates/task-runner/src/task_runner.rs +++ b/crates/task-runner/src/task_runner.rs @@ -35,11 +35,11 @@ pub struct TaskRunner<'task> { archiver: OutputArchiver<'task>, hydrater: OutputHydrater<'task>, - report_item: Option, // Public for testing pub cache: CacheItem, pub operations: OperationList, + pub report_item: TaskReportItem, } impl<'task> TaskRunner<'task> { @@ -72,8 +72,11 @@ impl<'task> TaskRunner<'task> { hydrater: OutputHydrater { app, task }, platform_manager: PlatformManager::read(), project, + report_item: TaskReportItem { + output_style: task.options.output_style, + ..Default::default() + }, task, - report_item: None, app, operations: OperationList::default(), }) @@ -104,13 +107,15 @@ impl<'task> TaskRunner<'task> { let hash = self.generate_hash(context, node).await?; + self.report_item.hash = Some(hash.clone()); + // Exit early if this build has already been cached/hashed if self.hydrate(context, &hash).await? { return Ok(Some(hash)); } // Otherwise build and execute the command as a child process - self.execute(context, node, Some(&hash)).await?; + self.execute(context, node).await?; // If we created outputs, archive them into the cache self.archive(&hash).await?; @@ -124,7 +129,7 @@ impl<'task> TaskRunner<'task> { ); // Otherwise build and execute the command as a child process - self.execute(context, node, None).await?; + self.execute(context, node).await?; Ok(None) } @@ -140,23 +145,14 @@ impl<'task> TaskRunner<'task> { self.cache.data.last_run_time = now_millis(); self.cache.save()?; - let mut item = self.report_item.clone().unwrap_or_else(|| { - // When the task is cached, we don't have the original report, - // so create an empty one with necessary fields - TaskReportItem { - output_style: self.task.options.output_style, - ..Default::default() - } - }); - match result { Ok(maybe_hash) => { - item.hash = maybe_hash.clone(); + self.report_item.hash = maybe_hash.clone(); self.app.console.reporter.on_task_completed( &self.task.target, &self.operations, - &item, + &self.report_item, None, )?; @@ -172,7 +168,7 @@ impl<'task> TaskRunner<'task> { self.app.console.reporter.on_task_completed( &self.task.target, &self.operations, - &item, + &self.report_item, Some(&error), )?; @@ -414,11 +410,10 @@ impl<'task> TaskRunner<'task> { &mut self, context: &ActionContext, node: &ActionNode, - hash: Option<&str>, ) -> miette::Result<()> { // If the task is a no-operation, we should exit early if self.task.is_no_op() { - self.skip_no_op(context, hash)?; + self.skip_no_op(context)?; return Ok(()); } @@ -461,9 +456,9 @@ impl<'task> TaskRunner<'task> { // This execution is required within this block so that the // guard above isn't immediately dropped! - executor.execute(context, hash).await? + executor.execute(context, &mut self.report_item).await? } else { - executor.execute(context, hash).await? + executor.execute(context, &mut self.report_item).await? }; if let Some(last_attempt) = result.attempts.get_last_execution() { @@ -472,7 +467,6 @@ impl<'task> TaskRunner<'task> { // Extract the attempts from the result self.operations.merge(result.attempts); - self.report_item = Some(result.report_item); // Update the action state based on the result context.set_target_state(&self.task.target, result.run_state); @@ -516,11 +510,7 @@ impl<'task> TaskRunner<'task> { } #[instrument(skip(self, context))] - pub fn skip_no_op( - &mut self, - context: &ActionContext, - hash: Option<&str>, - ) -> miette::Result<()> { + pub fn skip_no_op(&mut self, context: &ActionContext) -> miette::Result<()> { debug!( task = self.task.target.as_str(), "Skipping task as its a no-operation" @@ -531,7 +521,10 @@ impl<'task> TaskRunner<'task> { ActionStatus::Passed, )); - context.set_target_state(&self.task.target, TargetState::from_hash(hash)); + context.set_target_state( + &self.task.target, + TargetState::from_hash(self.report_item.hash.as_deref()), + ); Ok(()) } @@ -608,6 +601,9 @@ impl<'task> TaskRunner<'task> { "Ran cache hydration operation" ); + // Fill in these values since the command executor does not run! + self.report_item.output_prefix = Some(context.get_target_prefix(&self.task.target)); + self.load_logs(&mut operation)?; operation.finish(match from { @@ -640,7 +636,6 @@ impl<'task> TaskRunner<'task> { } let mut operation = Operation::task_execution(&self.task.command); - let default_item = TaskReportItem::default(); if let (Some(output), Some(error)) = (operation.get_output_mut(), report) { output.exit_code = Some(-1); @@ -652,7 +647,7 @@ impl<'task> TaskRunner<'task> { self.app.console.reporter.on_task_finished( &self.task.target, &operation, - self.report_item.as_ref().unwrap_or(&default_item), + &self.report_item, report, )?; diff --git a/crates/task-runner/tests/command_executor_test.rs b/crates/task-runner/tests/command_executor_test.rs index 9d80ec56892..acbf9e6ce8e 100644 --- a/crates/task-runner/tests/command_executor_test.rs +++ b/crates/task-runner/tests/command_executor_test.rs @@ -2,6 +2,7 @@ mod utils; use moon_action::ActionStatus; use moon_action_context::{ActionContext, TargetState}; +use moon_console::TaskReportItem; use utils::*; mod command_executor { @@ -11,19 +12,21 @@ mod command_executor { async fn returns_attempt_on_success() { let container = TaskRunnerContainer::new_os("runner").await; let context = ActionContext::default(); + let mut item = TaskReportItem::default(); + item.hash = Some("hash123".into()); let result = container .create_command_executor("success", &context) .await - .execute(&context, Some("hash123")) + .execute(&context, &mut item) .await .unwrap(); // Check state + assert_eq!(item.hash.unwrap(), "hash123"); + assert_eq!(item.attempt_current, 1); + assert_eq!(item.attempt_total, 1); assert!(result.error.is_none()); - assert_eq!(result.report_item.hash.unwrap(), "hash123"); - assert_eq!(result.report_item.attempt_current, 1); - assert_eq!(result.report_item.attempt_total, 1); assert_eq!(result.run_state, TargetState::Passed("hash123".into())); // Check attempt @@ -42,19 +45,21 @@ mod command_executor { async fn returns_attempt_on_failure() { let container = TaskRunnerContainer::new_os("runner").await; let context = ActionContext::default(); + let mut item = TaskReportItem::default(); + item.hash = Some("hash123".into()); let result = container .create_command_executor("failure", &context) .await - .execute(&context, Some("hash123")) + .execute(&context, &mut item) .await .unwrap(); // Check state + assert_eq!(item.hash.unwrap(), "hash123"); + assert_eq!(item.attempt_current, 1); + assert_eq!(item.attempt_total, 1); assert!(result.error.is_none()); - assert_eq!(result.report_item.hash.unwrap(), "hash123"); - assert_eq!(result.report_item.attempt_current, 1); - assert_eq!(result.report_item.attempt_total, 1); assert_eq!(result.run_state, TargetState::Failed); // Check attempt @@ -72,19 +77,20 @@ mod command_executor { async fn returns_attempts_for_each_retry() { let container = TaskRunnerContainer::new_os("runner").await; let context = ActionContext::default(); + let mut item = TaskReportItem::default(); let result = container .create_command_executor("retry", &context) .await - .execute(&context, None) + .execute(&context, &mut item) .await .unwrap(); // Check state + assert!(item.hash.is_none()); + assert_eq!(item.attempt_current, 4); + assert_eq!(item.attempt_total, 4); assert!(result.error.is_none()); - assert!(result.report_item.hash.is_none()); - assert_eq!(result.report_item.attempt_current, 4); - assert_eq!(result.report_item.attempt_total, 4); assert_eq!(result.run_state, TargetState::Failed); // Check attempt diff --git a/crates/task-runner/tests/task_runner_test.rs b/crates/task-runner/tests/task_runner_test.rs index fc405adc45b..00bc3a588b1 100644 --- a/crates/task-runner/tests/task_runner_test.rs +++ b/crates/task-runner/tests/task_runner_test.rs @@ -660,10 +660,8 @@ mod task_runner { let node = container.create_action_node("success"); let context = ActionContext::default(); - runner - .execute(&context, &node, Some("hash123")) - .await - .unwrap(); + runner.report_item.hash = Some("hash123".into()); + runner.execute(&context, &node).await.unwrap(); assert_eq!( context @@ -684,7 +682,7 @@ mod task_runner { let node = container.create_action_node("success"); let context = ActionContext::default(); - runner.execute(&context, &node, None).await.unwrap(); + runner.execute(&context, &node).await.unwrap(); assert_eq!( context @@ -706,7 +704,8 @@ mod task_runner { let context = ActionContext::default(); // Swallow panic so we can check operations - let _ = runner.execute(&context, &node, Some("hash123")).await; + runner.report_item.hash = Some("hash123".into()); + let _ = runner.execute(&context, &node).await; assert_eq!( context @@ -727,10 +726,8 @@ mod task_runner { let node = container.create_action_node("success"); let context = ActionContext::default(); - runner - .execute(&context, &node, Some("hash123")) - .await - .unwrap(); + runner.report_item.hash = Some("hash123".into()); + runner.execute(&context, &node).await.unwrap(); let operation = runner.operations.last().unwrap(); @@ -753,7 +750,8 @@ mod task_runner { let context = ActionContext::default(); // Swallow panic so we can check operations - let _ = runner.execute(&context, &node, Some("hash123")).await; + runner.report_item.hash = Some("hash123".into()); + let _ = runner.execute(&context, &node).await; let operation = runner.operations.last().unwrap(); @@ -774,10 +772,8 @@ mod task_runner { let node = container.create_action_node("success"); let context = ActionContext::default(); - runner - .execute(&context, &node, Some("hash123")) - .await - .unwrap(); + runner.report_item.hash = Some("hash123".into()); + runner.execute(&context, &node).await.unwrap(); assert!(container .sandbox @@ -798,7 +794,8 @@ mod task_runner { let context = ActionContext::default(); // Swallow panic so we can check operations - let _ = runner.execute(&context, &node, Some("hash123")).await; + runner.report_item.hash = Some("hash123".into()); + let _ = runner.execute(&context, &node).await; let operation = runner .operations @@ -819,10 +816,8 @@ mod task_runner { let node = container.create_action_node("failure"); let context = ActionContext::default(); - runner - .execute(&context, &node, Some("hash123")) - .await - .unwrap(); + runner.report_item.hash = Some("hash123".into()); + runner.execute(&context, &node).await.unwrap(); } } @@ -871,7 +866,7 @@ mod task_runner { let mut runner = container.create_runner("base"); let context = ActionContext::default(); - runner.skip_no_op(&context, None).unwrap(); + runner.skip_no_op(&context).unwrap(); let operation = runner.operations.last().unwrap(); @@ -885,7 +880,7 @@ mod task_runner { let mut runner = container.create_runner("base"); let context = ActionContext::default(); - runner.skip_no_op(&context, None).unwrap(); + runner.skip_no_op(&context).unwrap(); assert_eq!( context @@ -902,7 +897,8 @@ mod task_runner { let mut runner = container.create_runner("base"); let context = ActionContext::default(); - runner.skip_no_op(&context, Some("hash123")).unwrap(); + runner.report_item.hash = Some("hash123".into()); + runner.skip_no_op(&context).unwrap(); assert_eq!( context diff --git a/legacy/bun/lang/src/bun_lockb.rs b/legacy/bun/lang/src/bun_lockb.rs index 2b36e66c360..4595f95c8fb 100644 --- a/legacy/bun/lang/src/bun_lockb.rs +++ b/legacy/bun/lang/src/bun_lockb.rs @@ -19,7 +19,7 @@ pub fn load_lockfile_dependencies( Err(_) => { warn!( lockfile = ?path, - "Failed to parse bun.lockb (in Yarn format). Resolved dependency matching will be disabled.", + "Failed to parse bun.lockb (in Yarn format). Task generated hashes will be different.", ); return Ok(deps); diff --git a/legacy/node/lang/src/yarn/mod.rs b/legacy/node/lang/src/yarn/mod.rs index cfc66bd7f68..613b4205308 100644 --- a/legacy/node/lang/src/yarn/mod.rs +++ b/legacy/node/lang/src/yarn/mod.rs @@ -16,7 +16,7 @@ pub fn load_lockfile_dependencies(path: PathBuf) -> miette::Result { warn!( lockfile = ?path, - "Failed to parse yarn.lock. Resolved dependency matching will be disabled.", + "Failed to parse yarn.lock. Task generated hashes will be different.", ); return Ok(deps);