Skip to content
Draft
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
30 changes: 28 additions & 2 deletions crates/vite_global_cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -294,8 +294,29 @@ fn print_unknown_argument_error(error: &clap::Error) -> bool {
true
}

#[tokio::main]
async fn main() -> ExitCode {
fn main() -> ExitCode {
// Advertise that this process tree is running under Vite+ so the tools we
// invoke (e.g. `vp dlx create-vite`) can detect vp as the package manager.
// The underlying package managers overwrite `npm_config_user_agent` with
// their own value, so we expose a dedicated variable that is passed through
// untouched and inherited by every child process (including the `npx`
// fallback used when there is no local `package.json`). Shim mode clears it
// again below, since there the user invokes the wrapped tool, not vp.
//
// SAFETY: `set_var` must run while the process is still single-threaded.
// This is the first statement in `main`, before the async runtime (and its
// worker threads) are created.
unsafe {
std::env::set_var(
vite_shared::env_vars::VP_USER_AGENT,
concat!("vp/", env!("CARGO_PKG_VERSION")),
);
Comment on lines +310 to +313

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid marking direct package-manager shims as vp

Because this is set before shim detection, any invocation through the managed npm/npx shims also exports VP_USER_AGENT before run() reaches shim::detect_shim_tool; in system-first mode this even survives when vp immediately execs the system package manager. A user running npx create-vite through Vite+'s shims is not using vp dlx, but create-vite will still see VP_USER_AGENT=vp/... and can scaffold commands for vp instead of the package manager the user actually invoked. Set this only on the normal vp command path, or clear it before dispatching shim invocations.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch, fixed in deeab22. VP_USER_AGENT is now cleared in the shim branch before shim::dispatch, so when vp runs as a managed npm/npx/node shim the wrapped tool and its children no longer see it. Verified: VP_SHIM_TOOL=node vp -e ... shows undefined, while vp dlx ... node -e ... still shows vp/0.2.1.

Comment on lines +310 to +313

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Set VP_USER_AGENT for local vp invocations too

This only runs in the Rust global binary, but the published vite-plus package also exposes its own vp bin and that JS entrypoint routes dlx through the NAPI package-manager path without setting this variable. In projects that invoke the local CLI directly, e.g. pnpm exec vp dlx create-vite or node_modules/.bin/vp dlx create-vite, the child create tool still won't see VP_USER_AGENT, so the new detection remains inconsistent for a supported vp entrypoint. Mirror this initialization in the local JS/NAPI path or a shared command launcher.

Useful? React with 👍 / 👎.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agreed this is a real consistency gap. Tracing it: user-facing vp dlx is implemented in the Rust binary (Commands::Dlx -> vite_pm_cli), which this PR now covers. The JS package's own dlx execution (getPackageRunner/formatDlxCommand in packages/cli/src/create/command.ts) spawns the native PM (pnpm dlx/npx/...) directly and is used internally by create/migration, not by user vp dlx — and it already carries a TODO to route through vp dlx instead (vite-task#27).

So I'd prefer not to duplicate the marker into the JS launcher here; the clean fix is to unify that path onto vp dlx (the existing TODO), after which it inherits this automatically. If you'd rather I set VP_USER_AGENT in the JS spawn env now (sourced from VP_GLOBAL_VERSION) as an interim, I can add that — let me know your preference.

}

tokio::runtime::Runtime::new().expect("failed to build tokio runtime").block_on(run())
}

async fn run() -> ExitCode {
// Initialize tracing
vite_shared::init_tracing();

Expand All @@ -317,6 +338,11 @@ async fn main() -> ExitCode {
if let Some(tool) = shim::detect_shim_tool(argv0) {
// Shim mode - dispatch to the appropriate tool. stdout belongs to the
// wrapped tool; route vp's own output to stderr.
//
// The user is invoking the wrapped tool (e.g. `npm`/`npx`), not vp, so
// don't advertise vp to it or its children. Clear the marker set in
// `main` before dispatching. SAFETY: see the `set_var` in `main`.
unsafe { std::env::remove_var(vite_shared::env_vars::VP_USER_AGENT) };
output::route_user_output_to_stderr();
let exit_code = shim::dispatch(&tool, &args[1..]).await;
return ExitCode::from(exit_code as u8);
Expand Down
7 changes: 7 additions & 0 deletions crates/vite_shared/src/env_vars.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,13 @@ pub const VP_CLI_BIN: &str = "VP_CLI_BIN";
/// Global CLI version, passed from Rust binary to JS for --version display.
pub const VP_GLOBAL_VERSION: &str = "VP_GLOBAL_VERSION";

/// Advertises that the process tree is running under Vite+ (value: `vp/<version>`).
///
/// Set once at startup and inherited by every child process. Tools we invoke
/// (e.g. `vp dlx create-vite`) read it to detect vp as the package manager,
/// since the underlying package manager overwrites `npm_config_user_agent`.
pub const VP_USER_AGENT: &str = "VP_USER_AGENT";

// ── HTTP client TLS / CA configuration ──────────────────────────────────

/// Path to a PEM bundle of extra CA certificates to trust for HTTPS.
Expand Down
Loading