Skip to content

Commit f606402

Browse files
authored
fix(install): Use relative symlinks in deno install (#25164)
Fixes #25161
1 parent b6475d0 commit f606402

File tree

5 files changed

+70
-25
lines changed

5 files changed

+70
-25
lines changed

cli/npm/managed/resolvers/local.rs

Lines changed: 32 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1048,42 +1048,50 @@ fn symlink_package_dir(
10481048
// need to delete the previous symlink before creating a new one
10491049
let _ignore = fs::remove_dir_all(new_path);
10501050

1051+
let old_path_relative =
1052+
crate::util::path::relative_path(new_parent, old_path)
1053+
.unwrap_or_else(|| old_path.to_path_buf());
1054+
10511055
#[cfg(windows)]
1052-
return junction_or_symlink_dir(old_path, new_path);
1056+
{
1057+
junction_or_symlink_dir(&old_path_relative, old_path, new_path)
1058+
}
10531059
#[cfg(not(windows))]
1054-
symlink_dir(old_path, new_path)
1060+
{
1061+
symlink_dir(&old_path_relative, new_path).map_err(Into::into)
1062+
}
10551063
}
10561064

10571065
#[cfg(windows)]
10581066
fn junction_or_symlink_dir(
1067+
old_path_relative: &Path,
10591068
old_path: &Path,
10601069
new_path: &Path,
10611070
) -> Result<(), AnyError> {
1062-
use deno_core::anyhow::bail;
1063-
// Use junctions because they're supported on ntfs file systems without
1064-
// needing to elevate privileges on Windows
1071+
static USE_JUNCTIONS: std::sync::atomic::AtomicBool =
1072+
std::sync::atomic::AtomicBool::new(false);
1073+
1074+
if USE_JUNCTIONS.load(std::sync::atomic::Ordering::Relaxed) {
1075+
// Use junctions because they're supported on ntfs file systems without
1076+
// needing to elevate privileges on Windows.
1077+
// Note: junctions don't support relative paths, so we need to use the
1078+
// absolute path here.
1079+
return junction::create(old_path, new_path)
1080+
.context("Failed creating junction in node_modules folder");
1081+
}
10651082

1066-
match junction::create(old_path, new_path) {
1083+
match symlink_dir(old_path_relative, new_path) {
10671084
Ok(()) => Ok(()),
1068-
Err(junction_err) => {
1069-
if cfg!(debug_assertions) {
1070-
// When running the tests, junctions should be created, but if not then
1071-
// surface this error.
1072-
log::warn!("Error creating junction. {:#}", junction_err);
1073-
}
1074-
1075-
match symlink_dir(old_path, new_path) {
1076-
Ok(()) => Ok(()),
1077-
Err(symlink_err) => bail!(
1078-
concat!(
1079-
"Failed creating junction and fallback symlink in node_modules folder.\n\n",
1080-
"{:#}\n\n{:#}",
1081-
),
1082-
junction_err,
1083-
symlink_err,
1084-
),
1085-
}
1085+
Err(symlink_err)
1086+
if symlink_err.kind() == std::io::ErrorKind::PermissionDenied =>
1087+
{
1088+
USE_JUNCTIONS.store(true, std::sync::atomic::Ordering::Relaxed);
1089+
junction::create(old_path, new_path).map_err(Into::into)
10861090
}
1091+
Err(symlink_err) => Err(
1092+
AnyError::from(symlink_err)
1093+
.context("Failed creating symlink in node_modules folder"),
1094+
),
10871095
}
10881096
}
10891097

cli/util/fs.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -509,7 +509,7 @@ pub fn hard_link_dir_recursive(from: &Path, to: &Path) -> Result<(), AnyError> {
509509
Ok(())
510510
}
511511

512-
pub fn symlink_dir(oldpath: &Path, newpath: &Path) -> Result<(), AnyError> {
512+
pub fn symlink_dir(oldpath: &Path, newpath: &Path) -> Result<(), Error> {
513513
let err_mapper = |err: Error| {
514514
Error::new(
515515
err.kind(),
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"tempDir": true,
3+
"envs": {
4+
"DENO_FUTURE": "1"
5+
},
6+
"steps": [
7+
{
8+
"cwd": "./test-project",
9+
"args": "install",
10+
"output": "[WILDCARD]"
11+
},
12+
{
13+
"cwd": "./test-project",
14+
"args": "run -A main.mjs",
15+
"output": "5\n"
16+
},
17+
{
18+
"commandName": "mv",
19+
"args": "test-project test-project-moved",
20+
"output": ""
21+
},
22+
{
23+
"cwd": "./test-project-moved",
24+
"args": "run -A main.mjs",
25+
"output": "5\n"
26+
}
27+
]
28+
}
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
import { getValue, setValue } from "@denotest/esm-basic";
2+
3+
setValue(5);
4+
console.log(getValue());
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"dependencies": {
3+
"@denotest/esm-basic": "*"
4+
}
5+
}

0 commit comments

Comments
 (0)