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
20 changes: 18 additions & 2 deletions crates/vite_package_manager/src/add.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use std::collections::HashMap;
use std::{collections::HashMap, process::ExitStatus};

use vite_error::Error;
use vite_path::AbsolutePath;

use crate::package_manager::{
PackageManager, PackageManagerType, ResolveCommandResult, format_path_env,
PackageManager, PackageManagerType, ResolveCommandResult, format_path_env, run_command,
};

/// The type of dependency to save.
Expand Down Expand Up @@ -33,6 +36,19 @@ pub struct AddCommandOptions<'a> {
}

impl PackageManager {
/// Run the add command with the package manager.
/// Return the exit status of the command.
#[must_use]
pub async fn run_add_command(
&self,
options: &AddCommandOptions<'_>,
cwd: impl AsRef<AbsolutePath>,
) -> Result<ExitStatus, Error> {
let resolve_command = self.resolve_add_command(options);
run_command(&resolve_command.bin_path, &resolve_command.args, &resolve_command.envs, cwd)
.await
}

/// Resolve the add command.
#[must_use]
pub fn resolve_add_command(&self, options: &AddCommandOptions) -> ResolveCommandResult {
Expand Down
28 changes: 25 additions & 3 deletions crates/vite_package_manager/src/package_manager.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@ use std::{
fs::{self, File},
io::{BufReader, Seek, SeekFrom},
path::Path,
process::{ExitStatus, Stdio},
};

use semver::{Version, VersionReq};
use serde::{Deserialize, Serialize};
use tokio::fs::remove_dir_all;
use tokio::{fs::remove_dir_all, process::Command};
use vite_error::Error;
use vite_path::{AbsolutePath, AbsolutePathBuf, RelativePathBuf};
use vite_str::Str;
Expand Down Expand Up @@ -138,8 +139,8 @@ impl PackageManagerBuilder {
}

impl PackageManager {
pub fn builder(workspace_root: impl AsRef<AbsolutePath>) -> PackageManagerBuilder {
PackageManagerBuilder::new(workspace_root)
pub fn builder(cwd: impl AsRef<AbsolutePath>) -> PackageManagerBuilder {
PackageManagerBuilder::new(cwd)
}

#[must_use]
Expand Down Expand Up @@ -600,6 +601,27 @@ pub(crate) fn format_path_env(bin_prefix: impl AsRef<Path>) -> String {
env::join_paths(paths).unwrap().to_string_lossy().to_string()
}

pub(crate) async fn run_command(
bin_name: &str,
args: &Vec<String>,
envs: &HashMap<String, String>,
cwd: impl AsRef<AbsolutePath>,
) -> Result<ExitStatus, Error> {
println!("Running: {} {}", bin_name, args.join(" "));

// TODO: color support for stdout/stderr
let status = Command::new(bin_name)
.args(args)
.envs(envs)
.current_dir(cwd.as_ref())
.stdin(Stdio::inherit())
.stdout(Stdio::inherit())
.stderr(Stdio::inherit())
.status()
.await?;
Ok(status)
}

#[cfg(test)]
mod tests {
use std::fs;
Expand Down
42 changes: 10 additions & 32 deletions crates/vite_task/src/add.rs
Original file line number Diff line number Diff line change
@@ -1,27 +1,24 @@
use petgraph::stable_graph::StableGraph;
use std::process::ExitStatus;

use vite_package_manager::{
add::{AddCommandOptions, SaveDependencyType},
package_manager::PackageManager,
};
use vite_path::AbsolutePathBuf;

use crate::{
Error, ResolveCommandResult, Workspace,
config::ResolvedTask,
schedule::{ExecutionPlan, ExecutionSummary},
};
use crate::Error;

/// Add command for adding packages to dependencies.
///
/// This command automatically detects the package manager and translates
/// the add command to the appropriate package manager-specific syntax.
pub struct AddCommand {
workspace_root: AbsolutePathBuf,
cwd: AbsolutePathBuf,
}

impl AddCommand {
pub fn new(workspace_root: AbsolutePathBuf) -> Self {
Self { workspace_root }
pub fn new(cwd: AbsolutePathBuf) -> Self {
Self { cwd }
}

pub async fn execute(
Expand All @@ -36,15 +33,11 @@ impl AddCommand {
global: bool,
allow_build: Option<&str>,
pass_through_args: Option<&[String]>,
) -> Result<ExecutionSummary, Error> {
) -> Result<ExitStatus, Error> {
if packages.is_empty() {
return Err(Error::NoPackagesSpecified);
}

// Detect package manager
let package_manager = PackageManager::builder(&self.workspace_root).build().await?;
let workspace = Workspace::partial_load(self.workspace_root)?;

let add_command_options = AddCommandOptions {
packages,
save_dependency_type,
Expand All @@ -57,26 +50,11 @@ impl AddCommand {
allow_build,
pass_through_args,
};
let resolve_command = package_manager.resolve_add_command(&add_command_options);

println!("Running: {} {}", resolve_command.bin_path, resolve_command.args.join(" "));

// TODO: set cacheable to false
let resolved_task = ResolvedTask::resolve_from_builtin_with_command_result(
&workspace,
"add",
resolve_command.args.iter(),
ResolveCommandResult { bin_path: resolve_command.bin_path, envs: resolve_command.envs },
false,
None,
)?;

let mut task_graph: StableGraph<ResolvedTask, ()> = Default::default();
task_graph.add_node(resolved_task);
let summary = ExecutionPlan::plan(task_graph, false)?.execute(&workspace).await?;
workspace.unload().await?;
// Detect package manager
let package_manager = PackageManager::builder(&self.cwd).build().await?;

Ok(summary)
package_manager.run_add_command(&add_command_options, &self.cwd).await
}
}

Expand Down
46 changes: 41 additions & 5 deletions crates/vite_task/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -241,7 +241,7 @@ async fn execute_add_command(
global: bool,
allow_build: Option<&str>,
pass_through_args: Option<&[String]>,
) -> Result<ExecutionSummary, Error> {
) -> Result<ExitStatus, Error> {
let save_dependency_type = if save_dev {
Some(SaveDependencyType::Dev)
} else if save_peer {
Expand Down Expand Up @@ -342,6 +342,37 @@ pub struct ResolvedUniversalViteConfig {
pub fmt: Option<FmtConfig>,
}

#[cfg(unix)]
fn fix_stdio_streams() {
// libuv may mark stdin/stdout/stderr as close-on-exec.
// As a workaround, we clear the FD_CLOEXEC flag on these file descriptors to prevent them from being closed when spawning child processes.
//
// For details see https://github.com/libuv/libuv/issues/2062
// Fixed by reference from https://github.com/electron/electron/pull/15555

use std::os::unix::io::RawFd;

use nix::libc;

unsafe {
// Helper function to clear FD_CLOEXEC flag on a file descriptor
let clear_cloexec = |fd: RawFd| {
// Get current file descriptor flags
let flags = libc::fcntl(fd, libc::F_GETFD);
if flags >= 0 {
// Clear the FD_CLOEXEC flag
let new_flags = flags & !libc::FD_CLOEXEC;
libc::fcntl(fd, libc::F_SETFD, new_flags);
}
};

// Clear FD_CLOEXEC on stdin, stdout, stderr
clear_cloexec(libc::STDIN_FILENO);
clear_cloexec(libc::STDOUT_FILENO);
clear_cloexec(libc::STDERR_FILENO);
}
}

/// Main entry point for vite-plus task execution.
///
/// # Execution Flow
Expand Down Expand Up @@ -409,6 +440,9 @@ pub async fn main<
>,
>,
) -> Result<std::process::ExitStatus, Error> {
#[cfg(unix)]
fix_stdio_streams();

// Auto-install dependencies if needed, but skip for install command itself, or if `VITE_DISABLE_AUTO_INSTALL=1` is set.
if !matches!(args.commands, Commands::Install { .. })
&& std::env::var_os("VITE_DISABLE_AUTO_INSTALL") != Some("1".into())
Expand Down Expand Up @@ -534,7 +568,7 @@ pub async fn main<
allow_build,
pass_through_args,
} => {
execute_add_command(
let exit_status = execute_add_command(
cwd,
packages,
*save_prod,
Expand All @@ -551,7 +585,8 @@ pub async fn main<
allow_build.as_deref(),
pass_through_args.as_deref(),
)
.await?
.await?;
return Ok(exit_status);
}
Commands::Install { args } => {
// Check if args contain packages - if yes, redirect to Add command
Expand All @@ -573,7 +608,7 @@ pub async fn main<
pass_through_args,
}) = parse_install_as_add(args)
{
execute_add_command(
let exit_status = execute_add_command(
cwd,
&packages,
save_prod,
Expand All @@ -590,7 +625,8 @@ pub async fn main<
allow_build.as_deref(),
pass_through_args.as_deref(),
)
.await?
.await?;
return Ok(exit_status);
} else {
install::InstallCommand::builder(cwd).build().execute(args).await?
}
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
"install-global-cli": "npm install -g ./packages/global",
"typecheck": "tsc -b tsconfig.json",
"lint": "vite lint && vite run typecheck",
"test": "vite test && pnpm -r snap-test",
"test": "vite test run && pnpm -r snap-test",
"prepare": "husky"
},
"devDependencies": {
Expand Down
2 changes: 2 additions & 0 deletions packages/cli/binding/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,8 @@ pub async fn run(options: CliOptions) -> Result<i32> {
)
.await;

tracing::debug!("Result: {result:?}");

match result {
Ok(exit_status) => Ok(exit_status.code().unwrap_or(1)),
Err(e) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
Running: npm install --include-workspace-root --save-dev --no-audit testnpm2

added 3 packages in <variable>ms

{
"name": "command-add-npm10-with-workspace",
"version": "1.0.0",
Expand All @@ -27,7 +26,6 @@ added 3 packages in <variable>ms
Running: npm install --no-audit @vite-plus-test/utils

up to date in <variable>ms

{
"name": "command-add-npm10-with-workspace",
"version": "1.0.0",
Expand Down Expand Up @@ -55,7 +53,6 @@ up to date in <variable>ms
Running: npm install --workspace app --no-audit testnpm2 test-vite-plus-install@<semver>

added 1 package in <variable>ms

{
"name": "command-add-npm10-with-workspace",
"version": "1.0.0",
Expand Down Expand Up @@ -87,7 +84,6 @@ added 1 package in <variable>ms
Running: npm install --workspace app --no-audit @vite-plus-test/utils

up to date in <variable>ms

{
"name": "command-add-npm10-with-workspace",
"version": "1.0.0",
Expand Down Expand Up @@ -120,7 +116,6 @@ up to date in <variable>ms
Running: npm install --workspace * --no-audit testnpm2 test-vite-plus-install@<semver>

up to date in <variable>ms

{
"name": "command-add-npm10-with-workspace",
"version": "1.0.0",
Expand Down Expand Up @@ -157,7 +152,6 @@ up to date in <variable>ms
Running: npm install --workspace * --include-workspace-root --save-exact --no-audit testnpm2 test-vite-plus-install@<semver>

up to date in <variable>ms

{
"name": "command-add-npm10-with-workspace",
"version": "1.0.0",
Expand Down Expand Up @@ -195,7 +189,6 @@ up to date in <variable>ms
Running: npm install --workspace * --include-workspace-root --no-audit test-vite-plus-package@<semver>

added 1 package in <variable>ms

{
"name": "command-add-npm10-with-workspace",
"version": "1.0.0",
Expand Down
5 changes: 0 additions & 5 deletions packages/global/snap-tests/command-add-npm10/snap.txt
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ Options:
Running: npm install --save-dev --no-audit testnpm2

added 1 package in <variable>ms

{
"name": "command-add-npm10",
"version": "1.0.0",
Expand All @@ -53,7 +52,6 @@ added 1 package in <variable>ms
Running: npm install --no-audit testnpm2 test-vite-plus-install

added 1 package in <variable>ms

{
"name": "command-add-npm10",
"version": "1.0.0",
Expand All @@ -70,7 +68,6 @@ added 1 package in <variable>ms
Running: npm install --save-peer --no-audit test-vite-plus-package@<semver>

added 1 package in <variable>ms

{
"name": "command-add-npm10",
"version": "1.0.0",
Expand All @@ -90,7 +87,6 @@ added 1 package in <variable>ms
Running: npm install --save-optional --no-audit test-vite-plus-package-optional

added 1 package in <variable>ms

{
"name": "command-add-npm10",
"version": "1.0.0",
Expand All @@ -113,7 +109,6 @@ added 1 package in <variable>ms
Running: npm install --loglevel=warn --no-audit test-vite-plus-package-optional

up to date in <variable>ms

{
"name": "command-add-npm10",
"version": "1.0.0",
Expand Down
Loading
Loading