Skip to content
Closed
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
14 changes: 14 additions & 0 deletions .devcontainer/devcontainer-lock.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"features": {
"ghcr.io/devcontainers-extra/features/fish-apt-get:1": {
"version": "1.0.5",
"resolved": "ghcr.io/devcontainers-extra/features/fish-apt-get@sha256:d3c21bb6aec6e0f9d5348adee443c70c31d5f4372b8ad5f56a0ab925b2725108",
"integrity": "sha256:d3c21bb6aec6e0f9d5348adee443c70c31d5f4372b8ad5f56a0ab925b2725108"
},
"ghcr.io/devcontainers/features/rust:1": {
"version": "1.5.0",
"resolved": "ghcr.io/devcontainers/features/rust@sha256:0c55e65f2e3df736e478f26ee4d5ed41bae6b54dac1318c443e31444c8ed283c",
"integrity": "sha256:0c55e65f2e3df736e478f26ee4d5ed41bae6b54dac1318c443e31444c8ed283c"
}
}
}
1 change: 1 addition & 0 deletions .github/ISSUE_TEMPLATE/bug_report.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ body:
- npm
- yarn
- pnpm
- aube
- bun
validations:
required: true
Expand Down
10 changes: 5 additions & 5 deletions .github/workflows/test-vp-create.yml
Original file line number Diff line number Diff line change
Expand Up @@ -291,8 +291,8 @@ jobs:
# brings the runtime in transitively. For npm/yarn/bun those keys
# are dropped (the root overrides/resolutions redirect the
# transitive/peer vite to @voidzero-dev/vite-plus-core regardless).
# For pnpm the aliased `vite` is kept on purpose: pnpm only surfaces
# the pnpm-workspace.yaml `overrides.vite: catalog:` entry through a
# For pnpm/aube the aliased `vite` is kept on purpose: pnpm/aube only
# surface the workspace YAML `overrides.vite: catalog:` entry through a
# package that directly depends on `vite`, so dropping it would make
# `vp why vite` report upstream vite and the override look ineffective.
node -e "
Expand All @@ -309,12 +309,12 @@ jobs:
const appDev = app.devDependencies || {};
const utilsDev = utils.devDependencies || {};

