Skip to content

Commit 76e474a

Browse files
committed
Add explicit formatting for Github Actions and Azure Pipelines
Closes #2 and #3
1 parent e103abf commit 76e474a

8 files changed

+135
-13
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
filter GetGooglePositionMessage {
2+
[CmdletBinding()]
3+
[OUtputType([string])]
4+
param(
5+
[Parameter(ValueFromPipeline)]
6+
[System.Management.Automation.ErrorRecord]
7+
$InputObject
8+
)
9+
$InvocationInfo = $InputObject.InvocationInfo
10+
# 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
11+
# 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
12+
# 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.
13+
$useTargetObject = $null -ne $InputObject.TargetObject -and
14+
$InputObject.TargetObject -is [System.Collections.IDictionary] -and
15+
([System.Collections.IDictionary]$InputObject.TargetObject).Contains('Line') -and
16+
([System.Collections.IDictionary]$InputObject.TargetObject).Contains('LineText')
17+
18+
$file = if ($useTargetObject) {
19+
"$($InputObject.TargetObject.File)"
20+
} elseif (.ScriptName) {
21+
"$($InvocationInfo.ScriptName)"
22+
}
23+
24+
$line = if ($useTargetObject) {
25+
$InputObject.TargetObject.Line
26+
} else {
27+
$InvocationInfo.ScriptLineNumber
28+
}
29+
30+
if ($useTargetObject) {
31+
"sourcepath=$file;linenumber=$line"
32+
} else {
33+
$column = $InvocationInfo.OffsetInLine
34+
"sourcepath=$file;linenumber=$line,columnnumber=$column"
35+
}
36+
}

