New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(npm): set up node_modules/.bin/ entries for package that provide bin entrypoints #23496
Merged
nathanwhit
merged 21 commits into
denoland:main
from
bartlomieju:generate_node_modules_bin_entries
May 23, 2024
Merged
Changes from all commits
Commits
Show all changes
21 commits
Select commit
Hold shift + click to select a range
e958340
wip
bartlomieju 633a078
it works on unix
bartlomieju f46ab0a
Merge branch 'main' into generate_node_modules_bin_entries
bartlomieju be289c1
bump eszip and deno_npm
bartlomieju 8e8fe75
Merge branch 'main' into generate_node_modules_bin_entries
bartlomieju 5a5b887
Merge branch 'main' into generate_node_modules_bin_entries
bartlomieju 727ff9f
fmt
bartlomieju 6e28847
reset CI
bartlomieju 7dc69cd
Create dir, set executable, fix link for inferred bin name
nathanwhit ad0f578
Add shebang
nathanwhit 2c58b39
Add basic test
nathanwhit 8fa9b1e
Use relative symlinks
nathanwhit 0670838
Appease clippy
nathanwhit 4958e17
Add windows support
nathanwhit d5d5530
Appease linter
nathanwhit f31dc9b
Factor out relative_path util
nathanwhit 9b2728f
Appease clippy
nathanwhit 1f685d9
Ignore dead code warning on windows
nathanwhit 05ae47c
Add test for already set up bin entries
nathanwhit d5531cc
Fmt
nathanwhit 123e428
Unix only
nathanwhit File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,109 @@ | ||
// Copyright 2018-2024 the Deno authors. All rights reserved. MIT license. | ||
|
||
use crate::npm::managed::NpmResolutionPackage; | ||
use deno_core::anyhow::Context; | ||
use deno_core::error::AnyError; | ||
use std::path::Path; | ||
|
||
pub(super) fn set_up_bin_entry( | ||
package: &NpmResolutionPackage, | ||
bin_name: &str, | ||
#[allow(unused_variables)] bin_script: &str, | ||
#[allow(unused_variables)] package_path: &Path, | ||
bin_node_modules_dir_path: &Path, | ||
) -> Result<(), AnyError> { | ||
#[cfg(windows)] | ||
{ | ||
set_up_bin_shim(package, bin_name, bin_node_modules_dir_path)?; | ||
} | ||
#[cfg(unix)] | ||
{ | ||
symlink_bin_entry( | ||
package, | ||
bin_name, | ||
bin_script, | ||
package_path, | ||
bin_node_modules_dir_path, | ||
)?; | ||
} | ||
Ok(()) | ||
} | ||
|
||
#[cfg(windows)] | ||
fn set_up_bin_shim( | ||
package: &NpmResolutionPackage, | ||
bin_name: &str, | ||
bin_node_modules_dir_path: &Path, | ||
) -> Result<(), AnyError> { | ||
use std::fs; | ||
let mut cmd_shim = bin_node_modules_dir_path.join(bin_name); | ||
|
||
cmd_shim.set_extension("cmd"); | ||
let shim = format!("@deno run -A npm:{}/{bin_name} %*", package.id.nv); | ||
if cmd_shim.exists() { | ||
if let Ok(contents) = fs::read_to_string(cmd_shim) { | ||
if contents == shim { | ||
// up to date | ||
return Ok(()); | ||
} | ||
} | ||
return Ok(()); | ||
} | ||
fs::write(&cmd_shim, shim).with_context(|| { | ||
format!("Can't set up '{}' bin at {}", bin_name, cmd_shim.display()) | ||
})?; | ||
|
||
Ok(()) | ||
} | ||
|
||
#[cfg(unix)] | ||
fn symlink_bin_entry( | ||
_package: &NpmResolutionPackage, | ||
bin_name: &str, | ||
bin_script: &str, | ||
package_path: &Path, | ||
bin_node_modules_dir_path: &Path, | ||
) -> Result<(), AnyError> { | ||
use std::os::unix::fs::symlink; | ||
let link = bin_node_modules_dir_path.join(bin_name); | ||
let original = package_path.join(bin_script); | ||
|
||
// Don't bother setting up another link if it already exists | ||
if link.exists() { | ||
let resolved = std::fs::read_link(&link).ok(); | ||
if let Some(resolved) = resolved { | ||
if resolved != original { | ||
log::warn!( | ||
"{} Trying to set up '{}' bin for \"{}\", but an entry pointing to \"{}\" already exists. Skipping...", | ||
deno_terminal::colors::yellow("Warning"), | ||
bin_name, | ||
resolved.display(), | ||
original.display() | ||
); | ||
} | ||
return Ok(()); | ||
} | ||
} | ||
|
||
use std::os::unix::fs::PermissionsExt; | ||
let mut perms = std::fs::metadata(&original).unwrap().permissions(); | ||
if perms.mode() & 0o111 == 0 { | ||
// if the original file is not executable, make it executable | ||
perms.set_mode(perms.mode() | 0o111); | ||
std::fs::set_permissions(&original, perms).with_context(|| { | ||
format!("Setting permissions on '{}'", original.display()) | ||
})?; | ||
} | ||
let original_relative = | ||
crate::util::path::relative_path(bin_node_modules_dir_path, &original) | ||
.unwrap_or(original); | ||
symlink(&original_relative, &link).with_context(|| { | ||
format!( | ||
"Can't set up '{}' bin at {}", | ||
bin_name, | ||
original_relative.display() | ||
) | ||
})?; | ||
|
||
Ok(()) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,5 @@ | ||
#!/usr/bin/env -S node | ||
|
||
import process from "node:process"; | ||
|
||
for (const arg of process.argv.slice(2)) { | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
{ | ||
"tests": { | ||
"sets_up_bin_dir": { | ||
"tempDir": true, | ||
"steps": [ | ||
// {"commandName": "npm", "args": "install", "output": "\nadded 1 package in [WILDCARD]\n"}, | ||
{ | ||
"args": "task sayhi", | ||
"output": "task.out" | ||
}, | ||
{ | ||
"if": "unix", | ||
"commandName": "./node_modules/.bin/cli-esm", | ||
"args": "hi hello", | ||
"output": "hi\nhello\n" | ||
}, | ||
{ | ||
"if": "windows", | ||
"commandName": "./node_modules/.bin/cli-esm.cmd", | ||
"args": "hi hello", | ||
"output": "hi\nhello\n" | ||
}, | ||
{ | ||
"commandName": "npm", | ||
"args": "run sayhi", | ||
"output": "npm-run.out" | ||
} | ||
] | ||
}, | ||
"warns_if_already_setup": { | ||
"tempDir": true, | ||
"steps": [{ | ||
"if": "unix", | ||
"commandName": "npm", | ||
"args": "install", | ||
"output": "\nadded 1 package in [WILDCARD]\n" | ||
}, { | ||
"if": "unix", | ||
"args": "task sayhi", | ||
"output": "already-set-up.out" | ||
}] | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
Download http://localhost:4260/@denotest/bin | ||
Download http://localhost:4260/@denotest/bin/1.0.0.tgz | ||
Initialize @denotest/bin@1.0.0 | ||
Warning Trying to set up [WILDCARD] bin for [WILDCARD], but an entry pointing to [WILDCARD] already exists. Skipping... | ||
Warning Trying to set up [WILDCARD] bin for [WILDCARD] but an entry pointing to [WILDCARD] already exists. Skipping... | ||
Warning Trying to set up [WILDCARD] bin for [WILDCARD], but an entry pointing to [WILDCARD] already exists. Skipping... | ||
Task sayhi cli-esm hi hello | ||
hi | ||
hello |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
{ | ||
"nodeModulesDir": true | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
|
||
> sayhi | ||
> cli-esm hi hello | ||
|
||
hi | ||
hello |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
{ | ||
"name": "bin_package", | ||
"devDependencies": { | ||
"@denotest/bin": "1.0.0" | ||
}, | ||
"scripts": { | ||
"sayhi": "cli-esm hi hello" | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
Download http://localhost:4260/@denotest/bin | ||
Download http://localhost:4260/@denotest/bin/1.0.0.tgz | ||
Initialize @denotest/bin@1.0.0 | ||
Task sayhi cli-esm hi hello | ||
hi | ||
hello |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add to the spec test a step that would cause this codepath to be hit on an already setup node_modules directory?