if (pm === 'pnpm') {
if (pm === 'pnpm' || pm === 'aube') {
if (!appDev['vite']) {
console.error('✗ pnpm apps/website should keep aliased vite so the workspace override stays effective');
console.error('✗ pnpm/aube apps/website should keep aliased vite so the workspace override stays effective');
process.exit(1);
}
console.log('✓ pnpm apps/website keeps aliased vite');
console.log('✓ pnpm/aube apps/website keeps aliased vite');
} else {
for (const name of ['vite', 'vitest']) {
if (appDev[name]) {
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,4 @@ rolldown-vite
vite
/crates/vite_global_cli/vp
.void/
.pnpm-store
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,7 @@ Use `vp migrate` to migrate to Vite+. It merges tool-specific config files such

#### Manage Dependencies

Vite+ automatically wraps your package manager (pnpm, npm, or Yarn) based on `packageManager` and lockfiles:
Vite+ automatically wraps your package manager (pnpm, aube, npm, Yarn, or Bun) based on `packageManager` and lockfiles:

- **add** - Add packages to dependencies
- **remove** (`rm`, `un`, `uninstall`) - Remove packages from dependencies
Expand Down Expand Up @@ -198,7 +198,7 @@ You need to add overrides to your package manager for `vite` and `vitest` so tha
}
```

If you are using `pnpm`, add this to your `pnpm-workspace.yaml`:
If you are using `pnpm` or `aube`, add this to your workspace YAML (`pnpm-workspace.yaml` or `aube-workspace.yaml`):

```yaml
overrides:
Expand Down
2 changes: 1 addition & 1 deletion crates/vite_global_cli/src/cli.rs
Original file line number Diff line number Diff line change
Expand Up @@ -558,7 +558,7 @@ fn run_tasks_completions(current: &OsStr) -> Vec<clap_complete::CompletionCandid
/// `Install`/`Add`/`Update`/`Remove` invoked with `-g`/`--global` are routed
/// through the vite-plus-managed Node.js install store (`commands::global`).
/// Everything else is forwarded to `vite_pm_cli::dispatch`, which executes
/// the underlying package manager (pnpm/npm/yarn/bun).
/// the underlying package manager (pnpm/aube/npm/yarn/bun).
async fn run_package_manager_command(
cwd: AbsolutePathBuf,
command: PackageManagerCommand,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ pub struct PackageMetadata {
/// Binary names that are JavaScript files (need Node.js to run).
#[serde(default)]
pub js_bins: HashSet<String>,
/// Package manager used for installation (npm, yarn, pnpm)
/// Package manager used for installation (npm, pnpm, aube, yarn, bun)
pub manager: String,
/// Installation timestamp
pub installed_at: DateTime<Utc>,
Expand Down
8 changes: 4 additions & 4 deletions crates/vite_global_cli/src/shim/dispatch.rs
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ fn resolve_npm_prefix(
/// `packageManager` field.
///
/// The match is intentionally strict to avoid translating commands: `npm` only uses
/// `npm@...`, `pnpm` only uses `pnpm@...`, etc.
/// `npm@...`, `pnpm` only uses `pnpm@...`, `aube` only uses `aube@...`, etc.
async fn resolve_matching_package_manager_tool(
cwd: &AbsolutePath,
tool: &str,
Expand Down Expand Up @@ -936,7 +936,7 @@ async fn dispatch_package_binary(tool: &str, args: &[String]) -> i32 {
match resolve_matching_package_manager_tool(&cwd, tool).await {
Ok(Some(tool_path)) => {
// Bun is a native binary and does not need a Node.js runtime on PATH;
// JS-based PMs (npm/pnpm/yarn) do.
// JS-based PMs (npm/pnpm/aube/yarn) do.
if pm_family != PackageManagerType::Bun {
let node_version = match resolve_with_cache(&cwd).await {
Ok(resolution) => resolution.version,
Expand Down Expand Up @@ -992,8 +992,8 @@ async fn dispatch_package_binary(tool: &str, args: &[String]) -> i32 {
};

// Determine Node.js version to use:
// - Package managers (pnpm, yarn): resolve from project context so they respect
// the project's engines.node / .node-version, falling back to install-time version
// - Package managers (pnpm/aube/yarn/bun): resolve from project context when possible,
// falling back to install-time version
// - Other package binaries: use the install-time version (original behavior)
let node_version = if is_package_manager_tool(tool) {
let cwd = match current_dir() {
Expand Down
2 changes: 1 addition & 1 deletion crates/vite_install/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@

- Auto-detects package manager type and version from package.json's `packageManager` field
- Downloads and caches the specified version
- Handles install, add, etc. commands for pnpm/yarn/npm.
- Handles install, add, etc. commands for pnpm/aube/yarn/npm/bun.
93 changes: 92 additions & 1 deletion crates/vite_install/src/commands/add.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl PackageManager {

match self.client {
PackageManagerType::Pnpm => {
bin_name = "pnpm".into();
bin_name = self.client.to_string();
// pnpm: --filter must come before command
if let Some(filters) = options.filters {
for filter in filters {
Expand Down Expand Up @@ -122,6 +122,59 @@ impl PackageManager {
args.push(format!("--allow-build={allow_build}"));
}
}
PackageManagerType::Aube => {
bin_name = self.client.to_string();
// aube: --filter must come before command
if let Some(filters) = options.filters {
for filter in filters {
args.push("--filter".into());
args.push(filter.clone());
}
}
args.push("add".into());

// aube: `add -w/--workspace` targets the workspace root's package.json.
if options.workspace_root {
args.push("--workspace".into());
}
// aube does not support pnpm's `add --workspace` semantics ("only add if the
// named package exists in the workspace").
if options.workspace_only {
output::warn("aube add does not support --workspace (only add if package exists in workspace)");
}

if let Some(save_dependency_type) = options.save_dependency_type {
match save_dependency_type {
SaveDependencyType::Production => {
// Default for aube.
}
SaveDependencyType::Dev => {
args.push("--save-dev".into());
}
SaveDependencyType::Peer => {
args.push("--save-peer".into());
}
SaveDependencyType::Optional => {
args.push("--save-optional".into());
}
}
}
if options.save_exact {
args.push("--save-exact".into());
}

if let Some(save_catalog_name) = options.save_catalog_name {
if save_catalog_name.is_empty() {
args.push("--save-catalog".into());
} else {
args.push(format!("--save-catalog-name={save_catalog_name}"));
}
}

if let Some(allow_build) = options.allow_build {
args.push(format!("--allow-build={allow_build}"));
}
}
PackageManagerType::Yarn => {
bin_name = "yarn".into();
// yarn: workspaces foreach --all --include {filter} add
Expand Down Expand Up @@ -600,4 +653,42 @@ mod tests {
assert_eq!(result.args, vec!["add", "--allow-build=react,napi", "react"]);
assert_eq!(result.bin_path, "pnpm");
}

#[test]
fn test_aube_add_workspace_root() {
let pm = create_mock_package_manager(PackageManagerType::Aube);
let result = pm.resolve_add_command(&AddCommandOptions {
packages: &["typescript".to_string()],
save_dependency_type: Some(SaveDependencyType::Dev),
save_exact: false,
filters: None,
workspace_root: true,
workspace_only: false,
global: false,
save_catalog_name: None,
allow_build: None,
pass_through_args: None,
});
assert_eq!(result.args, vec!["add", "--workspace", "--save-dev", "typescript"]);
assert_eq!(result.bin_path, "aube");
}

#[test]
fn test_aube_add_does_not_pass_pnpm_workspace_only_flag() {
let pm = create_mock_package_manager(PackageManagerType::Aube);
let result = pm.resolve_add_command(&AddCommandOptions {
packages: &["@myorg/utils".to_string()],
save_dependency_type: None,
save_exact: false,
filters: Some(&["app".to_string()]),
workspace_root: false,
workspace_only: true,
global: false,
save_catalog_name: None,
allow_build: None,
pass_through_args: None,
});
assert_eq!(result.args, vec!["--filter", "app", "add", "@myorg/utils"]);
assert_eq!(result.bin_path, "aube");
}
}
12 changes: 10 additions & 2 deletions crates/vite_install/src/commands/approve_builds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ const NPM_ADVISORY_NOTE: &str = "npm's allowScripts policy is advisory in npm 11
/// Options for the approve-builds command.
#[derive(Debug, Default)]
pub struct ApproveBuildsCommandOptions<'a> {
/// Packages to approve. Prefix with `!` to deny (pnpm only).
/// Packages to approve. Prefix with `!` to deny (pnpm & aube only).
pub packages: &'a [String],
/// Approve every package that is currently pending approval.
pub all: bool,
Expand Down Expand Up @@ -89,6 +89,14 @@ impl PackageManager {
}
args.extend(options.packages.iter().cloned());
}
PackageManagerType::Aube => {
bin_name = "aube".into();
args.push("approve-builds".into());
if options.all {
args.push("--all".into());
}
args.extend(options.packages.iter().cloned());
}
PackageManagerType::Bun => {
// bun has no allow/deny model — filter `!pkg` with a warning.
let (denies, approves): (Vec<&String>, Vec<&String>) =
Expand Down Expand Up @@ -221,7 +229,7 @@ impl PackageManager {
}
}

// Append pass-through args to the underlying PM (pnpm, npm, and bun reach here;
// Append pass-through args to the underlying PM (pnpm, aube, npm, and bun reach here;
// yarn and npm < 11.16.0 returned early above).
if let Some(extra) = options.pass_through_args {
args.extend_from_slice(extra);
Expand Down
4 changes: 2 additions & 2 deletions crates/vite_install/src/commands/audit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -71,8 +71,8 @@ impl PackageManager {
args.push("--json".into());
}
}
PackageManagerType::Pnpm => {
bin_name = "pnpm".into();
PackageManagerType::Pnpm | PackageManagerType::Aube => {
bin_name = self.client.to_string();
args.push("audit".into());

if options.fix {
Expand Down
7 changes: 4 additions & 3 deletions crates/vite_install/src/commands/cache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,8 @@ impl PackageManager {
let mut args: Vec<String> = Vec::new();

match self.client {
PackageManagerType::Pnpm => {
bin_name = "pnpm".into();
PackageManagerType::Pnpm | PackageManagerType::Aube => {
bin_name = self.client.to_string();

match options.subcommand {
"dir" | "path" => {
Expand All @@ -59,7 +59,8 @@ impl PackageManager {
}
_ => {
output::warn(&format!(
"pnpm cache subcommand '{}' not supported",
"{} cache subcommand '{}' not supported",
self.client,
options.subcommand
));
return None;
Expand Down
2 changes: 1 addition & 1 deletion crates/vite_install/src/commands/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ impl PackageManager {
let mut args: Vec<String> = Vec::new();

match self.client {
PackageManagerType::Pnpm => {
PackageManagerType::Pnpm | PackageManagerType::Aube => {
args.push("config".into());
args.push(options.subcommand.to_string());

Expand Down
6 changes: 3 additions & 3 deletions crates/vite_install/src/commands/dedupe.rs
Original file line number Diff line number Diff line change
Expand Up @@ -38,11 +38,11 @@ impl PackageManager {
let mut args: Vec<String> = Vec::new();

match self.client {
PackageManagerType::Pnpm => {
bin_name = "pnpm".into();
PackageManagerType::Pnpm | PackageManagerType::Aube => {
bin_name = self.client.to_string();
args.push("dedupe".into());

// pnpm uses --check for dry-run
// pnpm/aube use --check for dry-run
if options.check {
args.push("--check".into());
}
Expand Down
2 changes: 1 addition & 1 deletion crates/vite_install/src/commands/dist_tag.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ impl PackageManager {
let bin_name: String;

match self.client {
PackageManagerType::Npm | PackageManagerType::Pnpm => {
PackageManagerType::Npm | PackageManagerType::Pnpm | PackageManagerType::Aube => {
bin_name = "npm".into();
args.push("dist-tag".into());
}
Expand Down
6 changes: 4 additions & 2 deletions crates/vite_install/src/commands/dlx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,9 @@ impl PackageManager {
let envs = HashMap::from([("PATH".to_string(), format_path_env(self.get_bin_prefix()))]);

match self.client {
PackageManagerType::Pnpm => self.resolve_pnpm_dlx(options, envs),
PackageManagerType::Pnpm | PackageManagerType::Aube => {
self.resolve_pnpm_dlx(options, envs)
}
PackageManagerType::Npm => self.resolve_npm_dlx(options, envs),
PackageManagerType::Yarn => {
if self.version.starts_with("1.") {
Expand Down Expand Up @@ -87,7 +89,7 @@ impl PackageManager {
// Add command arguments
args.extend(options.args.iter().cloned());

ResolveCommandResult { bin_path: "pnpm".into(), args, envs }
ResolveCommandResult { bin_path: self.client.to_string(), args, envs }
}

fn resolve_npm_dlx(
Expand Down
12 changes: 6 additions & 6 deletions crates/vite_install/src/commands/install.rs
Original file line number Diff line number Diff line change
Expand Up @@ -34,11 +34,11 @@ pub struct InstallCommandOptions<'a> {
pub ignore_scripts: bool,
/// Don't read or generate lockfile
pub no_lockfile: bool,
/// Fix broken lockfile entries (pnpm and yarn@2+ only)
/// Fix broken lockfile entries (pnpm/aube and yarn@2+ only)
pub fix_lockfile: bool,
/// Create flat `node_modules` (pnpm only)
/// Create flat `node_modules` (pnpm/aube only)
pub shamefully_hoist: bool,
/// Re-run resolution for peer dependency analysis (pnpm only)
/// Re-run resolution for peer dependency analysis (pnpm/aube only)
pub resolution_only: bool,
/// Suppress output (silent mode)
pub silent: bool,
Expand Down Expand Up @@ -75,9 +75,9 @@ impl PackageManager {
let mut args: Vec<String> = Vec::new();

match self.client {
PackageManagerType::Pnpm => {
bin_name = "pnpm".into();
// pnpm: --filter must come before command
PackageManagerType::Pnpm | PackageManagerType::Aube => {
bin_name = self.client.to_string();
// pnpm/aube: --filter must come before command
if let Some(filters) = options.filters {
for filter in filters {
args.push("--filter".into());
Expand Down
4 changes: 2 additions & 2 deletions crates/vite_install/src/commands/link.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ impl PackageManager {
let mut args: Vec<String> = Vec::new();

match self.client {
PackageManagerType::Pnpm => {
bin_name = "pnpm".into();
PackageManagerType::Pnpm | PackageManagerType::Aube => {
bin_name = self.client.to_string();
args.push("link".into());
}
PackageManagerType::Yarn => {
Expand Down
Loading