diff --git a/.github/workflows/vp-binary-size.yml b/.github/workflows/vp-binary-size.yml index 0580e5fbd7..71196bdb8b 100644 --- a/.github/workflows/vp-binary-size.yml +++ b/.github/workflows/vp-binary-size.yml @@ -153,9 +153,35 @@ jobs: TARGET: ${{ matrix.settings.target }} run: | node <<'NODE' - const { existsSync, readFileSync, writeFileSync } = require('node:fs'); + const { existsSync, readFileSync, readdirSync, writeFileSync } = require('node:fs'); const { gzipSync } = require('node:zlib'); + function includeAllFiles() { + return true; + } + + function includeNonNodeFiles(file) { + return !file.endsWith('.node'); + } + + function measureDirectory(directory, includeFile = includeAllFiles) { + let files = 0; + let raw = 0; + function visit(currentDirectory) { + for (const entry of readdirSync(currentDirectory, { withFileTypes: true })) { + const entryPath = `${currentDirectory}/${entry.name}`; + if (entry.isDirectory()) { + visit(entryPath); + } else if (entry.isFile() && includeFile(entryPath)) { + files += 1; + raw += readFileSync(entryPath).length; + } + } + } + visit(directory); + return { path: directory, files, raw }; + } + const target = process.env.TARGET; const paths = process.env.PLATFORM === 'linux' @@ -187,6 +213,17 @@ jobs: gzip: gzipSync(contents, { level: 9 }).length, }; } + if (process.env.PLATFORM === 'linux') { + const cliDistDirectory = 'packages/cli/dist'; + const coreDistDirectory = 'packages/core/dist'; + for (const directory of [cliDistDirectory, coreDistDirectory]) { + if (!existsSync(directory)) { + throw new Error(`Expected final dist package at ${directory}`); + } + } + artifacts.cliDist = measureDirectory(cliDistDirectory); + artifacts.coreDist = measureDirectory(coreDistDirectory, includeNonNodeFiles); + } const result = { source: process.env.SOURCE, @@ -351,16 +388,42 @@ jobs: }; const shortSha = process.env.HEAD_SHA.slice(0, 7); - const rows = artifacts.flatMap((artifact) => [ - `| ${artifact.name} | Binary | ${formatSize(artifact.baseRaw)} | ${formatSize(artifact.headRaw)} | ${formatDelta(artifact.baseRaw, artifact.headRaw)} |`, - `| ${artifact.name} | gzip -9 | ${formatSize(artifact.baseGzip)} | ${formatSize(artifact.headGzip)} | ${formatDelta(artifact.baseGzip, artifact.headGzip)} |`, - ]); + const distArtifacts = [ + { + name: '`packages/cli/dist`', + baseRaw: baseLinux.artifacts.cliDist.raw, + headRaw: headLinux.artifacts.cliDist.raw, + }, + { + name: '`packages/core/dist`', + baseRaw: baseLinux.artifacts.coreDist.raw, + headRaw: headLinux.artifacts.coreDist.raw, + }, + { + name: 'Combined package dist', + baseRaw: + baseLinux.artifacts.cliDist.raw + baseLinux.artifacts.coreDist.raw, + headRaw: + headLinux.artifacts.cliDist.raw + headLinux.artifacts.coreDist.raw, + }, + ]; + const rows = [ + ...distArtifacts.map( + (artifact) => + `| ${artifact.name} | Directory total | ${formatSize(artifact.baseRaw)} | ${formatSize(artifact.headRaw)} | ${formatDelta(artifact.baseRaw, artifact.headRaw)} |`, + ), + ...artifacts.flatMap((artifact) => [ + `| ${artifact.name} | Binary | ${formatSize(artifact.baseRaw)} | ${formatSize(artifact.headRaw)} | ${formatDelta(artifact.baseRaw, artifact.headRaw)} |`, + `| ${artifact.name} | gzip -9 | ${formatSize(artifact.baseGzip)} | ${formatSize(artifact.headGzip)} | ${formatDelta(artifact.baseGzip, artifact.headGzip)} |`, + ]), + ]; const body = [ marker, '', - `### Native binary sizes (\`${shortSha}\`)`, + `### CLI artifact sizes (\`${shortSha}\`)`, '', 'Final release artifacts built by the canonical `build-upstream` and `build-windows-cli` actions.', + 'The dist rows use the Linux build. The core total excludes `.node` files to match the release artifact.', '', '| Artifact | Format | Base | PR | Change |', '| --- | --- | ---: | ---: | ---: |', diff --git a/Cargo.lock b/Cargo.lock index 01ab26bcc4..6c95f5a1eb 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -8439,6 +8439,7 @@ dependencies = [ "tokio", "tracing", "uuid", + "vp_cli_help", "vp_command", "vp_error", "vp_migration", @@ -8453,6 +8454,16 @@ dependencies = [ "vt_workspace", ] +[[package]] +name = "vp_cli_help" +version = "0.0.0" +dependencies = [ + "clap", + "owo-colors", + "terminal_size", + "vp_shared", +] + [[package]] name = "vp_cli_snapshots" version = "0.0.0" @@ -8543,6 +8554,7 @@ dependencies = [ "tokio", "tracing", "uuid", + "vp_cli_help", "vp_command", "vp_error", "vp_js_runtime", diff --git a/Cargo.toml b/Cargo.toml index f8a4368d91..91d2a65d81 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -290,6 +290,7 @@ url = "2.5.4" uuid = "1.17.0" vfs = "0.13.0" vp_command = { path = "crates/vp_command" } +vp_cli_help = { path = "crates/vp_cli_help" } vp_error = { path = "crates/vp_error" } vp_js_runtime = { path = "crates/vp_js_runtime" } vp_migration = { path = "crates/vp_migration" } diff --git a/crates/vp_cli_help/Cargo.toml b/crates/vp_cli_help/Cargo.toml new file mode 100644 index 0000000000..86dfb739e9 --- /dev/null +++ b/crates/vp_cli_help/Cargo.toml @@ -0,0 +1,17 @@ +[package] +name = "vp_cli_help" +version = "0.0.0" +authors.workspace = true +edition.workspace = true +license.workspace = true +publish = false +rust-version.workspace = true + +[dependencies] +clap = { workspace = true } +owo-colors = { workspace = true } +terminal_size = { workspace = true } +vp_shared = { workspace = true } + +[lints] +workspace = true diff --git a/crates/vp_cli_help/src/lib.rs b/crates/vp_cli_help/src/lib.rs new file mode 100644 index 0000000000..c4595ec270 --- /dev/null +++ b/crates/vp_cli_help/src/lib.rs @@ -0,0 +1,545 @@ +#![expect( + clippy::disallowed_macros, + clippy::disallowed_types, + reason = "help rendering needs large, mutable, owned text buffers" +)] + +//! Shared help documents and rendering for Vite+ command-line interfaces. + +use std::{borrow::Cow, fmt::Write as _, io::Write as _}; + +use clap::{Arg, Command}; +use owo_colors::OwoColorize; +use terminal_size::{Width, terminal_size_of}; + +const HELP_RIGHT_MARGIN: usize = 4; +const ROW_LABEL_INDENT: &str = " "; +const ROW_DESCRIPTION_GAP: &str = " "; +const ROW_DESCRIPTION_INDENT: &str = " "; + +#[derive(Clone, Debug)] +pub struct HelpDoc { + pub usage: Cow<'static, str>, + pub summary: Vec>, + pub sections: Vec, + pub documentation_url: Option>, +} + +#[derive(Clone, Debug)] +pub enum HelpSection { + Rows { title: Cow<'static, str>, rows: Vec }, + Lines { title: Cow<'static, str>, lines: Vec> }, +} + +#[derive(Clone, Debug)] +pub struct HelpRow { + pub label: Cow<'static, str>, + pub description: Vec>, +} + +/// Build a help document from public `clap` command metadata. +#[must_use] +pub fn help_doc_from_command( + mut command: Command, + documentation_url: Option>, +) -> HelpDoc { + command.build(); + + let usage = command.render_usage().to_string(); + let usage = usage.strip_prefix("Usage: ").unwrap_or(&usage).to_owned(); + let summary = + command.get_about().map(ToString::to_string).into_iter().map(Into::into).collect(); + let mut sections = Vec::new(); + + push_argument_rows( + &mut sections, + "Arguments", + command.get_arguments().filter(|arg| arg.is_positional()), + ); + push_argument_rows( + &mut sections, + "Options", + command.get_arguments().filter(|arg| !arg.is_positional()), + ); + + let subcommand_title = command.get_subcommand_help_heading().unwrap_or("Commands").to_owned(); + let mut subcommands = command + .get_subcommands() + .filter(|subcommand| !subcommand.is_hide_set()) + .collect::>(); + subcommands.sort_by_key(|subcommand| subcommand.get_display_order()); + for subcommand in subcommands { + let label = subcommand.get_name_and_visible_aliases().join(", "); + let description = subcommand.get_about().map(ToString::to_string).unwrap_or_default(); + push_help_row( + &mut sections, + &subcommand_title, + HelpRow { label: label.into(), description: vec![description.into()] }, + ); + } + + HelpDoc { usage: usage.into(), summary, sections, documentation_url } +} + +fn push_argument_rows<'a>( + sections: &mut Vec, + default_title: &str, + arguments: impl Iterator, +) { + let mut arguments = arguments.filter(|arg| !arg.is_hide_set()).collect::>(); + arguments.sort_by_key(|arg| arg.get_display_order()); + + for arg in arguments { + let title = arg.get_help_heading().unwrap_or(default_title); + let description = arg + .get_help() + .or_else(|| arg.get_long_help()) + .map(ToString::to_string) + .unwrap_or_default(); + push_help_row( + sections, + title, + HelpRow { label: arg_label(arg).into(), description: vec![description.into()] }, + ); + } +} + +fn arg_label(arg: &Arg) -> String { + let label = arg.to_string(); + match (arg.get_short(), arg.get_long()) { + (Some(short), Some(_)) => format!("-{short}, {label}"), + _ => label, + } +} + +fn push_help_row(sections: &mut Vec, title: &str, row: HelpRow) { + if let Some(HelpSection::Rows { rows, .. }) = sections.iter_mut().find(|section| { + matches!(section, HelpSection::Rows { title: section_title, .. } if section_title == title) + }) { + rows.push(row); + } else { + sections.push(HelpSection::Rows { title: title.to_owned().into(), rows: vec![row] }); + } +} + +pub fn render_heading(title: &str) -> String { + let heading = format!("{title}:"); + if !should_style_help() { + return heading; + } + + if should_accent_heading(title) { + heading.bold().bright_blue().to_string() + } else { + heading.bold().to_string() + } +} + +fn render_usage_value(usage: &str) -> String { + if should_style_help() { usage.bold().to_string() } else { usage.to_string() } +} + +fn should_accent_heading(title: &str) -> bool { + title != "Usage" +} + +fn write_documentation_footer(output: &mut String, documentation_url: &str) { + let _ = writeln!(output); + let _ = writeln!(output, "{} {documentation_url}", render_heading("Documentation")); +} + +pub fn accent(text: &str) -> String { + if should_style_help() { text.bright_blue().to_string() } else { text.to_string() } +} + +pub fn accent_command(command: &str) -> String { + format!("`{}`", accent(command)) +} + +pub fn should_style_help() -> bool { + vp_shared::is_stdout_terminal() + && std::env::var_os("NO_COLOR").is_none() + && std::env::var("CLICOLOR").map_or(true, |value| value != "0") + && std::env::var("TERM").map_or(true, |term| term != "dumb") +} + +fn terminal_content_width() -> usize { + terminal_size_of(std::io::stdout()) + .map(|(Width(width), _)| usize::from(width).saturating_sub(HELP_RIGHT_MARGIN)) + .unwrap_or(usize::MAX) +} + +fn visible_length(value: &str) -> usize { + let mut length = 0; + let mut chars = value.chars().peekable(); + + while let Some(ch) = chars.next() { + if ch == '\u{1b}' { + match chars.peek().copied() { + Some('[') => { + let _ = chars.next(); + for next in chars.by_ref() { + if ('@'..='~').contains(&next) { + break; + } + } + } + Some(']') => { + let _ = chars.next(); + let mut previous = '\0'; + for next in chars.by_ref() { + if next == '\u{7}' || (previous == '\u{1b}' && next == '\\') { + break; + } + previous = next; + } + } + _ => {} + } + } else { + length += 1; + } + } + + length +} + +fn words_with_separators(value: &str) -> Vec<(&str, &str)> { + let mut output = Vec::new(); + let mut offset = 0; + + while offset < value.len() { + let word_start = value[offset..] + .char_indices() + .find_map(|(index, ch)| (!ch.is_whitespace()).then_some(offset + index)) + .unwrap_or(value.len()); + if word_start == value.len() { + break; + } + + let word_end = value[word_start..] + .char_indices() + .find_map(|(index, ch)| ch.is_whitespace().then_some(word_start + index)) + .unwrap_or(value.len()); + output.push((&value[offset..word_start], &value[word_start..word_end])); + offset = word_end; + } + + output +} + +fn wrap_line(line: &str, width: usize) -> Vec { + if width == 0 || visible_length(line) <= width { + return vec![line.to_owned()]; + } + + let content = line.trim(); + if content.is_empty() { + return vec![line.to_owned()]; + } + + let indent = &line[..line.len() - line.trim_start().len()]; + let mut output = Vec::new(); + let mut current = indent.to_owned(); + + for (whitespace, word) in words_with_separators(content) { + let separator = if current == indent { "" } else { whitespace }; + let candidate = format!("{current}{separator}{word}"); + if current == indent || visible_length(&candidate) <= width { + current = candidate; + } else { + output.push(current); + current = format!("{indent}{word}"); + } + } + + output.push(current); + output +} + +fn render_stacked_rows(rows: &[HelpRow], content_width: usize) -> Vec { + let description_width = content_width.saturating_sub(ROW_DESCRIPTION_INDENT.len()); + let mut output = Vec::new(); + + for row in rows { + output.push(format!("{}{}", ROW_LABEL_INDENT, row.label)); + for line in row.description.iter().flat_map(|line| wrap_line(line, description_width)) { + if !line.is_empty() { + output.push(format!("{ROW_DESCRIPTION_INDENT}{line}")); + } + } + } + + output +} + +fn render_rows(rows: &[HelpRow], content_width: usize) -> Vec { + if rows.is_empty() { + return vec![]; + } + + let label_width = rows.iter().map(|row| visible_length(&row.label)).max().unwrap_or(0); + if content_width <= label_width.saturating_add(ROW_DESCRIPTION_INDENT.len()) { + return render_stacked_rows(rows, content_width); + } + + let description_width = + content_width.saturating_sub(label_width + ROW_DESCRIPTION_INDENT.len()); + let mut output = Vec::new(); + + for row in rows { + let mut description_iter = + row.description.iter().flat_map(|line| wrap_line(line, description_width)); + if let Some(first) = description_iter.next() { + let label = format!( + "{}{}", + row.label, + " ".repeat(label_width.saturating_sub(visible_length(&row.label))) + ); + output.push(format!("{ROW_LABEL_INDENT}{label}{ROW_DESCRIPTION_GAP}{first}")); + for line in description_iter { + output.push(format!( + "{ROW_LABEL_INDENT}{:label_width$}{ROW_DESCRIPTION_GAP}{line}", + "" + )); + } + } else { + output.push(format!("{ROW_LABEL_INDENT}{}", row.label)); + } + } + + output +} + +fn split_comment_suffix(line: &str) -> Option<(&str, &str)> { + line.find(" #").map(|index| line.split_at(index)) +} + +fn render_muted_comment_suffix(line: &str) -> String { + if !should_style_help() { + return line.to_string(); + } + + if let Some((prefix, suffix)) = split_comment_suffix(line) { + return format!("{}{}", prefix, suffix.bright_black()); + } + + line.to_string() +} + +#[must_use] +pub fn render_help_doc(doc: &HelpDoc) -> String { + render_help_doc_with_width(doc, terminal_content_width()) +} + +fn render_help_doc_with_width(doc: &HelpDoc, content_width: usize) -> String { + let mut output = String::new(); + + let _ = writeln!(output, "{} {}", render_heading("Usage"), render_usage_value(&doc.usage)); + + if !doc.summary.is_empty() { + let _ = writeln!(output); + for line in &doc.summary { + let _ = writeln!(output, "{line}"); + } + } + + for section in &doc.sections { + let _ = writeln!(output); + match section { + HelpSection::Rows { title, rows } => { + let _ = writeln!(output, "{}", render_heading(title)); + for line in render_rows(rows, content_width) { + let _ = writeln!(output, "{line}"); + } + } + HelpSection::Lines { title, lines } => { + let _ = writeln!(output, "{}", render_heading(title)); + for line in lines { + let line = render_muted_comment_suffix(line); + for wrapped_line in wrap_line(&line, content_width) { + let _ = writeln!(output, "{wrapped_line}"); + } + } + } + } + } + + if let Some(documentation_url) = doc.documentation_url.as_deref() { + write_documentation_footer(&mut output, documentation_url); + } + + output +} + +/// Print the Vite+ header and a help document to stdout. +pub fn print_help_doc(doc: &HelpDoc) { + let mut output = String::new(); + if vp_shared::header::should_print_header() { + let _ = writeln!(output, "{}\n", vp_shared::header::vite_plus_header()); + } + let _ = writeln!(output, "{}", render_help_doc(doc)); + + let mut stdout = std::io::stdout().lock(); + let _ = stdout.write_all(output.as_bytes()); + let _ = stdout.flush(); +} + +#[cfg(test)] +mod tests { + use clap::{ArgAction, Command}; + + use super::{ + HelpDoc, HelpRow, HelpSection, ROW_DESCRIPTION_INDENT, help_doc_from_command, + render_help_doc_with_width, render_rows, visible_length, + }; + + #[test] + fn builds_help_from_command_metadata() { + let command = Command::new("vp example") + .about("Run an example command") + .arg(clap::Arg::new("input").value_name("path").help("Input path")) + .arg( + clap::Arg::new("concurrent") + .short('p') + .long("concurrent") + .value_name("number") + .num_args(0..=1) + .display_order(2) + .help("Run tasks at the same time"), + ) + .arg( + clap::Arg::new("verbose") + .long("verbose") + .action(ArgAction::SetTrue) + .display_order(1) + .help("Show more output"), + ) + .arg(clap::Arg::new("internal").long("internal").hide(true).action(ArgAction::SetTrue)) + .arg( + clap::Arg::new("environment") + .long("environment") + .help_heading("Environment") + .action(ArgAction::SetTrue) + .help("Read the environment"), + ) + .subcommand(Command::new("inspect").visible_alias("show").about("Inspect the input")); + + let doc = help_doc_from_command(command, Some("https://viteplus.dev/example".into())); + + assert_eq!(doc.usage, "vp example [OPTIONS] [path] [COMMAND]"); + assert_eq!(doc.summary, ["Run an example command"]); + assert_eq!(doc.documentation_url.as_deref(), Some("https://viteplus.dev/example")); + assert_eq!(doc.sections.len(), 4); + + let HelpSection::Rows { title, rows } = &doc.sections[0] else { + panic!("Arguments must contain rows"); + }; + assert_eq!(title, "Arguments"); + assert_eq!(rows[0].label, "[path]"); + + let HelpSection::Rows { title, rows } = &doc.sections[1] else { + panic!("Options must contain rows"); + }; + assert_eq!(title, "Options"); + assert_eq!(rows[0].label, "--verbose"); + assert_eq!(rows[1].label, "-p, --concurrent []"); + assert_eq!(rows[1].description, ["Run tasks at the same time"]); + assert_eq!(rows[2].label, "-h, --help"); + + let HelpSection::Rows { title, rows } = &doc.sections[2] else { + panic!("Environment must contain rows"); + }; + assert_eq!(title, "Environment"); + assert_eq!(rows[0].label, "--environment"); + + let HelpSection::Rows { title, rows } = &doc.sections[3] else { + panic!("Commands must contain rows"); + }; + assert_eq!(title, "Commands"); + assert_eq!(rows[0].label, "inspect, show"); + } + + #[test] + fn wraps_help_within_the_terminal_width() { + let doc = HelpDoc { + usage: "vp example".into(), + summary: vec![], + sections: vec![ + HelpSection::Lines { + title: "Details".into(), + lines: vec![" * `all` - Include every category except one.".into()], + }, + HelpSection::Rows { + title: "Options".into(), + rows: vec![HelpRow { + label: "--config=".into(), + description: vec![ + "Override the configuration file used for import resolution.".into(), + ], + }], + }, + ], + documentation_url: None, + }; + + assert_eq!( + render_help_doc_with_width(&doc, 36), + concat!( + "Usage: vp example\n", + "\n", + "Details:\n", + " * `all` - Include every category\n", + " except one.\n", + "\n", + "Options:\n", + " --config= Override the\n", + " configuration\n", + " file used for\n", + " import\n", + " resolution.\n", + ) + ); + } + + #[test] + fn stacks_rows_when_labels_leave_no_description_width() { + let rows = vec![ + HelpRow { + label: "--package-manager ".into(), + description: vec![ + "Use the selected package manager for the generated project.".into(), + ], + }, + HelpRow { + label: "--verbose".into(), + description: vec!["Show detailed scaffolding output.".into()], + }, + ]; + + let content_width = 28; + let label_width = rows.iter().map(|row| visible_length(&row.label)).max().unwrap_or(0); + assert!(content_width <= label_width + ROW_DESCRIPTION_INDENT.len()); + + let output = render_rows(&rows, content_width); + + assert_eq!( + output, + [ + " --package-manager ", + " Use the selected package", + " manager for the", + " generated project.", + " --verbose", + " Show detailed", + " scaffolding output.", + ] + ); + assert!( + output + .iter() + .filter(|line| line.starts_with(" ")) + .all(|line| visible_length(line) <= content_width) + ); + } +} diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_config_help/snapshots/command_config_help.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_config_help/snapshots/command_config_help.md index 4c755dc08c..f41790ea74 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_config_help/snapshots/command_config_help.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_config_help/snapshots/command_config_help.md @@ -11,7 +11,9 @@ Configure Vite+ for the current project (hook dispatcher + agent integration). Options: --hooks-dir Custom hooks directory (default: .vite-hooks, or last used in this clone) + --hooks Install the hook dispatcher --no-hooks Skip hook dispatcher installation + --agent Update coding agent instructions --no-agent Skip updating coding agent instructions -h, --help Show this help message @@ -32,7 +34,9 @@ Configure Vite+ for the current project (hook dispatcher + agent integration). Options: --hooks-dir Custom hooks directory (default: .vite-hooks, or last used in this clone) + --hooks Install the hook dispatcher --no-hooks Skip hook dispatcher installation + --agent Update coding agent instructions --no-agent Skip updating coding agent instructions -h, --help Show this help message @@ -53,7 +57,9 @@ Configure Vite+ for the current project (hook dispatcher + agent integration). Options: --hooks-dir Custom hooks directory (default: .vite-hooks, or last used in this clone) + --hooks Install the hook dispatcher --no-hooks Skip hook dispatcher installation + --agent Update coding agent instructions --no-agent Skip updating coding agent instructions -h, --help Show this help message diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_help/snapshots/command_create_help.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_help/snapshots/command_create_help.md index a8ffcb8c86..e28982230d 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_help/snapshots/command_create_help.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_help/snapshots/command_create_help.md @@ -10,62 +10,34 @@ Usage: vp create [TEMPLATE] [OPTIONS] [-- TEMPLATE_OPTIONS] Use any builtin, local or remote template with Vite+. Arguments: - TEMPLATE Template name. Run `vp create --list` to see available templates. - - Default: vite:monorepo, vite:application, vite:library, vite:generator - - Remote: vite, @tanstack/start, create-next-app, - create-nuxt, github:user/repo, https://github.com/user/template-repo, etc. - - Local: a `create.templates` entry name from vite.config.ts (monorepo) - - Org scope: @your-org → picker from @your-org/create's createConfig.templates manifest - - Org entry: @your-org:web → manifest entry "web" from @your-org/create - When omitted, uses `create.defaultTemplate` from vite.config.ts if set. + [TEMPLATE] Builtin, local, or remote template name + [TEMPLATE_OPTIONS]... Arguments passed to the template without changes Options: - --directory DIR Target directory for the generated project. - --agent NAME Write coding agent instructions to AGENTS.md, CLAUDE.md, etc. - --no-agent Skip writing coding agent instructions - --editor NAME Write editor config files for the specified editor. - --no-editor Skip writing editor config files - --git Initialize a git repository - --no-git Skip git repository initialization - --hooks Set up pre-commit hooks (default in non-interactive mode) - --no-hooks Skip pre-commit hooks setup - --package-manager NAME Use specified package manager (pnpm, npm, yarn, bun) - --approve-builds Approve and run gated dependency build scripts without prompting - --verbose Show detailed scaffolding output - --no-interactive Run in non-interactive mode - --list List all available templates - -h, --help Show this help message - -Template Options: - Any arguments after -- are passed directly to the template. + --directory Target directory for the generated project + --agent Write coding agent instructions to AGENTS.md, CLAUDE.md, etc. + --no-agent Skip writing coding agent instructions + --editor Write editor config files for the specified editor + --no-editor Skip writing editor config files + --git Initialize a git repository + --no-git Skip git repository initialization + --hooks Set up pre-commit hooks (default in non-interactive mode) + --no-hooks Skip pre-commit hooks setup + --package-manager Use the specified package manager + --approve-builds Approve and run gated dependency build scripts without prompting + --verbose Show detailed scaffolding output + --interactive Enable interactive prompts + --no-interactive Run in non-interactive mode + --list List all available templates + -h, --help Show this help message Examples: - # Interactive mode - vp create - - # Use existing templates (shorthand expands to create-* packages) - vp create vite - vp create @tanstack/start - vp create svelte - vp create vite -- --template react-ts - - # Full package names also work - vp create create-vite - vp create create-next-app - - # Create Vite+ monorepo, application, library, or generator scaffolds - vp create vite:monorepo - vp create vite:application - vp create vite:library - vp create vite:generator - - # Use templates from GitHub (via degit) - vp create github:user/repo - vp create https://github.com/user/template-repo - - # Pick from an org that publishes @scope/create with createConfig.templates - vp create @your-org # interactive picker - vp create @your-org:web # direct manifest-entry selection + vp create # Interactive mode + vp create vite # Use create-vite + vp create vite -- --template react-ts # Pass template options + vp create vite:monorepo # Create a Vite+ monorepo + vp create github:user/repo # Use a GitHub template + vp create @your-org # Open an org template picker Documentation: https://viteplus.dev/guide/create ``` @@ -80,62 +52,34 @@ Usage: vp create [TEMPLATE] [OPTIONS] [-- TEMPLATE_OPTIONS] Use any builtin, local or remote template with Vite+. Arguments: - TEMPLATE Template name. Run `vp create --list` to see available templates. - - Default: vite:monorepo, vite:application, vite:library, vite:generator - - Remote: vite, @tanstack/start, create-next-app, - create-nuxt, github:user/repo, https://github.com/user/template-repo, etc. - - Local: a `create.templates` entry name from vite.config.ts (monorepo) - - Org scope: @your-org → picker from @your-org/create's createConfig.templates manifest - - Org entry: @your-org:web → manifest entry "web" from @your-org/create - When omitted, uses `create.defaultTemplate` from vite.config.ts if set. + [TEMPLATE] Builtin, local, or remote template name + [TEMPLATE_OPTIONS]... Arguments passed to the template without changes Options: - --directory DIR Target directory for the generated project. - --agent NAME Write coding agent instructions to AGENTS.md, CLAUDE.md, etc. - --no-agent Skip writing coding agent instructions - --editor NAME Write editor config files for the specified editor. - --no-editor Skip writing editor config files - --git Initialize a git repository - --no-git Skip git repository initialization - --hooks Set up pre-commit hooks (default in non-interactive mode) - --no-hooks Skip pre-commit hooks setup - --package-manager NAME Use specified package manager (pnpm, npm, yarn, bun) - --approve-builds Approve and run gated dependency build scripts without prompting - --verbose Show detailed scaffolding output - --no-interactive Run in non-interactive mode - --list List all available templates - -h, --help Show this help message - -Template Options: - Any arguments after -- are passed directly to the template. + --directory Target directory for the generated project + --agent Write coding agent instructions to AGENTS.md, CLAUDE.md, etc. + --no-agent Skip writing coding agent instructions + --editor Write editor config files for the specified editor + --no-editor Skip writing editor config files + --git Initialize a git repository + --no-git Skip git repository initialization + --hooks Set up pre-commit hooks (default in non-interactive mode) + --no-hooks Skip pre-commit hooks setup + --package-manager Use the specified package manager + --approve-builds Approve and run gated dependency build scripts without prompting + --verbose Show detailed scaffolding output + --interactive Enable interactive prompts + --no-interactive Run in non-interactive mode + --list List all available templates + -h, --help Show this help message Examples: - # Interactive mode - vp create - - # Use existing templates (shorthand expands to create-* packages) - vp create vite - vp create @tanstack/start - vp create svelte - vp create vite -- --template react-ts - - # Full package names also work - vp create create-vite - vp create create-next-app - - # Create Vite+ monorepo, application, library, or generator scaffolds - vp create vite:monorepo - vp create vite:application - vp create vite:library - vp create vite:generator - - # Use templates from GitHub (via degit) - vp create github:user/repo - vp create https://github.com/user/template-repo - - # Pick from an org that publishes @scope/create with createConfig.templates - vp create @your-org # interactive picker - vp create @your-org:web # direct manifest-entry selection + vp create # Interactive mode + vp create vite # Use create-vite + vp create vite -- --template react-ts # Pass template options + vp create vite:monorepo # Create a Vite+ monorepo + vp create github:user/repo # Use a GitHub template + vp create @your-org # Open an org template picker Documentation: https://viteplus.dev/guide/create ``` @@ -150,62 +94,34 @@ Usage: vp create [TEMPLATE] [OPTIONS] [-- TEMPLATE_OPTIONS] Use any builtin, local or remote template with Vite+. Arguments: - TEMPLATE Template name. Run `vp create --list` to see available templates. - - Default: vite:monorepo, vite:application, vite:library, vite:generator - - Remote: vite, @tanstack/start, create-next-app, - create-nuxt, github:user/repo, https://github.com/user/template-repo, etc. - - Local: a `create.templates` entry name from vite.config.ts (monorepo) - - Org scope: @your-org → picker from @your-org/create's createConfig.templates manifest - - Org entry: @your-org:web → manifest entry "web" from @your-org/create - When omitted, uses `create.defaultTemplate` from vite.config.ts if set. + [TEMPLATE] Builtin, local, or remote template name + [TEMPLATE_OPTIONS]... Arguments passed to the template without changes Options: - --directory DIR Target directory for the generated project. - --agent NAME Write coding agent instructions to AGENTS.md, CLAUDE.md, etc. - --no-agent Skip writing coding agent instructions - --editor NAME Write editor config files for the specified editor. - --no-editor Skip writing editor config files - --git Initialize a git repository - --no-git Skip git repository initialization - --hooks Set up pre-commit hooks (default in non-interactive mode) - --no-hooks Skip pre-commit hooks setup - --package-manager NAME Use specified package manager (pnpm, npm, yarn, bun) - --approve-builds Approve and run gated dependency build scripts without prompting - --verbose Show detailed scaffolding output - --no-interactive Run in non-interactive mode - --list List all available templates - -h, --help Show this help message - -Template Options: - Any arguments after -- are passed directly to the template. + --directory Target directory for the generated project + --agent Write coding agent instructions to AGENTS.md, CLAUDE.md, etc. + --no-agent Skip writing coding agent instructions + --editor Write editor config files for the specified editor + --no-editor Skip writing editor config files + --git Initialize a git repository + --no-git Skip git repository initialization + --hooks Set up pre-commit hooks (default in non-interactive mode) + --no-hooks Skip pre-commit hooks setup + --package-manager Use the specified package manager + --approve-builds Approve and run gated dependency build scripts without prompting + --verbose Show detailed scaffolding output + --interactive Enable interactive prompts + --no-interactive Run in non-interactive mode + --list List all available templates + -h, --help Show this help message Examples: - # Interactive mode - vp create - - # Use existing templates (shorthand expands to create-* packages) - vp create vite - vp create @tanstack/start - vp create svelte - vp create vite -- --template react-ts - - # Full package names also work - vp create create-vite - vp create create-next-app - - # Create Vite+ monorepo, application, library, or generator scaffolds - vp create vite:monorepo - vp create vite:application - vp create vite:library - vp create vite:generator - - # Use templates from GitHub (via degit) - vp create github:user/repo - vp create https://github.com/user/template-repo - - # Pick from an org that publishes @scope/create with createConfig.templates - vp create @your-org # interactive picker - vp create @your-org:web # direct manifest-entry selection + vp create # Interactive mode + vp create vite # Use create-vite + vp create vite -- --template react-ts # Pass template options + vp create vite:monorepo # Create a Vite+ monorepo + vp create github:user/repo # Use a GitHub template + vp create @your-org # Open an org template picker Documentation: https://viteplus.dev/guide/create ``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/package.json b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/package.json new file mode 100644 index 0000000000..3cbcee767f --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/package.json @@ -0,0 +1,5 @@ +{ + "name": "create-template-args-fixture", + "private": true, + "packageManager": "pnpm@10.0.0" +} diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/packages/args-template/bin/index.mjs b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/packages/args-template/bin/index.mjs new file mode 100644 index 0000000000..c3040324a3 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/packages/args-template/bin/index.mjs @@ -0,0 +1,14 @@ +#!/usr/bin/env node +import { mkdirSync, writeFileSync } from 'node:fs'; +import path from 'node:path'; + +const args = process.argv.slice(2); +const directoryIndex = args.indexOf('--directory'); +const directory = directoryIndex === -1 ? 'output' : args[directoryIndex + 1]; + +mkdirSync(directory, { recursive: true }); +writeFileSync( + path.join(directory, 'package.json'), + `${JSON.stringify({ name: directory, version: '0.0.0', private: true }, null, 2)}\n`, +); +writeFileSync(path.join(directory, 'template-args.json'), `${JSON.stringify(args, null, 2)}\n`); diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/packages/args-template/package.json b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/packages/args-template/package.json new file mode 100644 index 0000000000..4fcc3a2d50 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/packages/args-template/package.json @@ -0,0 +1,7 @@ +{ + "name": "args-template", + "version": "0.0.0", + "private": true, + "bin": "./bin/index.mjs", + "type": "module" +} diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/pnpm-workspace.yaml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/pnpm-workspace.yaml new file mode 100644 index 0000000000..924b55f42e --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/pnpm-workspace.yaml @@ -0,0 +1,2 @@ +packages: + - packages/* diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/snapshots.toml new file mode 100644 index 0000000000..e615df8a0f --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/snapshots.toml @@ -0,0 +1,8 @@ +[[case]] +name = "command_create_template_args" +vp = ["local", "global"] +comment = "Create forwards every token after the first -- without changes." +steps = [ + { argv = ["vp", "create", "recorder", "--no-interactive", "--no-agent", "--no-editor", "--no-hooks", "--", "--directory", "output", "--flag=value", "-x", "--", "literal"], continue-on-failure = true }, + { argv = ["vpt", "print-file", "packages/output/template-args.json"], continue-on-failure = true }, +] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/snapshots/command_create_template_args.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/snapshots/command_create_template_args.global.md new file mode 100644 index 0000000000..f817fd607a --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/snapshots/command_create_template_args.global.md @@ -0,0 +1,27 @@ +# command_create_template_args + +Create forwards every token after the first -- without changes. + +## `vp create recorder --no-interactive --no-agent --no-editor --no-hooks -- --directory output --flag=value -x -- literal` + +``` + +Generating project… + +Running: node /packages/args-template/bin/index.mjs --directory output --flag=value -x -- literal + +Monorepo integration... + +Formatting code... + +Code formatted +◇ Scaffolded packages/output +• Node pnpm +→ Next: cd packages/output && vp run +``` + +## `vpt print-file packages/output/template-args.json` + +``` +["--directory", "output", "--flag=value", "-x", "--", "literal"] +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/snapshots/command_create_template_args.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/snapshots/command_create_template_args.local.md new file mode 100644 index 0000000000..f817fd607a --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/snapshots/command_create_template_args.local.md @@ -0,0 +1,27 @@ +# command_create_template_args + +Create forwards every token after the first -- without changes. + +## `vp create recorder --no-interactive --no-agent --no-editor --no-hooks -- --directory output --flag=value -x -- literal` + +``` + +Generating project… + +Running: node /packages/args-template/bin/index.mjs --directory output --flag=value -x -- literal + +Monorepo integration... + +Formatting code... + +Code formatted +◇ Scaffolded packages/output +• Node pnpm +→ Next: cd packages/output && vp run +``` + +## `vpt print-file packages/output/template-args.json` + +``` +["--directory", "output", "--flag=value", "-x", "--", "literal"] +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/vite.config.ts b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/vite.config.ts new file mode 100644 index 0000000000..0f17a6db0c --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_create_template_args/vite.config.ts @@ -0,0 +1,13 @@ +import { defineConfig } from 'vite-plus'; + +export default defineConfig({ + create: { + templates: [ + { + name: 'recorder', + description: 'Record each template argument.', + template: './packages/args-template', + }, + ], + }, +}); diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_hooks_help/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_hooks_help/snapshots.toml index 8ace63f5ef..878a219136 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_hooks_help/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_hooks_help/snapshots.toml @@ -4,5 +4,6 @@ vp = ["local", "global"] steps = [ { argv = ["vp", "hooks", "-h"], continue-on-failure = true }, { argv = ["vp", "hooks", "--help"], continue-on-failure = true }, + { argv = ["vp", "hooks", "enable", "--help"], continue-on-failure = true }, { argv = ["vp", "help", "hooks"], continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_hooks_help/snapshots/command_hooks_help.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_hooks_help/snapshots/command_hooks_help.global.md index fcd8511606..ef60f7dec4 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_hooks_help/snapshots/command_hooks_help.global.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_hooks_help/snapshots/command_hooks_help.global.md @@ -9,15 +9,14 @@ Usage: vp hooks [OPTIONS] Manage the Vite+ Git hook dispatcher for this repository. +Options: + -h, --help Show this help message + Commands: enable Install or refresh the hook dispatcher (sets core.hooksPath) disable Disable hooks: unset core.hooksPath, remove /_, persist preference status Show preference, core.hooksPath, and dispatcher state -Options: - --hooks-dir Custom hooks directory (default: .vite-hooks, or last used) - -h, --help Show this help message - Environment: VP_GIT_HOOKS=0 Skip dispatcher install in enable (and skip hooks at commit time) @@ -39,15 +38,14 @@ Usage: vp hooks [OPTIONS] Manage the Vite+ Git hook dispatcher for this repository. +Options: + -h, --help Show this help message + Commands: enable Install or refresh the hook dispatcher (sets core.hooksPath) disable Disable hooks: unset core.hooksPath, remove /_, persist preference status Show preference, core.hooksPath, and dispatcher state -Options: - --hooks-dir Custom hooks directory (default: .vite-hooks, or last used) - -h, --help Show this help message - Environment: VP_GIT_HOOKS=0 Skip dispatcher install in enable (and skip hooks at commit time) @@ -60,6 +58,22 @@ Examples: Documentation: https://viteplus.dev/guide/commit-hooks ``` +## `vp hooks enable --help` + +``` +VITE+ - The Unified Toolchain for the Web + +Usage: vp hooks enable [OPTIONS] + +Install or refresh the hook dispatcher (sets core.hooksPath) + +Options: + --hooks-dir Custom hooks directory (default: .vite-hooks, or last used) + -h, --help Show this help message + +Documentation: https://viteplus.dev/guide/commit-hooks +``` + ## `vp help hooks` ``` @@ -69,15 +83,14 @@ Usage: vp hooks [OPTIONS] Manage the Vite+ Git hook dispatcher for this repository. +Options: + -h, --help Show this help message + Commands: enable Install or refresh the hook dispatcher (sets core.hooksPath) disable Disable hooks: unset core.hooksPath, remove /_, persist preference status Show preference, core.hooksPath, and dispatcher state -Options: - --hooks-dir Custom hooks directory (default: .vite-hooks, or last used) - -h, --help Show this help message - Environment: VP_GIT_HOOKS=0 Skip dispatcher install in enable (and skip hooks at commit time) diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_hooks_help/snapshots/command_hooks_help.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_hooks_help/snapshots/command_hooks_help.local.md index fcd8511606..ef60f7dec4 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_hooks_help/snapshots/command_hooks_help.local.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_hooks_help/snapshots/command_hooks_help.local.md @@ -9,15 +9,14 @@ Usage: vp hooks [OPTIONS] Manage the Vite+ Git hook dispatcher for this repository. +Options: + -h, --help Show this help message + Commands: enable Install or refresh the hook dispatcher (sets core.hooksPath) disable Disable hooks: unset core.hooksPath, remove /_, persist preference status Show preference, core.hooksPath, and dispatcher state -Options: - --hooks-dir Custom hooks directory (default: .vite-hooks, or last used) - -h, --help Show this help message - Environment: VP_GIT_HOOKS=0 Skip dispatcher install in enable (and skip hooks at commit time) @@ -39,15 +38,14 @@ Usage: vp hooks [OPTIONS] Manage the Vite+ Git hook dispatcher for this repository. +Options: + -h, --help Show this help message + Commands: enable Install or refresh the hook dispatcher (sets core.hooksPath) disable Disable hooks: unset core.hooksPath, remove /_, persist preference status Show preference, core.hooksPath, and dispatcher state -Options: - --hooks-dir Custom hooks directory (default: .vite-hooks, or last used) - -h, --help Show this help message - Environment: VP_GIT_HOOKS=0 Skip dispatcher install in enable (and skip hooks at commit time) @@ -60,6 +58,22 @@ Examples: Documentation: https://viteplus.dev/guide/commit-hooks ``` +## `vp hooks enable --help` + +``` +VITE+ - The Unified Toolchain for the Web + +Usage: vp hooks enable [OPTIONS] + +Install or refresh the hook dispatcher (sets core.hooksPath) + +Options: + --hooks-dir Custom hooks directory (default: .vite-hooks, or last used) + -h, --help Show this help message + +Documentation: https://viteplus.dev/guide/commit-hooks +``` + ## `vp help hooks` ``` @@ -69,15 +83,14 @@ Usage: vp hooks [OPTIONS] Manage the Vite+ Git hook dispatcher for this repository. +Options: + -h, --help Show this help message + Commands: enable Install or refresh the hook dispatcher (sets core.hooksPath) disable Disable hooks: unset core.hooksPath, remove /_, persist preference status Show preference, core.hooksPath, and dispatcher state -Options: - --hooks-dir Custom hooks directory (default: .vite-hooks, or last used) - -h, --help Show this help message - Environment: VP_GIT_HOOKS=0 Skip dispatcher install in enable (and skip hooks at commit time) diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_js_args_strict/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_js_args_strict/snapshots.toml new file mode 100644 index 0000000000..2017fbdde3 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_js_args_strict/snapshots.toml @@ -0,0 +1,21 @@ +[[case]] +name = "command_js_args_strict" +vp = ["local", "global"] +comment = "JavaScript-owned commands reject invalid arguments before command work starts." +steps = [ + { argv = ["vp", "staged", "--unknown"], continue-on-failure = true }, + { argv = ["vp", "staged", "--cwd"], continue-on-failure = true }, + { argv = ["vp", "staged", "--no-cwd"], continue-on-failure = true }, + { argv = ["vp", "config", "--unknown"], continue-on-failure = true }, + { argv = ["vp", "config", "--hooks-dir"], continue-on-failure = true }, + { argv = ["vp", "config", "--no-hooks-dir"], continue-on-failure = true }, + { argv = ["vp", "hooks", "unknown"], continue-on-failure = true }, + { argv = ["vp", "hooks", "enable", "--hooks-dir"], continue-on-failure = true }, + { argv = ["vp", "hooks", "enable", "--no-hooks-dir"], continue-on-failure = true }, + { argv = ["vp", "migrate", "--unknown"], continue-on-failure = true }, + { argv = ["vp", "migrate", "--agent"], continue-on-failure = true }, + { argv = ["vp", "migrate", "--no-full"], continue-on-failure = true }, + { argv = ["vp", "create", "--unknown"], continue-on-failure = true }, + { argv = ["vp", "create", "--directory"], continue-on-failure = true }, + { argv = ["vp", "create", "--no-directory"], continue-on-failure = true }, +] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_js_args_strict/snapshots/command_js_args_strict.global.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_js_args_strict/snapshots/command_js_args_strict.global.md new file mode 100644 index 0000000000..8e0ee9efe4 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_js_args_strict/snapshots/command_js_args_strict.global.md @@ -0,0 +1,216 @@ +# command_js_args_strict + +JavaScript-owned commands reject invalid arguments before command work starts. + +## `vp staged --unknown` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--unknown' found + +Usage: vp staged [OPTIONS] + +For more information, try '--help'. +``` + +## `vp staged --cwd` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: a value is required for '--cwd ' but none was supplied + +For more information, try '--help'. +``` + +## `vp staged --no-cwd` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--no-cwd' found + +Usage: vp staged [OPTIONS] + +For more information, try '--help'. +``` + +## `vp config --unknown` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--unknown' found + +Usage: vp config [OPTIONS] + +For more information, try '--help'. +``` + +## `vp config --hooks-dir` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: a value is required for '--hooks-dir ' but none was supplied + +For more information, try '--help'. +``` + +## `vp config --no-hooks-dir` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--no-hooks-dir' found + + tip: a similar argument exists: '--no-hooks' + +Usage: vp config --no-hooks + +For more information, try '--help'. +``` + +## `vp hooks unknown` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unrecognized subcommand 'unknown' + +Usage: vp hooks [OPTIONS] + +For more information, try '--help'. +``` + +## `vp hooks enable --hooks-dir` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: a value is required for '--hooks-dir ' but none was supplied + +For more information, try '--help'. +``` + +## `vp hooks enable --no-hooks-dir` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--no-hooks-dir' found + + tip: a similar argument exists: '--hooks-dir' + +Usage: vp hooks enable --hooks-dir + +For more information, try '--help'. +``` + +## `vp migrate --unknown` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--unknown' found + + tip: to pass '--unknown' as a value, use '-- --unknown' + +Usage: vp migrate [PATH] [OPTIONS] + +For more information, try '--help'. +``` + +## `vp migrate --agent` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: a value is required for '--agent ' but none was supplied + +For more information, try '--help'. +``` + +## `vp migrate --no-full` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--no-full' found + + tip: to pass '--no-full' as a value, use '-- --no-full' + +Usage: vp migrate [PATH] [OPTIONS] + +For more information, try '--help'. +``` + +## `vp create --unknown` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--unknown' found + + tip: to pass '--unknown' as a value, use '-- --unknown' + +Usage: vp create [TEMPLATE] [OPTIONS] [-- TEMPLATE_OPTIONS] + +For more information, try '--help'. +``` + +## `vp create --directory` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: a value is required for '--directory ' but none was supplied + +For more information, try '--help'. +``` + +## `vp create --no-directory` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--no-directory' found + + tip: a similar argument exists: '--no-editor' + tip: to pass '--no-directory' as a value, use '-- --no-directory' + +Usage: vp create [TEMPLATE] [OPTIONS] [-- TEMPLATE_OPTIONS] + +For more information, try '--help'. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_js_args_strict/snapshots/command_js_args_strict.local.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_js_args_strict/snapshots/command_js_args_strict.local.md new file mode 100644 index 0000000000..8e0ee9efe4 --- /dev/null +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_js_args_strict/snapshots/command_js_args_strict.local.md @@ -0,0 +1,216 @@ +# command_js_args_strict + +JavaScript-owned commands reject invalid arguments before command work starts. + +## `vp staged --unknown` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--unknown' found + +Usage: vp staged [OPTIONS] + +For more information, try '--help'. +``` + +## `vp staged --cwd` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: a value is required for '--cwd ' but none was supplied + +For more information, try '--help'. +``` + +## `vp staged --no-cwd` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--no-cwd' found + +Usage: vp staged [OPTIONS] + +For more information, try '--help'. +``` + +## `vp config --unknown` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--unknown' found + +Usage: vp config [OPTIONS] + +For more information, try '--help'. +``` + +## `vp config --hooks-dir` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: a value is required for '--hooks-dir ' but none was supplied + +For more information, try '--help'. +``` + +## `vp config --no-hooks-dir` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--no-hooks-dir' found + + tip: a similar argument exists: '--no-hooks' + +Usage: vp config --no-hooks + +For more information, try '--help'. +``` + +## `vp hooks unknown` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unrecognized subcommand 'unknown' + +Usage: vp hooks [OPTIONS] + +For more information, try '--help'. +``` + +## `vp hooks enable --hooks-dir` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: a value is required for '--hooks-dir ' but none was supplied + +For more information, try '--help'. +``` + +## `vp hooks enable --no-hooks-dir` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--no-hooks-dir' found + + tip: a similar argument exists: '--hooks-dir' + +Usage: vp hooks enable --hooks-dir + +For more information, try '--help'. +``` + +## `vp migrate --unknown` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--unknown' found + + tip: to pass '--unknown' as a value, use '-- --unknown' + +Usage: vp migrate [PATH] [OPTIONS] + +For more information, try '--help'. +``` + +## `vp migrate --agent` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: a value is required for '--agent ' but none was supplied + +For more information, try '--help'. +``` + +## `vp migrate --no-full` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--no-full' found + + tip: to pass '--no-full' as a value, use '-- --no-full' + +Usage: vp migrate [PATH] [OPTIONS] + +For more information, try '--help'. +``` + +## `vp create --unknown` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--unknown' found + + tip: to pass '--unknown' as a value, use '-- --unknown' + +Usage: vp create [TEMPLATE] [OPTIONS] [-- TEMPLATE_OPTIONS] + +For more information, try '--help'. +``` + +## `vp create --directory` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: a value is required for '--directory ' but none was supplied + +For more information, try '--help'. +``` + +## `vp create --no-directory` + +**Exit code:** 1 + +``` +VITE+ - The Unified Toolchain for the Web + +error: unexpected argument '--no-directory' found + + tip: a similar argument exists: '--no-editor' + tip: to pass '--no-directory' as a value, use '-- --no-directory' + +Usage: vp create [TEMPLATE] [OPTIONS] [-- TEMPLATE_OPTIONS] + +For more information, try '--help'. +``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_staged_concurrent/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_staged_concurrent/snapshots.toml index b603d47b7e..34116ab223 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_staged_concurrent/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_staged_concurrent/snapshots.toml @@ -7,8 +7,8 @@ steps = [ { argv = ["git", "-c", "user.name=Vite Plus", "-c", "user.email=vite-plus@example.com", "commit", "-m", "init"], snapshot = false }, { argv = ["vpt", "write-file", "a.txt", "changed\n"], snapshot = false }, { argv = ["git", "add", "a.txt"], snapshot = false }, - { argv = ["vp", "staged", "--no-concurrent", "--verbose"], comment = "--no-concurrent should execute staged tasks instead of stalling", envs = [["TMPDIR", "${workspace}"]], timeout = 10000 }, - { argv = ["vp", "staged", "--concurrent=0"], comment = "zero concurrency should fail before starting lint-staged", continue-on-failure = true }, - { argv = ["vp", "staged", "--no-cwd"], comment = "negated string options should report a CLI error", continue-on-failure = true }, - { argv = ["vp", "staged", "--no-diff"], comment = "negated diff should report a CLI error", continue-on-failure = true }, + { argv = ["vp", "staged", "--no-concurrent", "--verbose"], comment = "--no-concurrent runs staged tasks and does not stall", envs = [["TMPDIR", "${workspace}"]], timeout = 10000 }, + { argv = ["vp", "staged", "--concurrent=0"], comment = "zero concurrency fails before lint-staged starts", continue-on-failure = true }, + { argv = ["vp", "staged", "--no-cwd"], comment = "negated string options report a CLI error", continue-on-failure = true }, + { argv = ["vp", "staged", "--no-diff"], comment = "negated diff reports a CLI error", continue-on-failure = true }, ] diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_staged_concurrent/snapshots/command_staged_concurrent.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_staged_concurrent/snapshots/command_staged_concurrent.md index 598fc112bc..d739e2e6d5 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_staged_concurrent/snapshots/command_staged_concurrent.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_staged_concurrent/snapshots/command_staged_concurrent.md @@ -18,7 +18,7 @@ ## `TMPDIR=${workspace} vp staged --no-concurrent --verbose` ---no-concurrent should execute staged tasks instead of stalling +--no-concurrent runs staged tasks and does not stall ``` ✔ Backed up original state in git stash () @@ -32,36 +32,46 @@ linted /a.txt ## `vp staged --concurrent=0` -zero concurrency should fail before starting lint-staged +zero concurrency fails before lint-staged starts **Exit code:** 1 ``` VITE+ - The Unified Toolchain for the Web -error: Option "--concurrent" must be true, false, or a number greater than 0. +error: invalid value '0' for '--concurrent []': use true, false, or an integer from 1 through 4294967295 + +For more information, try '--help'. ``` ## `vp staged --no-cwd` -negated string options should report a CLI error +negated string options report a CLI error **Exit code:** 1 ``` VITE+ - The Unified Toolchain for the Web -error: Option "--no-cwd" is not supported. Use "--cwd ". +error: unexpected argument '--no-cwd' found + +Usage: vp staged [OPTIONS] + +For more information, try '--help'. ``` ## `vp staged --no-diff` -negated diff should report a CLI error +negated diff reports a CLI error **Exit code:** 1 ``` VITE+ - The Unified Toolchain for the Web -error: Option "--no-diff" is not supported. Use "--diff ". +error: unexpected argument '--no-diff' found + +Usage: vp staged [OPTIONS] + +For more information, try '--help'. ``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_staged_help/snapshots/command_staged_help.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_staged_help/snapshots/command_staged_help.md index 80d0f60290..bf7be85f6e 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_staged_help/snapshots/command_staged_help.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_staged_help/snapshots/command_staged_help.md @@ -5,27 +5,28 @@ ``` VITE+ - The Unified Toolchain for the Web -Usage: vp staged [options] +Usage: vp staged [OPTIONS] Run linters on staged files using staged config from vite.config.ts. Options: - --allow-empty Allow empty commits when tasks revert all staged changes - -p, --concurrent Number of tasks to run concurrently, or false for serial - --continue-on-error Run all tasks to completion even if one fails - --cwd Working directory to run all tasks in - -d, --debug Enable debug output - --diff Override the default --staged flag of git diff - --diff-filter Override the default --diff-filter=ACMR flag of git diff - --fail-on-changes Fail with exit code 1 when tasks modify tracked files - --hide-partially-staged Hide unstaged changes from partially staged files - --hide-unstaged Hide all unstaged changes before running tasks - --no-stash Disable the backup stash - -q, --quiet Disable console output - -r, --relative Pass filepaths relative to cwd to tasks - --revert Revert to original state in case of errors - -v, --verbose Show task output even when tasks succeed - -h, --help Show this help message + --allow-empty Allow empty commits when tasks revert all staged changes + -p, --concurrent [] Run tasks at the same time. Use false to run one task at a time + --no-concurrent Run one task at a time + --continue-on-error Run all tasks to completion even if one fails + --cwd Working directory to run all tasks in + -d, --debug Enable debug output + --diff Override the default --staged flag of git diff + --diff-filter Override the default --diff-filter=ACMR flag of git diff + --fail-on-changes Fail with exit code 1 when tasks modify tracked files + --hide-partially-staged Hide unstaged changes from partially staged files + --hide-unstaged Hide all unstaged changes before running tasks + --no-stash Disable the backup stash + -q, --quiet Disable console output + -r, --relative Pass filepaths relative to cwd to tasks + --revert Revert to original state in case of errors + -v, --verbose Show task output even when tasks succeed + -h, --help Show this help message Documentation: https://viteplus.dev/guide/commit-hooks ``` @@ -35,27 +36,28 @@ Documentation: https://viteplus.dev/guide/commit-hooks ``` VITE+ - The Unified Toolchain for the Web -Usage: vp staged [options] +Usage: vp staged [OPTIONS] Run linters on staged files using staged config from vite.config.ts. Options: - --allow-empty Allow empty commits when tasks revert all staged changes - -p, --concurrent Number of tasks to run concurrently, or false for serial - --continue-on-error Run all tasks to completion even if one fails - --cwd Working directory to run all tasks in - -d, --debug Enable debug output - --diff Override the default --staged flag of git diff - --diff-filter Override the default --diff-filter=ACMR flag of git diff - --fail-on-changes Fail with exit code 1 when tasks modify tracked files - --hide-partially-staged Hide unstaged changes from partially staged files - --hide-unstaged Hide all unstaged changes before running tasks - --no-stash Disable the backup stash - -q, --quiet Disable console output - -r, --relative Pass filepaths relative to cwd to tasks - --revert Revert to original state in case of errors - -v, --verbose Show task output even when tasks succeed - -h, --help Show this help message + --allow-empty Allow empty commits when tasks revert all staged changes + -p, --concurrent [] Run tasks at the same time. Use false to run one task at a time + --no-concurrent Run one task at a time + --continue-on-error Run all tasks to completion even if one fails + --cwd Working directory to run all tasks in + -d, --debug Enable debug output + --diff Override the default --staged flag of git diff + --diff-filter Override the default --diff-filter=ACMR flag of git diff + --fail-on-changes Fail with exit code 1 when tasks modify tracked files + --hide-partially-staged Hide unstaged changes from partially staged files + --hide-unstaged Hide all unstaged changes before running tasks + --no-stash Disable the backup stash + -q, --quiet Disable console output + -r, --relative Pass filepaths relative to cwd to tasks + --revert Revert to original state in case of errors + -v, --verbose Show task output even when tasks succeed + -h, --help Show this help message Documentation: https://viteplus.dev/guide/commit-hooks ``` @@ -65,27 +67,28 @@ Documentation: https://viteplus.dev/guide/commit-hooks ``` VITE+ - The Unified Toolchain for the Web -Usage: vp staged [options] +Usage: vp staged [OPTIONS] Run linters on staged files using staged config from vite.config.ts. Options: - --allow-empty Allow empty commits when tasks revert all staged changes - -p, --concurrent Number of tasks to run concurrently, or false for serial - --continue-on-error Run all tasks to completion even if one fails - --cwd Working directory to run all tasks in - -d, --debug Enable debug output - --diff Override the default --staged flag of git diff - --diff-filter Override the default --diff-filter=ACMR flag of git diff - --fail-on-changes Fail with exit code 1 when tasks modify tracked files - --hide-partially-staged Hide unstaged changes from partially staged files - --hide-unstaged Hide all unstaged changes before running tasks - --no-stash Disable the backup stash - -q, --quiet Disable console output - -r, --relative Pass filepaths relative to cwd to tasks - --revert Revert to original state in case of errors - -v, --verbose Show task output even when tasks succeed - -h, --help Show this help message + --allow-empty Allow empty commits when tasks revert all staged changes + -p, --concurrent [] Run tasks at the same time. Use false to run one task at a time + --no-concurrent Run one task at a time + --continue-on-error Run all tasks to completion even if one fails + --cwd Working directory to run all tasks in + -d, --debug Enable debug output + --diff Override the default --staged flag of git diff + --diff-filter Override the default --diff-filter=ACMR flag of git diff + --fail-on-changes Fail with exit code 1 when tasks modify tracked files + --hide-partially-staged Hide unstaged changes from partially staged files + --hide-unstaged Hide all unstaged changes before running tasks + --no-stash Disable the backup stash + -q, --quiet Disable console output + -r, --relative Pass filepaths relative to cwd to tasks + --revert Revert to original state in case of errors + -v, --verbose Show task output even when tasks succeed + -h, --help Show this help message Documentation: https://viteplus.dev/guide/commit-hooks ``` diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_legacy_key/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_legacy_key/snapshots.toml index 4750d215e9..c5ed1e7561 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_legacy_key/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_legacy_key/snapshots.toml @@ -11,8 +11,6 @@ steps = [ "migrate", "--no-interactive", "--no-hooks", - "--package-manager", - "pnpm", ], comment = "migrate pins the toolchain through the workspace catalog", continue-on-failure = true }, { argv = [ "vpt", diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_legacy_key/snapshots/command_update_catalog_protocol_legacy_key.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_legacy_key/snapshots/command_update_catalog_protocol_legacy_key.md index 58722b5824..978fd3a7ab 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_legacy_key/snapshots/command_update_catalog_protocol_legacy_key.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_legacy_key/snapshots/command_update_catalog_protocol_legacy_key.md @@ -2,7 +2,7 @@ #2309 repair path. Migrate first so the catalog holds a real PINNED toolchain version (the reporter's shape), then downgrade the override key to the pre-fix bare spelling a project migrated by an older Vite+ still carries. -## `vp migrate --no-interactive --no-hooks --package-manager pnpm` +## `vp migrate --no-interactive --no-hooks` migrate pins the toolchain through the workspace catalog diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm/snapshots.toml index 39c7b8383f..f1a7e1b2f6 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm/snapshots.toml @@ -10,8 +10,6 @@ steps = [ "migrate", "--no-interactive", "--no-hooks", - "--package-manager", - "pnpm", ], comment = "migrate pins the toolchain through the workspace catalog", continue-on-failure = true }, { argv = [ "vpt", diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm/snapshots/command_update_catalog_protocol_pnpm.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm/snapshots/command_update_catalog_protocol_pnpm.md index dcebd89b54..379fecbba1 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm/snapshots/command_update_catalog_protocol_pnpm.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm/snapshots/command_update_catalog_protocol_pnpm.md @@ -1,6 +1,6 @@ # command_update_catalog_protocol_pnpm -## `vp migrate --no-interactive --no-hooks --package-manager pnpm` +## `vp migrate --no-interactive --no-hooks` migrate pins the toolchain through the workspace catalog diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm12/snapshots.toml b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm12/snapshots.toml index 8e260713c0..8345205d4c 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm12/snapshots.toml +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm12/snapshots.toml @@ -11,8 +11,6 @@ steps = [ "migrate", "--no-interactive", "--no-hooks", - "--package-manager", - "pnpm", ], comment = "migrate pins the toolchain through the workspace catalog", continue-on-failure = true }, { argv = [ "vpt", diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm12/snapshots/command_update_catalog_protocol_pnpm12.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm12/snapshots/command_update_catalog_protocol_pnpm12.md index faaf331eff..cc9426dfad 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm12/snapshots/command_update_catalog_protocol_pnpm12.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/command_update_catalog_protocol_pnpm12/snapshots/command_update_catalog_protocol_pnpm12.md @@ -2,7 +2,7 @@ #2309 on pnpm 12. pnpm 12 fixes the clobber upstream (a bare override key no longer strips a `catalog:` importer spec), so this pins that the range-qualified key vite-plus writes is also correct there rather than only being a pnpm 9-11 workaround. -## `vp migrate --no-interactive --no-hooks --package-manager pnpm` +## `vp migrate --no-interactive --no-hooks` migrate pins the toolchain through the workspace catalog diff --git a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_check/snapshots/migration_check.md b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_check/snapshots/migration_check.md index c1de7ffa38..90bbd46e80 100644 --- a/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_check/snapshots/migration_check.md +++ b/crates/vp_cli_snapshots/tests/cli_snapshots/fixtures/migration_check/snapshots/migration_check.md @@ -12,66 +12,38 @@ Usage: vp migrate [PATH] [OPTIONS] Migrate standalone Vite, Vitest, Oxlint, Oxfmt, and Prettier projects to unified Vite+. Arguments: - PATH Target directory to migrate (default: current directory) + [PATH] Target directory to migrate (default: current directory) Options: - --agent NAME Write coding agent instructions to AGENTS.md, CLAUDE.md, etc. + --agent Write coding agent instructions to AGENTS.md, CLAUDE.md, etc. --no-agent Skip writing coding agent instructions - --editor NAME Write editor config files into the project. + --editor Write editor config files into the project --no-editor Skip writing editor config files --hooks Set up pre-commit hooks (default in non-interactive mode) --no-hooks Skip pre-commit hooks setup - --full Existing Vite+ projects: also run the full setup (hooks, editor, agent files, ESLint/Prettier migration, framework shims, tsconfig baseUrl, .node-version). Without it, `vp migrate` only upgrades the toolchain version. + --interactive Enable interactive prompts --no-interactive Run in non-interactive mode (skip prompts and use defaults) + --full Also run the full setup for an existing Vite+ project -h, --help Show this help message Examples: - # Migrate current package - vp migrate - - # Migrate specific directory - vp migrate my-app - - # Non-interactive mode - vp migrate --no-interactive + vp migrate # Migrate the current package + vp migrate my-app # Migrate a directory + vp migrate --no-interactive # Use defaults without prompts Migration Prompt: Give this to a coding agent when you want it to drive the migration: Migrate this project to Vite+. - Vite+ replaces the current split tooling around runtime management, package - management, dev/build/test commands, linting, formatting, and packaging. - Run `vp help` and `vp help migrate` before making changes. - Use vp migrate --no-interactive in the workspace root. - Make sure the project is using Vite 8+ and Vitest 4.1+ before migrating. - - After the migration: - - Confirm `vite` imports were rewritten to `vite-plus` where needed - - Confirm `vitest` imports were rewritten to `vite-plus/test` where needed - - On pnpm, keep the `vite` / `vitest` entries that `vp migrate` aliased to - the Vite+ packages so the workspace override stays effective; with other - package managers you can remove them once those rewrites are confirmed - - Move remaining tool-specific config into the appropriate blocks in - `vite.config.ts` - - Command mapping: - - `vp run