Repository navigation
Enable path globbing for native commands - #2325
Andy Jordan (andyleejordan) wants to merge 2 commits into
Conversation
|
Hi Andy Jordan (@andschwa), I'm your friendly neighborhood Microsoft Pull Request Bot (You can call me MSBOT). Thanks for your contribution!
TTYL, MSBOT; |
|
Jeffery's great. The problem with |
There was a problem hiding this comment.
You can avoid a memory allocation that is thrown away in a common case by initializing with null instead.
There was a problem hiding this comment.
This is worth some discussion - I think we'll actually want to add escaping to globbing instead of this.
There was a problem hiding this comment.
While I agree escaping is the better way to go, I think that not only can it be done separately, it really needs to be done separately as it's a much much larger change (and would affect many more systems, as this is the same globbing system used by cmdlets).
sergei (vors)
left a comment
There was a problem hiding this comment.
I think we should talk about the overall approach in more details
There was a problem hiding this comment.
I would argue that we should provide some way to control it and not tide it to the platform. We can have different defaults on different platforms.
But the problem come with cross-platform tools (i.e. git). It would be pretty unfun to get inconsistent behavior on different platforms.
There was a problem hiding this comment.
Jason Shirk (@lzybkr) wanted it tied to the platform in #1639. Do you want something in addition to --% to disable globbing?
I agree, inconsistent behavior isn't fun. But this is what I'm operating off:
At a minimum, I think we can't do globbing on Windows at all - Windows tools implement globbing themselves, so even if we did something, it might work differently than the tool we're calling.
So Windows versus Linux tools are already introducing inconsistent behavior regardless of us.
There was a problem hiding this comment.
As I said, the motivation example are tools that exists on both platforms, like git, gcc and so on.
There was a problem hiding this comment.
Yes, and they appear to already operate differently. Investigating:
Git
PS C:\Users\andrew\src\test> ls
Directory: C:\Users\andrew\src\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 9/22/2016 10:42 AM 0 foo
-a---- 9/22/2016 10:42 AM 0 foobar
-a---- 9/22/2016 10:42 AM 0 foobaz
-a---- 9/22/2016 10:42 AM 0 foobil
-a---- 9/22/2016 10:42 AM 0 foocod
PS C:\Users\andrew\src\test> git add foo*
PS C:\Users\andrew\src\test> git status
On branch master
Initial commit
Changes to be committed:
(use "git rm --cached <file>..." to unstage)
new file: foo
new file: foobar
new file: foobaz
new file: foobil
new file: foocodIt did the same with PowerShell on Linux without these changes; so it globs itself on both platforms. That said, Bash definitely glob expands and it works just fine.
GCC
On Linux without these changes:
~/test |-/ ls
foobar.c foobaz.c foobil.c foo.c foocod.c
~/test |-/ gcc *.c
gcc: error: *.c: No such file or directory
gcc: fatal error: no input files
compilation terminated.But with GCC through MinGW (i.e. not Cygwin) on Windows, GCC globs:
PS C:\Users\andrew\src\test> ls
Directory: C:\Users\andrew\src\test
Mode LastWriteTime Length Name
---- ------------- ------ ----
-a---- 9/22/2016 11:07 AM 0 foo.c
-a---- 9/22/2016 11:07 AM 0 foobar.c
-a---- 9/22/2016 11:07 AM 0 foobaz.c
-a---- 9/22/2016 11:07 AM 0 foobil.c
-a---- 9/22/2016 11:07 AM 0 foocod.c
PS C:\Users\andrew\src\test> C:\MinGW\bin\gcc.exe *.c
PS C:\Users\andrew\src\test>
PS C:\Users\andrew\src\test> C:\MinGW\bin\gcc.exe *.blah
gcc.exe: error: *.blah: Invalid argument
gcc.exe: fatal error: no input files
compilation terminated.We can't test everything, but so far Jason Shirk (@lzybkr) appears right, and tools built for Windows (even cross-platform ones like Git and GCC) don't expect globbing to be done for them, and so do it themselves.
There was a problem hiding this comment.
Thank you for the detailed info!
There was a problem hiding this comment.
I actually don't get why globbing place any role here. There is no *, so it should not alternate the arguments that are passed.
There was a problem hiding this comment.
[ is also a wildcard character.
There was a problem hiding this comment.
And was previously discovered by Jason Shirk (@lzybkr), the :: is being interpreted as a filesystem provider separator.
There was a problem hiding this comment.
The meaning of :: as file path separator should not anyhow trigger globbing resolving. The [ makes more sense, I think the explanation comment above needs correction.
There was a problem hiding this comment.
Sure, I agree; but it's what's happening:
> & $powershell 2>&1 -noprofile -command '[Console]::Error.Write(\"foo`n`nbar`n`nbaz\");'
Cannot find a provider with the name '[Console]'.
At line:1 char:1
+ & $powershell 2>&1 -noprofile -command '[Console]::Error.Write(\"foo` ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: ([Console]:String) [], ProviderNotFoundException
+ FullyQualifiedErrorId : ProviderNotFound
There was a problem hiding this comment.
This is where I could really use some help, is there a better globber to use inside of PowerShell than this:
context.LocationGlobber.GetGlobbedProviderPathsFromMonadPath
It sure seemed correct; but I have minimal context.
There was a problem hiding this comment.
(By the way, if you do the non-sensical test of:
~ |-/ dir '[Console]::Error.Write(\"foo`n`nbar`n`nbaz\");'
dir : Cannot find a provider with the name '[Console]'.
At line:1 char:1
+ dir '[Console]::Error.Write(\"foo`n`nbar`n`nbaz\");'
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: ([Console]:String) [Get-ChildItem], ProviderNotFoundException
+ FullyQualifiedErrorId : ProviderNotFound,Microsoft.PowerShell.Commands.GetChildItemCommand
the same problem happens due to globbing. This is just a weird scenario because we're passing non-path data to a native command, but now glob arguments to native commands; and in this case we don't want to do that, so use verbatim.)
There was a problem hiding this comment.
If expansion fails, the argument is sent literally, so ls foo* results in /usr/bin/ls: cannot access foo*: No such file or directory.
Same should be applied here: if expansion failed due to provider error, the argument should be passed literally.
There was a problem hiding this comment.
Ah I see, yes I agree. Will fix.
sergei (@vors) Sure, please do. What ideas do you have? My approach was to plumb PowerShell's existing globbing logic into the native command parameter parser; minimum work and reuses logic to be consistent. |
|
Andy Jordan (@andschwa) I was mostly referring to UX and scripts portability, not the implementation. My concerns are in the single-line comments above. |
|
Hm, still getting used to GitHub reviews. I tried to remove my "change needed" mark, but the only way I found was to turn it into "approved". Now I don't see a way to recall it. |
fa20ea1 to
e072f7e
Compare
E.g. `ls *.md` expands to `ls /path/to/README.md /path/to/CHANGELOG.md` If expansion fails, the argument is sent literally, so `ls foo*` results in `/usr/bin/ls: cannot access foo*: No such file or directory`. Don't glob expand if the verbatim marker was used.
e072f7e to
92baf00
Compare
|
Per commitie decision we should revisit this work item. Jason Shirk (@lzybkr) proposed an implementation that would just call |
|
sergei (@vors) just read through the decision, it looks like a solid plan to me. I think we can close this PR, but feel free to reuse any portions of course. |
Enable path globbing for native commands.
E.g.
ls *.mdexpands tols /path/to/README.md /path/to/CHANGELOG.mdIf expansion fails, the argument is sent literally, so
ls foo*results in/usr/bin/ls: cannot access foo*: No such file or directory.Don't glob expand if the verbatim marker was used. So
ls --% *fails with/bin/ls: cannot access '*': No such file or directorySame caveats as #1639; but the code is enabled only on *nix platforms, and the failing test is fixed.