Skip to content

Commit

Permalink
fix: handle linkDir existence
Browse files Browse the repository at this point in the history
As nodeModulesDirForPackageInner is asynchronous and contains
several `await` calls, the file can be created after the first
check for existence.

The error thrown by `Deno.rename` is not an instance of
`Deno.errors.AlreadyExists`, but `move` does work as expected.
Tested on macOS (OS error 66) and linux (OS error 39)
  • Loading branch information
mxdvl committed Sep 25, 2023
1 parent e0941bd commit e9a8f77
Show file tree
Hide file tree
Showing 2 changed files with 6 additions and 9 deletions.
2 changes: 1 addition & 1 deletion deps.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ export {
resolve,
toFileUrl,
} from "https://deno.land/[email protected]/path/mod.ts";
export { copy } from "https://deno.land/[email protected]/fs/mod.ts";
export { copy, exists, move } from "https://deno.land/[email protected]/fs/mod.ts";
export { basename, extname } from "https://deno.land/[email protected]/path/mod.ts";
export * as JSONC from "https://deno.land/[email protected]/encoding/jsonc.ts";
export { encode as base32Encode } from "https://deno.land/[email protected]/encoding/base32.ts";
Expand Down
13 changes: 5 additions & 8 deletions src/loader_native.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,10 @@ import {
DenoDir,
dirname,
esbuild,
exists,
fromFileUrl,
join,
move,
} from "../deps.ts";
import * as deno from "./deno.ts";
import {
Expand Down Expand Up @@ -120,21 +122,16 @@ export class NativeLoader implements Loader {

// check if the package is already linked, if so, return the link and skip
// a bunch of work
try {
await Deno.stat(linkDir);
this.#linkDirCache.set(npmPackageId, linkDir);
return linkDir;
} catch {
// directory does not yet exist
}
if (await exists(linkDir)) return linkDir;

// create a temporary directory, recursively hardlink the package contents
// into it, and then rename it to the final location
const tmpDir = await Deno.makeTempDir();

await linkRecursive(packageDir, tmpDir);
try {
await Deno.mkdir(linkDirParent, { recursive: true });
await Deno.rename(tmpDir, linkDir);
await move(tmpDir, linkDir);
} catch (err) {
if (err instanceof Deno.errors.AlreadyExists) {
// ignore
Expand Down

0 comments on commit e9a8f77

Please sign in to comment.