From 6d6bcb3205287c3f9d7d67c3327b8a4ce6ccec06 Mon Sep 17 00:00:00 2001 From: MrKleeblatt Date: Sat, 24 Jun 2023 17:26:37 +0200 Subject: [PATCH 1/3] feat(std/fs.walk): include symlink option Instead of completely ignoring symlinks if `followSymlinks == false` there should be an option to at least return the symlink (and don't resolve the real path) --- fs/walk.ts | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/fs/walk.ts b/fs/walk.ts index fc7c746e0061..31c6fb5ab632 100644 --- a/fs/walk.ts +++ b/fs/walk.ts @@ -55,6 +55,8 @@ export interface WalkOptions { includeFiles?: boolean; /** @default {true} */ includeDirs?: boolean; + /** @default {true} */ + includeSymlinks?: boolean; /** @default {false} */ followSymlinks?: boolean; exts?: string[]; @@ -84,6 +86,7 @@ export async function* walk( maxDepth = Infinity, includeFiles = true, includeDirs = true, + includeSymlinks = true, followSymlinks = false, exts = undefined, match = undefined, @@ -108,7 +111,12 @@ export async function* walk( let { isSymlink, isDirectory } = entry; if (isSymlink) { - if (!followSymlinks) continue; + if (!followSymlinks) { + if (includeSymlinks && include(path, exts, match, skip)) { + yield { path, ...entry }; + } + continue; + } path = await Deno.realPath(path); // Caveat emptor: don't assume |path| is not a symlink. realpath() // resolves symlinks but another process can replace the file system @@ -121,6 +129,7 @@ export async function* walk( maxDepth: maxDepth - 1, includeFiles, includeDirs, + includeSymlinks, followSymlinks, exts, match, @@ -142,6 +151,7 @@ export function* walkSync( maxDepth = Infinity, includeFiles = true, includeDirs = true, + includeSymlinks = true, followSymlinks = false, exts = undefined, match = undefined, @@ -171,7 +181,12 @@ export function* walkSync( let { isSymlink, isDirectory } = entry; if (isSymlink) { - if (!followSymlinks) continue; + if (!followSymlinks) { + if (includeSymlinks && include(path, exts, match, skip)) { + yield { path, ...entry }; + } + continue; + } path = Deno.realPathSync(path); // Caveat emptor: don't assume |path| is not a symlink. realpath() // resolves symlinks but another process can replace the file system @@ -184,6 +199,7 @@ export function* walkSync( maxDepth: maxDepth - 1, includeFiles, includeDirs, + includeSymlinks, followSymlinks, exts, match, From df4f4f8df6fef8e067e513ae641215e6d4ac204c Mon Sep 17 00:00:00 2001 From: Yoshiya Hinosawa Date: Thu, 27 Jul 2023 21:56:29 +0900 Subject: [PATCH 2/3] test: add test case, fix expandGlob test cases --- fs/expand_glob_test.ts | 3 +++ fs/testdata/walk/broken_symlink/a | 1 + fs/testdata/walk/broken_symlink/broken_link | 1 + fs/walk_test.ts | 6 ++++++ 4 files changed, 11 insertions(+) create mode 100644 fs/testdata/walk/broken_symlink/a create mode 120000 fs/testdata/walk/broken_symlink/broken_link diff --git a/fs/expand_glob_test.ts b/fs/expand_glob_test.ts index 61d1993fd6e8..4a2970ffcb44 100644 --- a/fs/expand_glob_test.ts +++ b/fs/expand_glob_test.ts @@ -51,6 +51,7 @@ Deno.test("expandGlobWildcard", async function () { "abc", "abcdef", "abcdefghi", + "link", "subdir", ]); }); @@ -70,6 +71,7 @@ Deno.test("expandGlobParent", async function () { "abc", "abcdef", "abcdefghi", + "link", "subdir", ]); }); @@ -118,6 +120,7 @@ Deno.test("expandGlobGlobstarFalseWithGlob", async function () { "abc", "abcdef", "abcdefghi", + "link", "subdir", ]); }); diff --git a/fs/testdata/walk/broken_symlink/a b/fs/testdata/walk/broken_symlink/a new file mode 100644 index 000000000000..78981922613b --- /dev/null +++ b/fs/testdata/walk/broken_symlink/a @@ -0,0 +1 @@ +a diff --git a/fs/testdata/walk/broken_symlink/broken_link b/fs/testdata/walk/broken_symlink/broken_link new file mode 120000 index 000000000000..c86c3f3551ec --- /dev/null +++ b/fs/testdata/walk/broken_symlink/broken_link @@ -0,0 +1 @@ +none \ No newline at end of file diff --git a/fs/walk_test.ts b/fs/walk_test.ts index a37b5e190afc..a82768cad20c 100644 --- a/fs/walk_test.ts +++ b/fs/walk_test.ts @@ -78,6 +78,12 @@ Deno.test("[fs/walk] symlink", async () => followSymlinks: true, })); +Deno.test("[fs/walk] symlink without followSymlink", async () => { + await assertWalkPaths("symlink", [".", "x", "y"], { + followSymlinks: false, + }); +}); + Deno.test("[fs/walk] non-existent root", async () => { const root = resolve(testdataDir, "non_existent"); await assertRejects( From f32dc1267a954fd32ababeb485c261d1031536f7 Mon Sep 17 00:00:00 2001 From: Yoshiya Hinosawa Date: Thu, 27 Jul 2023 21:58:58 +0900 Subject: [PATCH 3/3] chore: remove irrelevant files --- fs/testdata/walk/broken_symlink/a | 1 - fs/testdata/walk/broken_symlink/broken_link | 1 - 2 files changed, 2 deletions(-) delete mode 100644 fs/testdata/walk/broken_symlink/a delete mode 120000 fs/testdata/walk/broken_symlink/broken_link diff --git a/fs/testdata/walk/broken_symlink/a b/fs/testdata/walk/broken_symlink/a deleted file mode 100644 index 78981922613b..000000000000 --- a/fs/testdata/walk/broken_symlink/a +++ /dev/null @@ -1 +0,0 @@ -a diff --git a/fs/testdata/walk/broken_symlink/broken_link b/fs/testdata/walk/broken_symlink/broken_link deleted file mode 120000 index c86c3f3551ec..000000000000 --- a/fs/testdata/walk/broken_symlink/broken_link +++ /dev/null @@ -1 +0,0 @@ -none \ No newline at end of file