-
Notifications
You must be signed in to change notification settings - Fork 7.7k
Adding support for native command globbing on UNIX #3643
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
2 commits
Select commit
Hold shift + click to select a range
File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
59 changes: 59 additions & 0 deletions
59
test/powershell/Language/Scripting/NativeExecution/NativeUnixGlobbing.Tests.ps1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
|
||
Describe 'Native UNIX globbing tests' -tags "CI" { | ||
|
||
BeforeAll { | ||
if (-not $IsWindows ) | ||
{ | ||
"" > "$TESTDRIVE/abc.txt" | ||
"" > "$TESTDRIVE/bbb.txt" | ||
"" > "$TESTDRIVE/cbb.txt" | ||
} | ||
|
||
$defaultParamValues = $PSDefaultParameterValues.Clone() | ||
$PSDefaultParameterValues["it:skip"] = $IsWindows | ||
} | ||
|
||
AfterAll { | ||
$global:PSDefaultParameterValues = $defaultParamValues | ||
} | ||
|
||
# Test * expansion | ||
It 'The globbing pattern *.txt should match 3 files' { | ||
(/bin/ls $TESTDRIVE/*.txt).Length | Should Be 3 | ||
} | ||
It 'The globbing pattern *b.txt should match 2 files whose basenames end in "b"' { | ||
(/bin/ls $TESTDRIVE/*b.txt).Length | Should Be 2 | ||
} | ||
# Test character classes | ||
It 'The globbing pattern should match 2 files whose names start with either "a" or "b"' { | ||
(/bin/ls $TESTDRIVE/[ab]*.txt).Length | Should Be 2 | ||
} | ||
It 'Globbing abc.* should return one file name "abc.txt"' { | ||
/bin/ls $TESTDRIVE/abc.* | Should Match "abc.txt" | ||
} | ||
# Test that ? matches any single character | ||
It 'Globbing [cde]b?.* should return one file name "cbb.txt"' { | ||
/bin/ls $TESTDRIVE/[cde]b?.* | Should Match "cbb.txt" | ||
} | ||
It 'Should return the original pattern if there are no matches' { | ||
/bin/echo $TESTDRIVE/*.nosuchfile | Should Match "\*\.nosuchfile$" | ||
} | ||
# Test the behavior in non-filesystem drives | ||
It 'Should not expand patterns on non-filesystem drives' { | ||
/bin/echo env:ps* | Should BeExactly "env:ps*" | ||
} | ||
# Test the behavior for files with spaces in the names | ||
It 'Globbing filenames with spaces should match 2 files' { | ||
"" > "$TESTDRIVE/foo bar.txt" | ||
"" > "$TESTDRIVE/foo baz.txt" | ||
(/bin/ls $TESTDRIVE/foo*.txt).Length | Should Be 2 | ||
} | ||
# Test ~ expansion | ||
It 'Tilde should be replaced by the filesystem provider home directory' { | ||
/bin/echo ~ | Should BeExactly ($executioncontext.SessionState.Provider.Get("FileSystem").Home) | ||
} | ||
# Test ~ expansion with a path fragment (e.g. ~/foo) | ||
It '~/foo should be replaced by the <filesystem provider home directory>/foo' { | ||
/bin/echo ~/foo | Should BeExactly "$($executioncontext.SessionState.Provider.Get("FileSystem").Home)/foo" | ||
} | ||
} |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought we settled on calling the C api glob.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have no recollection of any such thing. Why would we do that rather than using PowerShell's intrinsic globbing capability?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
To be compatible as compatible with
bash
as reasonably possible. There are thingsglob
does that we don't with character classes.I don't recall discussing or looking closely at the inverse - if our wildcards support things that
glob
does not.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
PowerShell globbing supports all of the constructs described in glob(3) but is case-insensitive plus it understands powershell drives which fnmatch(3) is unaware of. Having the globbing behavior change based on the type of the command sounds like a very bad user experience.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are you sure?
/bin/echo *
should not echo files starting with.
, and/bin/echo "*"
should echo*
, not the files in the current directory.Maybe less interesting, but glob(7) says glob supports character classes like
[:upper:]
and more - we definitely don't support those. That said, it doesn't look likebash
supports those.Case-insensitive also concerns me.
rm M*
shouldn't remove files starting with lowercasem
.I'm not saying that glob(3) is exactly what we should use - just that there may be subtleties that we miss by not using a POSIX api.
As for PowerShell drives - I'm really curious if they'll be used on non-Windows platforms - I'm skeptical - symbolic links have served that purpose perfectly and work outside of PowerShell.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking at the bash source, a lot of the subtleties around globbing are in bash itself, not the glob routine. For example ~ expansion is not handled by glob. Likewise quote processing is handled in bash itself, not by the glob routine. Given that PowerShell does it's quote removal (and addition) in a very different way than bash, there are going to be differences. (To make /bin/echo "*" work, we need to be able to be able to determine if a string value was parsed as a bareword literal at execution time.) Also note that Bash optionally supports extended globbing (See Bash Extended Globbing for an overview). Anyway, I've opened a new issue to track this investigation #3655