Add --follow-symlinks flag to glob command (fixes #15559) (#15626)

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:
Sebastian Nallar
2025-04-23 12:47:48 -03:00
committed by GitHub
parent 717081bd2f
commit cb57f0a539
2 changed files with 50 additions and 2 deletions

View File

@ -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()