Skip to content
Open
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Changelog

- **Changed** In a workspace with a single package, `vp run --log=labeled` and `vp run --log=grouped` now label output with `[task]` instead of `[package#task]`. Monorepos keep the package name in the label ([vite-plus#2912](https://github.com/voidzero-dev/vite-plus/issues/2912), [#883](https://github.com/voidzero-dev/vite-task/pull/883)).
- **Perf** When tasks miss the cache, `vp run` no longer waits for the disk after saving each task's result, so the run finishes sooner. If the computer loses power or the operating system crashes during `vp run`, the cache entries that the run saved can be lost, and those tasks run again next time instead of hitting the cache ([#871](https://github.com/voidzero-dev/vite-task/pull/871)).
- **Fixed** Running `vp run` in a package that sits inside a workspace folder but isn't listed in its `pnpm-workspace.yaml` `packages` or `package.json` `workspaces` now runs that package's own tasks, instead of treating the enclosing workspace as its root. When both configurations exist, `pnpm-workspace.yaml` takes precedence ([#859](https://github.com/voidzero-dev/vite-task/pull/859)).
- **Fixed** A mistyped or misplaced setting in a task now gets an error that names it. For example, `cache: { outputs: [...] }` now fails with an `unknown field` error that names `outputs` and lists the accepted settings, instead of `data did not match any variant of untagged enum UserTaskDefinition` ([vite-plus#2635](https://github.com/voidzero-dev/vite-plus/issues/2635), [#815](https://github.com/voidzero-dev/vite-task/pull/815)).
Expand Down
55 changes: 34 additions & 21 deletions crates/vt/src/session/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -337,7 +337,6 @@ impl<'a> Session<'a> {
};

let workspace_path = self.workspace_path();
let writer: Box<dyn std::io::Write> = Box::new(std::io::stdout());

// Detect color support once at the point where reporters are
// constructed. The reporters and their pipe writers then strip
Expand All @@ -349,26 +348,7 @@ impl<'a> Session<'a> {
stderr: stderr_supports_color(),
};

let inner: Box<dyn reporter::GraphExecutionReporterBuilder> = match run_command
.flags
.log
{
crate::cli::LogMode::Interleaved => Box::new(InterleavedReporterBuilder::new(
Arc::clone(&workspace_path),
writer,
color_support,
)),
crate::cli::LogMode::Labeled => Box::new(LabeledReporterBuilder::new(
Arc::clone(&workspace_path),
writer,
color_support,
)),
crate::cli::LogMode::Grouped => Box::new(GroupedReporterBuilder::new(
Arc::clone(&workspace_path),
writer,
color_support,
)),
};
let inner = self.make_mode_reporter(run_command.flags.log, color_support);

let builder = Box::new(SummaryReporterBuilder::new(
inner,
Expand Down Expand Up @@ -669,6 +649,39 @@ impl<'a> Session<'a> {
}
}

/// Create the reporter for the `--log` mode, writing to stdout.
fn make_mode_reporter(
&self,
log_mode: crate::cli::LogMode,
color_support: ColorSupport,
) -> Box<dyn reporter::GraphExecutionReporterBuilder> {
let workspace_path = self.workspace_path();
let writer: Box<dyn std::io::Write> = Box::new(std::io::stdout());
// In a single-package workspace every task belongs to the same package,
// so `labeled` and `grouped` label tasks as `[task]` instead of `[pkg#task]`.
let include_package_name = !matches!(
&self.lazy_task_graph,
LazyTaskGraph::Initialized(graph) if graph.is_single_package()
);
match log_mode {
crate::cli::LogMode::Interleaved => {
Box::new(InterleavedReporterBuilder::new(workspace_path, writer, color_support))
}
crate::cli::LogMode::Labeled => Box::new(LabeledReporterBuilder::new(
workspace_path,
writer,
color_support,
include_package_name,
)),
crate::cli::LogMode::Grouped => Box::new(GroupedReporterBuilder::new(
workspace_path,
writer,
color_support,
include_package_name,
)),
}
}

pub const fn task_graph(&self) -> Option<&TaskGraph> {
match &self.lazy_task_graph {
LazyTaskGraph::Initialized(graph) => Some(graph.task_graph()),
Expand Down
9 changes: 7 additions & 2 deletions crates/vt/src/session/reporter/grouped/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct GroupedReporterBuilder {
workspace_path: Arc<AbsolutePath>,
writer: Box<dyn Write>,
color_support: ColorSupport,
include_package_name: bool,
}

impl GroupedReporterBuilder {
Expand All @@ -34,8 +35,9 @@ impl GroupedReporterBuilder {
workspace_path: Arc<AbsolutePath>,
writer: Box<dyn Write>,
color_support: ColorSupport,
include_package_name: bool,
) -> Self {
Self { workspace_path, writer, color_support }
Self { workspace_path, writer, color_support, include_package_name }
}
}

Expand All @@ -45,6 +47,7 @@ impl GraphExecutionReporterBuilder for GroupedReporterBuilder {
writer: Rc::new(RefCell::new(self.writer)),
workspace_path: self.workspace_path,
color_support: self.color_support,
include_package_name: self.include_package_name,
})
}
}
Expand All @@ -53,6 +56,7 @@ struct GroupedGraphReporter {
writer: Rc<RefCell<Box<dyn Write>>>,
workspace_path: Arc<AbsolutePath>,
color_support: ColorSupport,
include_package_name: bool,
}

impl GraphExecutionReporter for GroupedGraphReporter {
Expand All @@ -61,7 +65,7 @@ impl GraphExecutionReporter for GroupedGraphReporter {
display: &ExecutionItemDisplay,
_leaf_kind: &LeafExecutionKind,
) -> Box<dyn LeafExecutionReporter> {
let label = format_task_label(display);
let label = format_task_label(display, self.include_package_name);
Box::new(GroupedLeafReporter {
writer: Rc::clone(&self.writer),
display: display.clone(),
Expand Down Expand Up @@ -177,6 +181,7 @@ mod tests {
test_path(),
Box::new(std::io::sink()),
ColorSupport::uniform(false),
true,
));
let mut reporter = builder.build();
let mut leaf = reporter.new_leaf_execution(&item.execution_item_display, leaf_kind(item));
Expand Down
12 changes: 10 additions & 2 deletions crates/vt/src/session/reporter/labeled/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use std::{cell::RefCell, io::Write, process::ExitStatus as StdExitStatus, rc::Rc

use vt_path::AbsolutePath;
use vt_plan::{ExecutionItemDisplay, LeafExecutionKind};
use vt_str::Str;

use super::{
ColorSupport, ExitStatus, GraphExecutionReporter, GraphExecutionReporterBuilder,
Expand All @@ -21,6 +22,7 @@ pub struct LabeledReporterBuilder {
workspace_path: Arc<AbsolutePath>,
writer: Box<dyn Write>,
color_support: ColorSupport,
include_package_name: bool,
}

impl LabeledReporterBuilder {
Expand All @@ -31,8 +33,9 @@ impl LabeledReporterBuilder {
workspace_path: Arc<AbsolutePath>,
writer: Box<dyn Write>,
color_support: ColorSupport,
include_package_name: bool,
) -> Self {
Self { workspace_path, writer, color_support }
Self { workspace_path, writer, color_support, include_package_name }
}
}

Expand All @@ -42,6 +45,7 @@ impl GraphExecutionReporterBuilder for LabeledReporterBuilder {
writer: Rc::new(RefCell::new(self.writer)),
workspace_path: self.workspace_path,
color_support: self.color_support,
include_package_name: self.include_package_name,
})
}
}
Expand All @@ -50,6 +54,7 @@ struct LabeledGraphReporter {
writer: Rc<RefCell<Box<dyn Write>>>,
workspace_path: Arc<AbsolutePath>,
color_support: ColorSupport,
include_package_name: bool,
}

impl GraphExecutionReporter for LabeledGraphReporter {
Expand All @@ -62,6 +67,7 @@ impl GraphExecutionReporter for LabeledGraphReporter {
writer: Rc::clone(&self.writer),
display: display.clone(),
workspace_path: Arc::clone(&self.workspace_path),
label: format_task_label(display, self.include_package_name),
started: false,
color_support: self.color_support,
})
Expand All @@ -78,13 +84,14 @@ struct LabeledLeafReporter {
writer: Rc<RefCell<Box<dyn Write>>>,
display: ExecutionItemDisplay,
workspace_path: Arc<AbsolutePath>,
label: Str,
started: bool,
color_support: ColorSupport,
}

impl LeafExecutionReporter for LabeledLeafReporter {
fn start(&mut self, cache_status: CacheStatus) -> StdioConfig {
let label = format_task_label(&self.display);
let label = &self.label;
let line =
format_command_with_cache_status(&self.display, &self.workspace_path, &cache_status);

Expand Down Expand Up @@ -157,6 +164,7 @@ mod tests {
test_path(),
Box::new(std::io::sink()),
ColorSupport::uniform(false),
true,
));
let mut reporter = builder.build();
let mut leaf = reporter.new_leaf_execution(&item.execution_item_display, leaf_kind(item));
Expand Down
15 changes: 10 additions & 5 deletions crates/vt/src/session/reporter/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -257,11 +257,16 @@ fn format_cwd_relative(display: &ExecutionItemDisplay, workspace_path: &Absolute
}

/// Format the task label for labeled/grouped modes (e.g., `[pkg#task]`).
fn format_task_label(display: &ExecutionItemDisplay) -> Str {
vt_str::format!(
"{}",
vt_str::format!("[{}]", display.task_display).style(Style::new().bright_black())
)
///
/// With `include_package_name` set to `false`, the label is just `[task]`.
/// Used for single-package workspaces, where every task is in the same package.
fn format_task_label(display: &ExecutionItemDisplay, include_package_name: bool) -> Str {
let label = if include_package_name {
vt_str::format!("[{}]", display.task_display)
} else {
vt_str::format!("[{}]", display.task_display.task_name)
};
vt_str::format!("{}", label.style(Style::new().bright_black()))
}

/// Format the command string with cwd prefix for display (e.g., `~/packages/lib$ vitest run`).
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"name": "single-package",
"private": true
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
[[e2e]]
name = "labeled"
comment = """
In a single-package workspace, `--log=labeled` prefixes lines with `[task]` instead of `[pkg#task]`.
"""
steps = [["vt", "run", "--log=labeled", "build"]]

[[e2e]]
name = "grouped"
comment = """
In a single-package workspace, `--log=grouped` labels each block with `[task]` instead of `[pkg#task]`.
"""
steps = [["vt", "run", "--log=grouped", "build"]]
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# grouped

In a single-package workspace, `--log=grouped` labels each block with `[task]` instead of `[pkg#task]`.

## `vt run --log=grouped build`

```
[lint] $ echo lint ⊘ cache disabled
── [lint] ──
lint

[build] $ echo build ⊘ cache disabled
── [build] ──
build

---
vt run: 2/2 successful. (Run `vt run --last-details` for full details)
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# labeled

In a single-package workspace, `--log=labeled` prefixes lines with `[task]` instead of `[pkg#task]`.

## `vt run --log=labeled build`

```
[lint] $ echo lint ⊘ cache disabled
[lint] lint

[build] $ echo build ⊘ cache disabled
[build] build

---
vt run: 2/2 successful. (Run `vt run --last-details` for full details)
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
{
"tasks": {
"lint": {
"command": "echo lint",
"cache": false
},
"build": {
"command": "echo build",
"dependsOn": ["lint"],
"cache": false
}
}
}
6 changes: 6 additions & 0 deletions crates/vt_graph/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,12 @@ impl IndexedTaskGraph {
&self.task_graph
}

/// Whether the workspace has only one package, i.e. it is not a monorepo.
#[must_use]
pub fn is_single_package(&self) -> bool {
self.indexed_package_graph.package_graph().node_count() == 1
}

#[must_use]
pub fn get_package_name(&self, package_index: PackageNodeIndex) -> &str {
self.indexed_package_graph.package_graph()[package_index].package_json.name.as_str()
Expand Down
2 changes: 1 addition & 1 deletion docs/stdio.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ The flag goes before the task name. Anything after the task name is passed to th

### Examples

In `interleaved` mode, task names are omitted from the command line to keep output clean. In `labeled` and `grouped` modes, the `[pkg#task]` prefix is necessary to identify which task produced each line.
In `interleaved` mode, task names are omitted from the command line to keep output clean. In `labeled` and `grouped` modes, the `[pkg#task]` prefix is necessary to identify which task produced each line. In a workspace with a single package, the prefix is just `[task]`, since every task belongs to that package.

#### `interleaved`

Expand Down