-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcount-code-lines.ps1
More file actions
122 lines (106 loc) · 3.33 KB
/
count-code-lines.ps1
File metadata and controls
122 lines (106 loc) · 3.33 KB
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
param(
[string]$Root = ".",
[switch]$IncludeBlankLines,
[switch]$IncludeComments
)
$ErrorActionPreference = "Stop"
$rootPath = (Resolve-Path -LiteralPath $Root).Path
# Default to C# source files only.
$codeExtensions = @(
".cs"
)
# Common folders to skip.
$excludeDirs = @(
".git", ".idea", ".vs",
"bin", "obj", "packages", "node_modules",
"artifacts", "TestResults"
)
function Is-ExcludedPath {
param(
[string]$FullPath,
[string[]]$ExcludedDirNames
)
$parts = $FullPath.Split([System.IO.Path]::DirectorySeparatorChar, [System.StringSplitOptions]::RemoveEmptyEntries)
foreach ($part in $parts) {
if ($ExcludedDirNames -contains $part) {
return $true
}
}
return $false
}
function Is-CommentLine {
param(
[string]$Line,
[string]$Extension
)
$trim = $Line.Trim()
if ([string]::IsNullOrWhiteSpace($trim)) {
return $false
}
switch ($Extension.ToLowerInvariant()) {
".cs" { return $trim.StartsWith("//") }
".cpp" { return $trim.StartsWith("//") }
".c" { return $trim.StartsWith("//") }
".h" { return $trim.StartsWith("//") }
".hpp" { return $trim.StartsWith("//") }
".js" { return $trim.StartsWith("//") }
".ts" { return $trim.StartsWith("//") }
".jsx" { return $trim.StartsWith("//") }
".tsx" { return $trim.StartsWith("//") }
".java" { return $trim.StartsWith("//") }
".kt" { return $trim.StartsWith("//") }
".go" { return $trim.StartsWith("//") }
".py" { return $trim.StartsWith("#") }
".rb" { return $trim.StartsWith("#") }
".sh" { return $trim.StartsWith("#") }
".ps1" { return $trim.StartsWith("#") }
".psm1" { return $trim.StartsWith("#") }
".sql" { return $trim.StartsWith("--") }
default { return $false }
}
}
$files = Get-ChildItem -LiteralPath $rootPath -Recurse -File | Where-Object {
($codeExtensions -contains $_.Extension.ToLowerInvariant()) -and
-not (Is-ExcludedPath -FullPath $_.FullName -ExcludedDirNames $excludeDirs)
}
if (-not $files) {
Write-Host "No matching code files found under: $rootPath"
exit 0
}
$totalLines = 0
$totalFiles = 0
$byExtension = @{}
foreach ($file in $files) {
$lines = Get-Content -LiteralPath $file.FullName -Encoding UTF8
$count = 0
foreach ($line in $lines) {
if (-not $IncludeBlankLines -and [string]::IsNullOrWhiteSpace($line)) {
continue
}
if (-not $IncludeComments -and (Is-CommentLine -Line $line -Extension $file.Extension)) {
continue
}
$count++
}
$totalFiles++
$totalLines += $count
$ext = $file.Extension.ToLowerInvariant()
if (-not $byExtension.ContainsKey($ext)) {
$byExtension[$ext] = [PSCustomObject]@{
Extension = $ext
Files = 0
Lines = 0
}
}
$byExtension[$ext].Files++
$byExtension[$ext].Lines += $count
}
Write-Host ""
Write-Host "Code statistics for: $rootPath" -ForegroundColor Cyan
Write-Host ("Files: {0}" -f $totalFiles)
Write-Host ("Total lines: {0}" -f $totalLines)
Write-Host ""
Write-Host "By extension:" -ForegroundColor Yellow
$byExtension.Values |
Sort-Object -Property Lines -Descending |
Format-Table Extension, Files, Lines -AutoSize