Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Use AnsiColor in jenkins via powershell

Any idea on how to use powershell to color my output on Jenkins ? I have already installed AnsiColor plugin on my Jenkins and I have set the job to use AnsiColor. The only problem is how to let my powershell output the color on Jenkins.

like image 310
fazlook1 Avatar asked Sep 02 '16 15:09

fazlook1


3 Answers

Well I've never used it before so I figured I'd try it. Basically you just literally put an escape character (ASCII 27) followed by a left bracket [ and then the codes, as described on this page, directly into the string.

To make this easier, I wrote a function that formats the string:

function Format-AnsiColor {
[CmdletBinding()]
[OutputType([String])]
param(
    [Parameter(
        Mandatory = $true,
        ValueFromPipeline = $true
    )]
    [AllowEmptyString()]
    [String]
    $Message ,

    [Parameter()]
    [ValidateSet(
         'normal display'
        ,'bold'
        ,'underline (mono only)'
        ,'blink on'
        ,'reverse video on'
        ,'nondisplayed (invisible)'
    )]
    [Alias('attribute')]
    [String]
    $Style ,

    [Parameter()]
    [ValidateSet(
         'black'
        ,'red'
        ,'green'
        ,'yellow'
        ,'blue'
        ,'magenta'
        ,'cyan'
        ,'white'
    )]
    [Alias('fg')]
    [String]
    $ForegroundColor ,

    [Parameter()]
    [ValidateSet(
         'black'
        ,'red'
        ,'green'
        ,'yellow'
        ,'blue'
        ,'magenta'
        ,'cyan'
        ,'white'
    )]
    [Alias('bg')]
    [String]
    $BackgroundColor
)

    Begin {
        $e = [char]27

        $attrib = @{
            'normal display' = 0
            'bold' = 1
            'underline (mono only)' = 4
            'blink on' = 5
            'reverse video on' = 7
            'nondisplayed (invisible)' = 8
        }

        $fore = @{
            black = 30
            red = 31
            green = 32
            yellow = 33
            blue = 34
            magenta = 35
            cyan = 36
            white = 37
        }

        $back = @{
            black = 40
            red = 41
            green = 42
            yellow = 43
            blue = 44
            magenta = 45
            cyan = 46
            white = 47
        }
    }

    Process {
        $formats = @()
        if ($Style) {
            $formats += $attrib[$Style]
        }
        if ($ForegroundColor) {
            $formats += $fore[$ForegroundColor]
        }
        if ($BackgroundColor) {
            $formats += $back[$BackgroundColor]
        }
        if ($formats) {
            $formatter = "$e[$($formats -join ';')m"
        }

       "$formatter$_"
    }
}

Usage:

Format-AnsiColor -Message 'Hey there' -Style Bold -ForegroundColor Red

'Hello' | Format-AnsiColor -BackgroundColor Green

'One','Two','Three' | Format-AnsiColor -Style 'normal display' -ForegroundColor White -BackgroundColor Black

Remember that you have to turn off the sequence (by that I mean set the style and colors back to whatever it was before) if you don't want it anymore.

like image 71
briantist Avatar answered Nov 07 '22 21:11

briantist


I use lot of long powershell in my Jenkin, color is essential ! I overwrite the native Write-Host in profile.ps1 of my Jenkins User. and now all my local script is colorized on Jenkins

function Write-Host {
    <#
        .SYNOPSIS
            Wrapper for Write-Host, adds ANSI SGR codes based on -foregroundColor and -backgroundColor
        .DESCRIPTION
            Renplace le Write-host standard, pour une compatibilité avec les sorties linux (JENKINS)
        .PARAMETER object
            Liste de String qui seront regroupe et affichée en couleur
        .PARAMETER foregroundColor
            Couleur du texte
        .PARAMETER backgroundColor
            Couleur de fond
        .PARAMETER nonewline
            si pas de retour a la ligne
        .NOTES
            👉 Alban LOPEZ 2018
            👣 [email protected]
            💛 http://git/PowerTech/
    #>
    param(
        $object,
        [ConsoleColor]$foregroundColor,
        [ConsoleColor]$backgroundColor,
        [switch]$nonewline
    )
        if (!(Get-Command Write-HostOriginal -ea 0).name){ # doit etre embarque (pour les scriptblock)
            $global:ConsoleOutput = ''
            $metaData = New-Object System.Management.Automation.CommandMetaData (Get-Command 'Microsoft.PowerShell.Utility\Write-Host')
            Invoke-Expression "function Global:Write-HostOriginal { $([System.Management.Automation.ProxyCommand]::create($metaData)) }"
        }

        # https://msdn.microsoft.com/en-us/library/system.consolecolor(v=vs.110).aspx
        # Converted to closest ANSI SGR equivalent
        $AnsiColor = [pscustomobject][ordered]@{ # doit etre embarque (pour les scriptblock)
            ForeGround = [pscustomobject][ordered]@{
                Black = 30
                Red = 91
                DarkRed = 31
                Green = 92
                DarkGreen = 32
                Yellow = 93
                DarkYellow = 33
                Blue = 94
                DarkBlue = 34
                Magenta = 95
                DarkMagenta = 35
                Cyan = 96
                DarkCyan = 36
                White = 97
                Gray = 37
                DarkGray = 90
            }
            BackGround = [pscustomobject][ordered]@{
                Black = 40
                White = 107
                Red = 101
                DarkRed = 41
                Green = 102
                DarkGreen = 42
                Yellow = 103
                DarkYellow = 43
                Blue = 104
                DarkBlue = 44
                Magenta = 105
                DarkMagenta = 45
                Cyan = 106
                DarkCyan = 46
                Gray = 47
                DarkGray = 100
            }
            style = [pscustomobject][ordered]@{
                RESET = 0
                BOLD_ON = 1
                ITALIC_ON = 3
                UNDERLINE_ON = 4
                BLINK_ON = 5
                REVERSE_ON = 7
                # BOLD_OFF = 22
                # ITALIC_OFF = 23
                # UDERLINE_OFF = 24
                # BLINK_OFF = 25
                # REVERSE_OFF = 27
            }
        }
        function Colorize-Text {
            <#
                .SYNOPSIS
                    Adds ANSI SGR codes to a string.
                .DESCRIPTION
                    Adds ANSI SGR codes to a string.
                .PARAMETER text
                    Text to be transformed.
                .PARAMETER ansiSgrCode
                    ANSI SGR number to insert.
                    See https://en.wikipedia.org/wiki/ANSI_escape_code for details
                    Or use the [AnsiColor] enum.

                    Also accepts an array of SGR numbers, and will apply all of them.
                .NOTES
                    Designed to play nicely with https://wiki.jenkins-ci.org/display/JENKINS/AnsiColor+Plugin
                .EXAMPLE
                    Colorize-Text 'toto' 7,93,101
            #>
            param(
                $object,
                [int[]]$ansiCodes #https://en.wikipedia.org/wiki/ANSI_escape_code#graphics
            )
            return "$([char]27)[$($ansiCodes -join(';'))m$object$([char]27)[0m"
        }

    $ansiCodes = @()

    if($style){
        $ansiCodes += $AnsiColor.style.$style
    }
    if($foregroundColor){
        $ansiCodes += $AnsiColor.ForeGround.$foregroundColor
    }
    if($backgroundColor) {
        $ansiCodes += $AnsiColor.BackGround.$backgroundColor
    }

    # Write-HostOriginal (Colorize-Text $object -ansiCodes $ansiCodes ) -nonewline # | Out-Host
    # (Colorize-Text $object -ansiCodes $ansiCodes ) | Out-Host
    # [Console]::Write( (Colorize-Text $object -ansiCodes $ansiCodes ) )
    if($foregroundColor -and $backgroundColor){
        # Write-HostOriginal (Colorize-Text $object -ansiCodes $ansiCodes ) -ForegroundColor $foregroundColor -BackgroundColor $backgroundColor -nonewline # | Out-Host
        $global:ConsoleOutput += (Colorize-Text $object -ansiCodes $ansiCodes )
    } elseif($foregroundColor){
        # Write-HostOriginal (Colorize-Text $object -ansiCodes $ansiCodes ) -ForegroundColor $foregroundColor -nonewline # | Out-Host
        $global:ConsoleOutput += (Colorize-Text $object -ansiCodes $ansiCodes )
    } elseif($backgroundColor){
        # Write-HostOriginal (Colorize-Text $object -ansiCodes $ansiCodes ) -BackgroundColor $backgroundColor -nonewline # | Out-Host
        $global:ConsoleOutput += (Colorize-Text $object -ansiCodes $ansiCodes )
    } else {
        # Write-HostOriginal $object -nonewline # | Out-Host
        $global:ConsoleOutput += $object
    }
    if (!$nonewline) {
        Write-HostOriginal $global:ConsoleOutput # -NoNewline
        $global:ConsoleOutput = ''
        # Write-HostOriginal '$!' -fore magenta 
    }
}

This code is compatible to ScriptBlock in thread and remote usage (Start-Job, Invoke-command)

like image 43
Alban Avatar answered Nov 07 '22 20:11

Alban


Drop-in Write-Host replacement that uses ANSI escape codes to render colors. Allows for colorized output in CI systems.

  • Source
.Synopsis
    Write-Host but with ANSI colors!

.Description
    Drop-in Write-Host replacement that uses ANSI escape codes to render colors.
    Allows for colorized output in CI systems.

.Parameter Object
    Objects to display in the host.

.Parameter ForegroundColor
    Specifies the text color. There is no default.

.Parameter BackgroundColor
    Specifies the background color. There is no default.

.Parameter Separator
    Specifies a separator string to insert between objects displayed by the host.

.Parameter NoNewline
    The string representations of the input objects are concatenated to form the output.
    No spaces or newlines are inserted between the output strings.
    No newline is added after the last output string.

.Example
    Write-Host 'Double rainbow!' -ForegroundColor Magenta -BackgroundColor Yellow

.Notes
    Author : beatcracker (https://github.com/beatcracker)
    License: MS-PL (https://opensource.org/licenses/MS-PL)
    Source : https://github.com/beatcracker/Powershell-Misc
#>
function Write-Host {
    [CmdletBinding()]
    Param(
        [Parameter(ValueFromPipeline)]
        [Alias('Msg', 'Message')]
        [System.Object[]]$Object,
        [System.Object]$Separator,
        [System.ConsoleColor]$ForegroundColor,
        [System.ConsoleColor]$BackgroundColor,
        [switch]$NoNewline
    )

    Begin {
        # Map ConsoleColor enum values to ANSI colors
        # https://en.wikipedia.org/wiki/ANSI_escape_code#3/4_bit
        $AnsiColor = @(
            30, 34, 32, 36, 31, 35, 33, 37, 90, 94, 92, 96, 91, 95, 93, 97
        )
        # PS < 6.0 doesn't have `e escape character
        $Esc = [char]27
        $AnsiTemplate = "$Esc[{0}m{1}$Esc[{2}m"
    }

    Process {
        # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_special_characters#escape-e
        # https://learn.microsoft.com/en-us/powershell/scripting/windows-powershell/wmf/whats-new/console-improvements#vt100-support
        if ($Host.UI.SupportsVirtualTerminal) {
            $Method = if ($NoNewline) { 'Write' } else { 'WriteLine' }
            $Output = if ($Separator) { $Object -join $Separator } else { "$Object" }

            # Splitting by regex ensures that this will work on files from Windows/Linux/macOS
            # Get-Content .\Foobar.txt -Raw | Write-Host -ForegroundColor Red
            foreach ($item in $Output -split '\r\n|\r|\n') {
                if ("$BackgroundColor") {
                    $item = $AnsiTemplate -f ($AnsiColor[$BackgroundColor.value__] + 10), $item, 49
                }
                if ("$ForegroundColor") {
                    $item = $AnsiTemplate -f $AnsiColor[$ForegroundColor.value__], $item, 39
                }

                [System.Console]::$Method($item)
            }
        }
        else {
            Microsoft.PowerShell.Utility\Write-Host @PSBoundParameters
        }
    }
}
like image 36
beatcracker Avatar answered Nov 07 '22 20:11

beatcracker