ugit
ugit copied to clipboard
bug: `Use-Git` throws when invocation starts with an `(`
When $CallingContext is falsy, $ToValidate can truncate the prefix of the command. of the command. Causing a syntax error.
It's essentially an off-by-one error when it calls substring. (It's off by 2 in this case)
The error occurs on these lines: Use-Git.ps1
Commands that can trigger it
( git log -n 3 )
( git remote get-url origin ).RemoteUrl
( use-git -GitArgument @( 'remote', 'get-url', 'origin' ) | % RemoteUrl
Error Message
> [scriptblock]::Create( 'git remote get-url origin ).RemoteUrl').Ast.EndBlock.Statements[0].PipelineElements[0]
Error: MethodInvocationException: Exception calling "Create" with "1" argument(s): "At line:1 char:14
+ git remote get-url origin ).RemoteUrl
+ ~
Unexpected token ')' in expression or statement."
# It meant to run
> [scriptblock]::Create( '( git remote get-url origin ).RemoteUrl').Ast.EndBlock.Statements[0].PipelineElements[0]
Expression Redirections Extent Parent
---------- ------------ ------ ------
( git remote get-url origin ).RemoteUrl {} ( git remote get-url origin ).RemoteUrl ( git remote get-url origin ).RemoteUrl
To reproduce
It does not error if ran interactively. It's deterministic. A script either fails 100% or 0% depending on the calling context.
-
$callingContextis true null -
$myInv.Linehas a prefix of( - It might only occur when ugit is being invoked from another script, or module.
I'm guessing this is referencing the wrong frame, when invoked by vs code
@(Get-PSCallStack)[-1].InvocationInfo.MyCommand.ScriptBlock
Example State
$null -eq $callingContext
# true
$myInv.Line
'( git remote get-url origin ).RemoteUrl'
$myInv.Line.Substring($myInv.OffsetInLine - 1)
'git remote get-url origin ).RemoteUrl'
$myInv.Line.Substring($myInv.OffsetInLine - 3)
'( git remote get-url origin ).RemoteUrl'
Potential fix
# The above cases ran as expected if I skip the substring step
$toValidate = $myInv.Line
# or added a prefix
[scriptblock]::Create( '( + ' $ToValidate ).Ast.EndBlock.Statements[0].PipelineElements[0]