1
+ use crate :: utils;
1
2
use serde:: { Deserialize , Serialize } ;
2
3
use std:: {
3
4
collections:: { hash_map:: Entry , HashMap } ,
@@ -172,13 +173,15 @@ impl Remapping {
172
173
173
174
let dir = dir. as_ref ( ) ;
174
175
let is_inside_node_modules = dir. ends_with ( "node_modules" ) ;
176
+
175
177
// iterate over all dirs that are children of the root
176
178
for dir in walkdir:: WalkDir :: new ( dir)
177
179
. follow_links ( true )
178
180
. min_depth ( 1 )
179
181
. max_depth ( 1 )
180
182
. into_iter ( )
181
- . filter_map ( std:: result:: Result :: ok)
183
+ . filter_entry ( |e| !is_hidden ( e) )
184
+ . filter_map ( Result :: ok)
182
185
. filter ( |e| e. file_type ( ) . is_dir ( ) )
183
186
{
184
187
let depth1_dir = dir. path ( ) ;
@@ -487,6 +490,11 @@ fn is_lib_dir(dir: &Path) -> bool {
487
490
. unwrap_or_default ( )
488
491
}
489
492
493
+ /// Returns true if the file is _hidden_
494
+ fn is_hidden ( entry : & walkdir:: DirEntry ) -> bool {
495
+ entry. file_name ( ) . to_str ( ) . map ( |s| s. starts_with ( '.' ) ) . unwrap_or ( false )
496
+ }
497
+
490
498
/// Finds all remappings in the directory recursively
491
499
fn find_remapping_candidates (
492
500
current_dir : & Path ,
@@ -506,8 +514,8 @@ fn find_remapping_candidates(
506
514
. min_depth ( 1 )
507
515
. max_depth ( 1 )
508
516
. into_iter ( )
509
- . filter_map ( std :: result :: Result :: ok )
510
- . filter ( |entry| !entry . file_name ( ) . to_str ( ) . map ( |s| s . starts_with ( '.' ) ) . unwrap_or ( false ) )
517
+ . filter_entry ( |e| ! is_hidden ( e ) )
518
+ . filter_map ( Result :: ok )
511
519
{
512
520
let entry: walkdir:: DirEntry = entry;
513
521
@@ -518,6 +526,26 @@ fn find_remapping_candidates(
518
526
{
519
527
is_candidate = true ;
520
528
} else if entry. file_type ( ) . is_dir ( ) {
529
+ // if the dir is a symlink to a parent dir we short circuit here
530
+ // `walkdir` will catch symlink loops, but this check prevents that we end up scanning a
531
+ // workspace like
532
+ // ```text
533
+ // my-package/node_modules
534
+ // ├── dep/node_modules
535
+ // ├── symlink to `my-package`
536
+ // ```
537
+ if entry. path_is_symlink ( ) {
538
+ if let Ok ( target) = utils:: canonicalize ( entry. path ( ) ) {
539
+ // the symlink points to a parent dir of the current window
540
+ if open. components ( ) . count ( ) > target. components ( ) . count ( ) &&
541
+ utils:: common_ancestor ( open, & target) . is_some ( )
542
+ {
543
+ // short-circuiting
544
+ return Vec :: new ( )
545
+ }
546
+ }
547
+ }
548
+
521
549
let subdir = entry. path ( ) ;
522
550
// we skip commonly used subdirs that should not be searched for recursively
523
551
if !( subdir. ends_with ( "tests" ) || subdir. ends_with ( "test" ) || subdir. ends_with ( "demo" ) )
0 commit comments