Skip to content

Commit

Permalink
Add explicit formatting for Github Actions and Azure Pipelines
Browse files Browse the repository at this point in the history
Closes #2 and #3
  • Loading branch information
Jaykul committed Oct 7, 2024
1 parent e103abf commit 76e474a
Show file tree
Hide file tree
Showing 8 changed files with 135 additions and 13 deletions.
36 changes: 36 additions & 0 deletions source/private/GetAzurePipelinePositionMessage.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
filter GetGooglePositionMessage {
[CmdletBinding()]
[OUtputType([string])]
param(
[Parameter(ValueFromPipeline)]
[System.Management.Automation.ErrorRecord]
$InputObject
)
$InvocationInfo = $InputObject.InvocationInfo
# Handle case where there is a TargetObject from a Pester `Should` assertion failure and we can show the error at the target rather than the script source
# Note that in some versions, this is a Dictionary<,> and in others it's a hashtable. So we explicitly cast to a shared interface in the method invocation
# to force using `IDictionary.Contains`. Hashtable does have it's own `ContainKeys` as well, but if they ever opt to use a custom `IDictionary`, that may not.
$useTargetObject = $null -ne $InputObject.TargetObject -and
$InputObject.TargetObject -is [System.Collections.IDictionary] -and
([System.Collections.IDictionary]$InputObject.TargetObject).Contains('Line') -and
([System.Collections.IDictionary]$InputObject.TargetObject).Contains('LineText')

$file = if ($useTargetObject) {
"$($InputObject.TargetObject.File)"
} elseif (.ScriptName) {
"$($InvocationInfo.ScriptName)"
}

$line = if ($useTargetObject) {
$InputObject.TargetObject.Line
} else {
$InvocationInfo.ScriptLineNumber
}

if ($useTargetObject) {
"sourcepath=$file;linenumber=$line"
} else {
$column = $InvocationInfo.OffsetInLine
"sourcepath=$file;linenumber=$line,columnnumber=$column"
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
filter GetConciseViewPositionMessage {
filter GetConciseMessage {
[CmdletBinding()]
param(
[Parameter(ValueFromPipeline)]
Expand Down
23 changes: 23 additions & 0 deletions source/private/GetErrorMessage.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
filter GetErrorTitle {
[CmdletBinding()]
[OUtputType([string])]
param(
[Parameter(ValueFromPipeline)]
[System.Management.Automation.ErrorRecord]
$InputObject
)
if (! $err.ErrorDetails -or ! $err.ErrorDetails.Message) {
if ($err.CategoryInfo.Category -eq 'ParserError' -and $err.Exception.Message.Contains("~$newline")) {
# need to parse out the relevant part of the pre-rendered positionmessage
$err.Exception.Message.split("~$newline")[1].split("${newline}${newline}")[0]
} elseif ($err.Exception) {
$err.Exception.Message
} elseif ($err.Message) {
$err.Message
} else {
$err.ToString()
}
} else {
$err.ErrorDetails.Message
}
}
29 changes: 29 additions & 0 deletions source/private/GetErrorTitle.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
filter GetErrorTitle {
[CmdletBinding()]
[OUtputType([string])]
param(
[Parameter(ValueFromPipeline)]
[System.Management.Automation.ErrorRecord]
$InputObject
)

if ($InputObject.Exception -and $InputObject.Exception.WasThrownFromThrowStatement) {
'Exception'
# MyCommand can be the script block, so we don't want to show that so check if it's an actual command
} elseif ($InputObject.InvocationInfo.MyCommand -and $InputObject.InvocationInfo.MyCommand.Name -and (Get-Command -Name $InputObject.InvocationInfo.MyCommand -ErrorAction Ignore)) {
$InputObject.InvocationInfo.MyCommand
} elseif ($InputObject.CategoryInfo.Activity) {
# If it's a scriptblock, better to show the command in the scriptblock that had the error
$InputObject.CategoryInfo.Activity
} elseif ($InputObject.InvocationInfo.MyCommand) {
$InputObject.InvocationInfo.MyCommand
} elseif ($InputObject.InvocationInfo.InvocationName) {
$InputObject.InvocationInfo.InvocationName
} elseif ($InputObject.CategoryInfo.Category) {
$InputObject.CategoryInfo.Category
} elseif ($InputObject.CategoryInfo.Reason) {
$InputObject.CategoryInfo.Reason
} else {
'Error'
}
}
39 changes: 39 additions & 0 deletions source/private/GetGoogleWorkflowPositionMessage.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
filter GetGoogleWorkflowPositionMessage {
[CmdletBinding()]
[OUtputType([string])]
param(
[Parameter(ValueFromPipeline)]
[System.Management.Automation.ErrorRecord]
$InputObject
)
$InvocationInfo = $InputObject.InvocationInfo
# Handle case where there is a TargetObject from a Pester `Should` assertion failure and we can show the error at the target rather than the script source
# Note that in some versions, this is a Dictionary<,> and in others it's a hashtable. So we explicitly cast to a shared interface in the method invocation
# to force using `IDictionary.Contains`. Hashtable does have it's own `ContainKeys` as well, but if they ever opt to use a custom `IDictionary`, that may not.
$useTargetObject = $null -ne $InputObject.TargetObject -and
$InputObject.TargetObject -is [System.Collections.IDictionary] -and
([System.Collections.IDictionary]$InputObject.TargetObject).Contains('Line') -and
([System.Collections.IDictionary]$InputObject.TargetObject).Contains('LineText')

$file = if ($useTargetObject) {
"$($InputObject.TargetObject.File)"
} elseif (.ScriptName) {
"$($InvocationInfo.ScriptName)"
}

$line = if ($useTargetObject) {
$InputObject.TargetObject.Line
} else {
$InvocationInfo.ScriptLineNumber
}

if ($useTargetObject) {
"file=$file,line=$line"
} else {
$column = $InvocationInfo.OffsetInLine

$Length = $InvocationInfo.PositionMessage.Split($newline)[-1].Substring(1).Trim().Length
$endColumn = $column + $Length
"file=$file,line=$line,col=$column,endColumn=$endColumn"
}
}
10 changes: 0 additions & 10 deletions source/private/WrapString.ps1
Original file line number Diff line number Diff line change
@@ -1,13 +1,3 @@
$script:AnsiPattern = "[\u001b\u009b][[\]()#;?]*(?:(?:(?:(?:;[-a-zA-Z\d\/#&.:=?%@~_]+)*|[a-zA-Z\d]+(?:;[-a-zA-Z\d\/#&.:=?%@~_]*)*)?(?:\u001b\u005c|\u0007))|(?:(?:\d{1,4}(?:;\d{0,4})*)?[\dA-PR-TZcf-nq-uy=><~]))"
$script:AnsiRegex = [Regex]::new($AnsiPattern, "Compiled");
function MeasureString {
[CmdletBinding()]
param(
[string]$InputObject
)
$AnsiRegex.Replace($InputObject, '').Length
}


filter WrapString {
[CmdletBinding()]
Expand Down
2 changes: 1 addition & 1 deletion source/public/ConvertTo-ConciseErrorView.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ function ConvertTo-ConciseErrorView {
$local:resetColor = "<<<"
}

$message = GetConciseViewPositionMessage -InputObject $InputObject
$message = GetConciseMessage -InputObject $InputObject

if ($InputObject.PSMessageDetails) {
$message = $errorColor + ' : ' + $InputObject.PSMessageDetails + $message
Expand Down
7 changes: 6 additions & 1 deletion source/public/ConvertTo-DetailedErrorView.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,10 @@ filter ConvertTo-DetailedErrorView {
begin { ResetColor }
process {
$newline + (GetListRecursive $InputObject) + $newline
if ($Env:GITHUB_ACTIONS) {
Write-Host "::error $(GetGoogleWorkflowPositionMesage),title=$(GetErrorTitle $InputObject)::$(GetErrorMessage $InputObject)"
} elseif ($Env:TF_BUILD) {
Write-Host "##vso[task.logissue type=error;$(GetAzurePipelinesPositionMesage)]$(GetErrorTitle $InputObject): $(GetErrorMessage $InputObject)"
}
}
}
}

0 comments on commit 76e474a

Please sign in to comment.