ugit icon indicating copy to clipboard operation
ugit copied to clipboard

bug: `Use-Git` throws when invocation starts with an `(`

Open ninmonkey opened this issue 1 year ago • 0 comments

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.

  • $callingContext is true null
  • $myInv.Line has 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]

ninmonkey avatar Aug 23 '24 17:08 ninmonkey