Measure-Script.ps1

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
<#PSScriptInfo
.VERSION 1.0
 
.GUID c8dde45c-025a-4354-bf6e-eebe26d432c1
 
.AUTHOR Joel 'Jaykul' Bennett
 
.COMPANYNAME PoshCode.org
 
.COPYRIGHT Copyright 2019, Joel Bennett. All Rights Reserved
 
.TAGS Measure, LinesOfCode
 
.LICENSEURI https://opensource.org/licenses/MIT
 
.PROJECTURI https://gist.github.com/Jaykul/e1056d5182d0c5566a22f72387abf741
 
.ICONURI
 
.EXTERNALMODULEDEPENDENCIES PSScriptAnalyzer
 
.REQUIREDSCRIPTS
 
.EXTERNALSCRIPTDEPENDENCIES
 
.RELEASENOTES
 
.PRIVATEDATA
 
#>


#requires -module @{ModuleName = "PSScriptAnalyzer"; ModuleVersion = "1.17.1" }

<#
    .SYNOPSIS
        Count the lines of code in PowerShell script (or module) files
    .DESCRIPTION
        Counts the lines of code based on the compact One True Brace style (requires PSScriptAnalyzer)
        In -Verbose mode, outputs the OTBS formatted script with line number next to the lines that count
    .EXAMPLE
        Measure-Script $profile.CurrentUserAllHosts -Verbose
 
        Counts the number of lines in your profile script, and shows you which ones counted in verbose output
#>

[CmdletBinding()]
param(
    # The path to a script (.ps1) or module (.psm1) file
    [Parameter(ValueFromPipeline,ValueFromPipelineByPropertyName,Mandatory)]
    [Alias("PSPath")]
    [string]$Path,

    # If set, counts lines with nothing but a closing brace (default is not to count them)
    # See https://gist.github.com/Jaykul/e1056d5182d0c5566a22f72387abf741 for further details
    [switch]$IncludeTrailingBraces
)
process {
    # For lines of code, reformat everything to OTBS to produce meaningful numbers
    $Reformatted = Invoke-Formatter (Get-Content $Path -Raw) -Settings @{
        IncludeRules = @(
            'PSPlaceOpenBrace',
            'PSPlaceCloseBrace',
            'PSUseConsistentWhitespace',
            'PSUseConsistentIndentation',
            'PSAlignAssignmentStatement'
        )

        Rules        = @{
            PSPlaceOpenBrace           = @{
                Enable             = $true
                OnSameLine         = $true
                NewLineAfter       = $true
                IgnoreOneLineBlock = $false
            }

            PSPlaceCloseBrace          = @{
                Enable             = $true
                NewLineAfter       = $false
                IgnoreOneLineBlock = $true
                NoEmptyLineBefore  = $false
            }

            PSUseConsistentIndentation = @{
                Enable          = $true
                Kind            = 'space'
                IndentationSize = 4
            }

            PSUseConsistentWhitespace  = @{
                Enable         = $true
                CheckOpenBrace = $true
                CheckOpenParen = $true
                CheckOperator  = $true
                CheckSeparator = $true
            }

            PSAlignAssignmentStatement = @{
                Enable         = $true
                CheckHashtable = $true
            }
        }
    } -Verbose:$false

    $Ast = [System.Management.Automation.Language.Parser]::ParseInput($Reformatted, $Path, [ref]$Null, [ref]$Null)

    $LineNumbers = $(
        foreach ($Extent in $Ast.FindAll( {$Args[0] -ne $Ast}, $true).Extent) {
            $Extent.StartLineNumber
            if ($IncludeTrailingBraces) {
                $Extent.EndLineNumber
            }
        }
    ) | Sort-Object -Unique

    [PSCustomObject]@{
        PSTypeName = "CodeMetrics"
        "LinesOfCode" = $LineNumbers.Count
    }

    if ($VerbosePreference -notin "SilentlyContinue", "Ingore") {
        $Reformatted = $Reformatted -split "`n"
        $count = 0
        foreach($line in 0..$Reformatted.Count) {
            if(($line + 1) -in $LineNumbers) {
                Write-Verbose ("{0,3:d} {1}" -f (++$count), $Reformatted[$line])
            } else {
                Write-Verbose (" " + $Reformatted[$line])
            }
        }
    }
}