Skip to content

Commit

Permalink
fix(install): Use relative symlinks in deno install (#25164)
Browse files Browse the repository at this point in the history
Fixes #25161
  • Loading branch information
nathanwhit authored Aug 22, 2024
1 parent b6475d0 commit f606402
Show file tree
Hide file tree
Showing 5 changed files with 70 additions and 25 deletions.
56 changes: 32 additions & 24 deletions cli/npm/managed/resolvers/local.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1048,42 +1048,50 @@ fn symlink_package_dir(
// need to delete the previous symlink before creating a new one
let _ignore = fs::remove_dir_all(new_path);

let old_path_relative =
crate::util::path::relative_path(new_parent, old_path)
.unwrap_or_else(|| old_path.to_path_buf());

#[cfg(windows)]
return junction_or_symlink_dir(old_path, new_path);
{
junction_or_symlink_dir(&old_path_relative, old_path, new_path)
}
#[cfg(not(windows))]
symlink_dir(old_path, new_path)
{
symlink_dir(&old_path_relative, new_path).map_err(Into::into)
}
}

#[cfg(windows)]
fn junction_or_symlink_dir(
old_path_relative: &Path,
old_path: &Path,
new_path: &Path,
) -> Result<(), AnyError> {
use deno_core::anyhow::bail;
// Use junctions because they're supported on ntfs file systems without
// needing to elevate privileges on Windows
static USE_JUNCTIONS: std::sync::atomic::AtomicBool =
std::sync::atomic::AtomicBool::new(false);

if USE_JUNCTIONS.load(std::sync::atomic::Ordering::Relaxed) {
// Use junctions because they're supported on ntfs file systems without
// needing to elevate privileges on Windows.
// Note: junctions don't support relative paths, so we need to use the
// absolute path here.
return junction::create(old_path, new_path)
.context("Failed creating junction in node_modules folder");
}

match junction::create(old_path, new_path) {
match symlink_dir(old_path_relative, new_path) {
Ok(()) => Ok(()),
Err(junction_err) => {
if cfg!(debug_assertions) {
// When running the tests, junctions should be created, but if not then
// surface this error.
log::warn!("Error creating junction. {:#}", junction_err);
}

match symlink_dir(old_path, new_path) {
Ok(()) => Ok(()),
Err(symlink_err) => bail!(
concat!(
"Failed creating junction and fallback symlink in node_modules folder.\n\n",
"{:#}\n\n{:#}",
),
junction_err,
symlink_err,
),
}
Err(symlink_err)
if symlink_err.kind() == std::io::ErrorKind::PermissionDenied =>
{
USE_JUNCTIONS.store(true, std::sync::atomic::Ordering::Relaxed);
junction::create(old_path, new_path).map_err(Into::into)
}
Err(symlink_err) => Err(
AnyError::from(symlink_err)
.context("Failed creating symlink in node_modules folder"),
),
}
}

Expand Down
2 changes: 1 addition & 1 deletion cli/util/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,7 @@ pub fn hard_link_dir_recursive(from: &Path, to: &Path) -> Result<(), AnyError> {
Ok(())
}

pub fn symlink_dir(oldpath: &Path, newpath: &Path) -> Result<(), AnyError> {
pub fn symlink_dir(oldpath: &Path, newpath: &Path) -> Result<(), Error> {
let err_mapper = |err: Error| {
Error::new(
err.kind(),
Expand Down
28 changes: 28 additions & 0 deletions tests/specs/install/move_after_install/__test__.jsonc
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"tempDir": true,
"envs": {
"DENO_FUTURE": "1"
},
"steps": [
{
"cwd": "./test-project",
"args": "install",
"output": "[WILDCARD]"
},
{
"cwd": "./test-project",
"args": "run -A main.mjs",
"output": "5\n"
},
{
"commandName": "mv",
"args": "test-project test-project-moved",
"output": ""
},
{
"cwd": "./test-project-moved",
"args": "run -A main.mjs",
"output": "5\n"
}
]
}
4 changes: 4 additions & 0 deletions tests/specs/install/move_after_install/test-project/main.mjs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import { getValue, setValue } from "@denotest/esm-basic";

setValue(5);
console.log(getValue());
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"dependencies": {
"@denotest/esm-basic": "*"
}
}

0 comments on commit f606402

Please sign in to comment.