Skip to content

Commit

Permalink
fix(cli): set npm_config_user_agent when running npm packages or ta…
Browse files Browse the repository at this point in the history
…sks (#26639)

Fixes #25342.

Still not sure on the exact user agent to set (should it include
`node`?).

After this PR, here's the state of running some `create-*` packages
(just ones I could think of off the top of my head):

| package                  | prints/runs/suggests deno install | notes |
| ---------------- | ------------- | ------ |
| `create-next-app` | ❌ | falls back to npm, needs a PR
([code](https://github.com/vercel/next.js/blob/c32e2802097c03fd9f95b1dae228d6e0257569c0/packages/create-next-app/helpers/get-pkg-manager.ts#L3))
| `sv create` | ❌ | uses `package-manager-detector`, needs a PR
([code](https://github.com/antfu-collective/package-manager-detector/tree/main))
| `create-qwik` | ✅ | runs `deno install` but suggests `deno start`
which doesn't work (should be `deno task start` or `deno run start`)
| `create-astro` | ✅ | runs `deno install` but suggests `npm run dev`
later in output, probably needs a PR
| `nuxi init` | ❌ | deno not an option in dialog, needs a PR
([code](https://github.com/nuxt/cli/blob/f04e2e894446f597da9d971b7eb03191d5a0da7e/src/commands/init.ts#L96-L102))
| `create-react-app` | ❌ | uses npm
| `ng new` (`@angular/cli`) | ❌ | uses npm
| `create-vite` | ✅ | suggests working deno commands 🎉 
| `create-solid` |  ❌ | suggests npm commands, needs PR

It's possible that fixing `package-manager-detector` or other packages
might make some of these just work, but haven't looked too carefully at
each
  • Loading branch information
nathanwhit authored Nov 1, 2024
1 parent 6c6bbeb commit 04ae1a5
Show file tree
Hide file tree
Showing 13 changed files with 123 additions and 1 deletion.
12 changes: 12 additions & 0 deletions cli/npm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -189,3 +189,15 @@ impl NpmFetchResolver {
info
}
}

pub const NPM_CONFIG_USER_AGENT_ENV_VAR: &str = "npm_config_user_agent";

pub fn get_npm_config_user_agent() -> String {
format!(
"deno/{} npm/? deno/{} {} {}",
env!("CARGO_PKG_VERSION"),
env!("CARGO_PKG_VERSION"),
std::env::consts::OS,
std::env::consts::ARCH
)
}
10 changes: 9 additions & 1 deletion cli/task_runner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,12 @@ fn prepare_env_vars(
initial_cwd.to_string_lossy().to_string(),
);
}
if !env_vars.contains_key(crate::npm::NPM_CONFIG_USER_AGENT_ENV_VAR) {
env_vars.insert(
crate::npm::NPM_CONFIG_USER_AGENT_ENV_VAR.into(),
crate::npm::get_npm_config_user_agent(),
);
}
if let Some(node_modules_dir) = node_modules_dir {
prepend_to_path(
&mut env_vars,
Expand Down Expand Up @@ -204,7 +210,7 @@ impl ShellCommand for NpmCommand {
mut context: ShellCommandContext,
) -> LocalBoxFuture<'static, ExecuteResult> {
if context.args.first().map(|s| s.as_str()) == Some("run")
&& context.args.len() > 2
&& context.args.len() >= 2
// for now, don't run any npm scripts that have a flag because
// we don't handle stuff like `--workspaces` properly
&& !context.args.iter().any(|s| s.starts_with('-'))
Expand Down Expand Up @@ -267,10 +273,12 @@ impl ShellCommand for NodeCommand {
)
.execute(context);
}

args.extend(["run", "-A"].into_iter().map(|s| s.to_string()));
args.extend(context.args.iter().cloned());

let mut state = context.state;

state.apply_env_var(USE_PKG_JSON_HIDDEN_ENV_VAR_NAME, "1");
ExecutableCommand::new("deno".to_string(), std::env::current_exe().unwrap())
.execute(ShellCommandContext {
Expand Down
18 changes: 18 additions & 0 deletions cli/tools/run/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,16 @@ To grant permissions, set them before the script argument. For example:
}
}

fn set_npm_user_agent() {
static ONCE: std::sync::Once = std::sync::Once::new();
ONCE.call_once(|| {
std::env::set_var(
crate::npm::NPM_CONFIG_USER_AGENT_ENV_VAR,
crate::npm::get_npm_config_user_agent(),
);
});
}

pub async fn run_script(
mode: WorkerExecutionMode,
flags: Arc<Flags>,
Expand Down Expand Up @@ -58,6 +68,10 @@ pub async fn run_script(

let main_module = cli_options.resolve_main_module()?;

if main_module.scheme() == "npm" {
set_npm_user_agent();
}

maybe_npm_install(&factory).await?;

let worker_factory = factory.create_cli_main_worker_factory().await?;
Expand Down Expand Up @@ -119,6 +133,10 @@ async fn run_with_watch(
let cli_options = factory.cli_options()?;
let main_module = cli_options.resolve_main_module()?;

if main_module.scheme() == "npm" {
set_npm_user_agent();
}

maybe_npm_install(&factory).await?;

let _ = watcher_communicator.watch_paths(cli_options.watch_paths());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
#!/usr/bin/env node
console.log(`npm_config_user_agent: ${process.env["npm_config_user_agent"]}`);
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"name": "@denotest/print-npm-user-agent",
"version": "1.0.0",
"bin": {
"print-npm-user-agent": "index.js"
},
"scripts": {
"postinstall": "echo postinstall && node index.js && exit 1"
}
}
46 changes: 46 additions & 0 deletions tests/specs/npm/user_agent_env_var/__test__.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
{
"tempDir": true,
"tests": {
"set_for_npm_package": {
"steps": [
{
"args": "install",
"output": "[WILDCARD]"
},
{
"args": "run -A npm:@denotest/print-npm-user-agent",
"output": "run.out"
}
]
},
"unset_for_local_file": {
"steps": [
{
"args": "run -A main.ts",
"output": "Download [WILDCARD]\nnpm_config_user_agent: undefined\n"
}
]
},
"set_for_tasks": {
"steps": [
{
"args": "install",
"output": "[WILDCARD]"
},
{
"args": "task run-via-bin",
"output": "bin_command.out"
}
]
},
"set_for_lifecycle_scripts": {
"steps": [
{
"args": "install --allow-scripts",
"output": "postinstall.out",
"exitCode": 1
}
]
}
}
}
2 changes: 2 additions & 0 deletions tests/specs/npm/user_agent_env_var/bin_command.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Task run-via-bin print-npm-user-agent
npm_config_user_agent: deno/[WILDCARD] npm/? deno/[WILDCARD] [WILDCARD] [WILDCARD]
3 changes: 3 additions & 0 deletions tests/specs/npm/user_agent_env_var/deno.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
{
"nodeModulesDir": "auto"
}
1 change: 1 addition & 0 deletions tests/specs/npm/user_agent_env_var/main.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log(`npm_config_user_agent: ${Deno.env.get("npm_config_user_agent")}`);
8 changes: 8 additions & 0 deletions tests/specs/npm/user_agent_env_var/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
{
"scripts": {
"run-via-bin": "print-npm-user-agent"
},
"dependencies": {
"@denotest/print-npm-user-agent": "1.0.0"
}
}
10 changes: 10 additions & 0 deletions tests/specs/npm/user_agent_env_var/postinstall.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Download http://localhost:4260/@denotest%2fprint-npm-user-agent
Download http://localhost:4260/@denotest/print-npm-user-agent/1.0.0.tgz
Initialize @denotest/[email protected]
Initialize @denotest/[email protected]: running 'postinstall' script
error: script 'postinstall' in '@denotest/[email protected]' failed with exit code 1
stdout:
postinstall
npm_config_user_agent: deno/[WILDCARD] npm/? deno/[WILDCARD] [WILDCARD] [WILDCARD]

error: failed to run scripts for packages: @denotest/[email protected]
1 change: 1 addition & 0 deletions tests/specs/npm/user_agent_env_var/run.out
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
npm_config_user_agent: deno/[WILDCARD] npm/? deno/[WILDCARD] [WILDCARD] [WILDCARD]
1 change: 1 addition & 0 deletions tests/specs/npm/user_agent_env_var/test.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
console.log(process.env.npm_config_user_agent);

0 comments on commit 04ae1a5

Please sign in to comment.