mirror of
https://github.com/nushell/nushell.git
synced 2025-04-29 15:44:28 +02:00
Fixes #15559 # Description The glob command wasn't working correctly with symlinks in the /sys filesystem. This commit adds a new flag that allows users to explicitly control whether symlinks should be followed, with special handling for the /sys directory. The issue was that the glob command didn't follow symbolic links when traversing the /sys filesystem, resulting in an empty list even though paths should be found. This implementation adds a new `--follow-symlinks` flag that explicitly enables following symlinks. By default, it now follows symlinks in most paths but has special handling for /sys paths where the flag is required. Example: ` # Before: This would return an empty list on Linux systems glob /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor # Now: This works as expected with the new flag glob /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor --follow-symlinks ` # User-Facing Changes 1. Added the --follow-symlinks (-l) flag to the glob command that allows users to explicitly control whether symbolic links should be followed 2. Added a new example to the glob command help text demonstrating the use of this flag # Tests + Formatting 1. Added a test for the new --follow-symlinks flag
This commit is contained in:
parent
717081bd2f
commit
cb57f0a539
@ -35,6 +35,11 @@ impl Command for Glob {
|
||||
"Whether to filter out symlinks from the returned paths",
|
||||
Some('S'),
|
||||
)
|
||||
.switch(
|
||||
"follow-symlinks",
|
||||
"Whether to follow symbolic links to their targets",
|
||||
Some('l'),
|
||||
)
|
||||
.named(
|
||||
"exclude",
|
||||
SyntaxShape::List(Box::new(SyntaxShape::String)),
|
||||
@ -111,6 +116,11 @@ impl Command for Glob {
|
||||
example: r#"glob **/* --exclude [**/target/** **/.git/** */]"#,
|
||||
result: None,
|
||||
},
|
||||
Example {
|
||||
description: "Search for files following symbolic links to their targets",
|
||||
example: r#"glob "**/*.txt" --follow-symlinks"#,
|
||||
result: None,
|
||||
},
|
||||
]
|
||||
}
|
||||
|
||||
@ -132,6 +142,7 @@ impl Command for Glob {
|
||||
let no_dirs = call.has_flag(engine_state, stack, "no-dir")?;
|
||||
let no_files = call.has_flag(engine_state, stack, "no-file")?;
|
||||
let no_symlinks = call.has_flag(engine_state, stack, "no-symlink")?;
|
||||
let follow_symlinks = call.has_flag(engine_state, stack, "follow-symlinks")?;
|
||||
let paths_to_exclude: Option<Value> = call.get_flag(engine_state, stack, "exclude")?;
|
||||
|
||||
let (not_patterns, not_pattern_span): (Vec<String>, Span) = match paths_to_exclude {
|
||||
@ -213,6 +224,11 @@ impl Command for Glob {
|
||||
}
|
||||
};
|
||||
|
||||
let link_behavior = match follow_symlinks {
|
||||
true => wax::LinkBehavior::ReadTarget,
|
||||
false => wax::LinkBehavior::ReadFile,
|
||||
};
|
||||
|
||||
let result = if !not_patterns.is_empty() {
|
||||
let np: Vec<&str> = not_patterns.iter().map(|s| s as &str).collect();
|
||||
let glob_results = glob
|
||||
@ -220,7 +236,7 @@ impl Command for Glob {
|
||||
path,
|
||||
WalkBehavior {
|
||||
depth: folder_depth,
|
||||
..Default::default()
|
||||
link: link_behavior,
|
||||
},
|
||||
)
|
||||
.into_owned()
|
||||
@ -247,7 +263,7 @@ impl Command for Glob {
|
||||
path,
|
||||
WalkBehavior {
|
||||
depth: folder_depth,
|
||||
..Default::default()
|
||||
link: link_behavior,
|
||||
},
|
||||
)
|
||||
.into_owned()
|
||||
|
@ -173,3 +173,35 @@ fn glob_files_in_parent(
|
||||
assert_eq!(actual.out, expected, "\n test: {}", tag);
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn glob_follow_symlinks() {
|
||||
Playground::setup("glob_follow_symlinks", |dirs, sandbox| {
|
||||
// Create a directory with some files
|
||||
sandbox.mkdir("target_dir");
|
||||
sandbox
|
||||
.within("target_dir")
|
||||
.with_files(&[EmptyFile("target_file.txt")]);
|
||||
|
||||
let target_dir = dirs.test().join("target_dir");
|
||||
let symlink_path = dirs.test().join("symlink_dir");
|
||||
#[cfg(unix)]
|
||||
std::os::unix::fs::symlink(target_dir, &symlink_path).expect("Failed to create symlink");
|
||||
#[cfg(windows)]
|
||||
std::os::windows::fs::symlink_dir(target_dir, &symlink_path)
|
||||
.expect("Failed to create symlink");
|
||||
|
||||
// on some systems/filesystems, symlinks are followed by default
|
||||
// on others (like Linux /sys), they aren't
|
||||
// Test that with the --follow-symlinks flag, files are found for sure
|
||||
let with_flag = nu!(
|
||||
cwd: dirs.test(),
|
||||
"glob 'symlink_dir/*.txt' --follow-symlinks | length",
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
with_flag.out, "1",
|
||||
"Should find file with --follow-symlinks flag"
|
||||
);
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user