source/private/GetConciseViewPositionMessage.ps1 renamed to source/private/GetConciseMessage.ps1

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
filter GetConciseViewPositionMessage {
1+
filter GetConciseMessage {
22
[CmdletBinding()]
33
param(
44
[Parameter(ValueFromPipeline)]

source/private/GetErrorMessage.ps1

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
filter GetErrorTitle {
2+
[CmdletBinding()]
3+
[OUtputType([string])]
4+
param(
5+
[Parameter(ValueFromPipeline)]
6+
[System.Management.Automation.ErrorRecord]
7+
$InputObject
8+
)
9+
if (! $err.ErrorDetails -or ! $err.ErrorDetails.Message) {
10+
if ($err.CategoryInfo.Category -eq 'ParserError' -and $err.Exception.Message.Contains("~$newline")) {
11+
# need to parse out the relevant part of the pre-rendered positionmessage
12+
$err.Exception.Message.split("~$newline")[1].split("${newline}${newline}")[0]
13+
} elseif ($err.Exception) {
14+
$err.Exception.Message
15+
} elseif ($err.Message) {
16+
$err.Message
17+
} else {
18+
$err.ToString()
19+
}
20+
} else {
21+
$err.ErrorDetails.Message
22+
}
23+
}

source/private/GetErrorTitle.ps1

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
filter GetErrorTitle {
2+
[CmdletBinding()]
3+
[OUtputType([string])]
4+
param(
5+
[Parameter(ValueFromPipeline)]
6+
[System.Management.Automation.ErrorRecord]
7+
$InputObject
8+
)
9+
10+
if ($InputObject.Exception -and $InputObject.Exception.WasThrownFromThrowStatement) {
11+
'Exception'
12+
# MyCommand can be the script block, so we don't want to show that so check if it's an actual command
13+
} elseif ($InputObject.InvocationInfo.MyCommand -and $InputObject.InvocationInfo.MyCommand.Name -and (Get-Command -Name $InputObject.InvocationInfo.MyCommand -ErrorAction Ignore)) {
14+
$InputObject.InvocationInfo.MyCommand
15+
} elseif ($InputObject.CategoryInfo.Activity) {
16+
# If it's a scriptblock, better to show the command in the scriptblock that had the error
17+
$InputObject.CategoryInfo.Activity
18+
} elseif ($InputObject.InvocationInfo.MyCommand) {
19+
$InputObject.InvocationInfo.MyCommand
20+
} elseif ($InputObject.InvocationInfo.InvocationName) {
21+
$InputObject.InvocationInfo.InvocationName
22+
} elseif ($InputObject.CategoryInfo.Category) {
23+
$InputObject.CategoryInfo.Category
24+
} elseif ($InputObject.CategoryInfo.Reason) {
25+
$InputObject.CategoryInfo.Reason
26+
} else {
27+
'Error'
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
filter GetGoogleWorkflowPositionMessage {
2+
[CmdletBinding()]
3+
[OUtputType([string])]
4+
param(
5+
[Parameter(ValueFromPipeline)]
6+
[System.Management.Automation.ErrorRecord]
7+
$InputObject
8+
)
9+
$InvocationInfo = $InputObject.InvocationInfo
10+
# 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
11+
# 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
12+
# 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.
13+
$useTargetObject = $null -ne $InputObject.TargetObject -and
14+
$InputObject.TargetObject -is [System.Collections.IDictionary] -and
15+
([System.Collections.IDictionary]$InputObject.TargetObject).Contains('Line') -and
16+
([System.Collections.IDictionary]$InputObject.TargetObject).Contains('LineText')
17+
18+
$file = if ($useTargetObject) {
19+
"$($InputObject.TargetObject.File)"
20+
} elseif (.ScriptName) {
21+
"$($InvocationInfo.ScriptName)"
22+
}
23+
24+
$line = if ($useTargetObject) {
25+
$InputObject.TargetObject.Line
26+
} else {
27+
$InvocationInfo.ScriptLineNumber
28+
}
29+
30+
if ($useTargetObject) {
31+
"file=$file,line=$line"
32+
} else {
33+
$column = $InvocationInfo.OffsetInLine
34+
35+
$Length = $InvocationInfo.PositionMessage.Split($newline)[-1].Substring(1).Trim().Length
36+
$endColumn = $column + $Length
37+
"file=$file,line=$line,col=$column,endColumn=$endColumn"
38+
}
39+
}

source/private/WrapString.ps1

-10
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,3 @@
1-
$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=><~]))"
2-
$script:AnsiRegex = [Regex]::new($AnsiPattern, "Compiled");
3-
function MeasureString {
4-
[CmdletBinding()]
5-
param(
6-
[string]$InputObject
7-
)
8-
$AnsiRegex.Replace($InputObject, '').Length
9-
}
10-
111

122
filter WrapString {
133
[CmdletBinding()]

source/public/ConvertTo-ConciseErrorView.ps1

+1-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ function ConvertTo-ConciseErrorView {
1515
$local:resetColor = "<<<"
1616
}
1717

18-
$message = GetConciseViewPositionMessage -InputObject $InputObject
18+
$message = GetConciseMessage -InputObject $InputObject
1919

2020
if ($InputObject.PSMessageDetails) {
2121
$message = $errorColor + ' : ' + $InputObject.PSMessageDetails + $message

source/public/ConvertTo-DetailedErrorView.ps1

+6-1
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,10 @@ filter ConvertTo-DetailedErrorView {
2222
begin { ResetColor }
2323
process {
2424
$newline + (GetListRecursive $InputObject) + $newline
25+
if ($Env:GITHUB_ACTIONS) {
26+
Write-Host "::error $(GetGoogleWorkflowPositionMesage),title=$(GetErrorTitle $InputObject)::$(GetErrorMessage $InputObject)"
27+
} elseif ($Env:TF_BUILD) {
28+
Write-Host "##vso[task.logissue type=error;$(GetAzurePipelinesPositionMesage)]$(GetErrorTitle $InputObject): $(GetErrorMessage $InputObject)"
29+
}
2530
}
26-
}
31+
}

0 commit comments

Comments
 (0)