Skip to main content

Count lines of code per file type

Symptoms​

You have source code in a folder and want to count the total number of lines per file type.

Cause​

n/a

Resolution​

This script starts in a root folder and recurses. If there is a .gitIgnore file it will ignore files and paths specified within there. Results are saved to a CSV file.

Define the folder to explore

$folderPath = "C:\PathToProject" $outputFilePath = "$folderPath\results-summary.csv" $gitIgnorePath = "$folderPath.gitignore"

Function to get the patterns from the .gitignore file

function Get-GitIgnorePatterns { param ( [string]$gitIgnorePath )

if (Test-Path $gitIgnorePath) {
Get-Content $gitIgnorePath | Where-Object {
$_ -and -not $_.StartsWith('#') -and -not $_.Trim().StartsWith('!')
}
} else {
return @() # Return empty if no .gitignore found
}

}

Function to check if a path matches any pattern in the .gitignore

function Is-IgnoredPath { param ( [string]$path, [array]$patterns )

foreach ($pattern in $patterns) {
# Convert gitignore patterns to match file/directory paths in a flexible way
$regexPattern = [regex]::Escape($folderPath + "\" + $pattern).Replace("\\*", ".*").Replace("\\?", ".")

if ($path -like $regexPattern) {
return $true
}
}
return $false

}

Get all patterns from .gitignore

$gitIgnorePatterns = Get-GitIgnorePatterns -gitIgnorePath $gitIgnorePath

Initialize a hashtable to store file extensions, file counts, and line counts

$fileStats = @{}

Get all files from the folder and subfolders

Get-ChildItem -Path $folderPath -Recurse -File | ForEach-Object { $file = $_ $filePath = $file.FullName

# Skip files and folders that match the .gitignore patterns
if (Is-IgnoredPath -path $filePath -patterns $gitIgnorePatterns) {
return
}

$extension = $file.Extension.ToLower()

# Initialize the extension in the hashtable if it doesn't exist
if (-not $fileStats.ContainsKey($extension)) {
$fileStats[$extension] = @{
FileCount = 0
LineCount = 0
}
}

# Increment the file count
$fileStats[$extension].FileCount++

# Get the number of lines in the file and add to the line count
$lineCount = (Get-Content $file.FullName | Measure-Object -Line).Lines
$fileStats[$extension].LineCount += $lineCount

}

Prepare the output data as a list of custom objects

$outputData = foreach ($extension in $fileStats.Keys) { $fileInfo = $fileStats[$extension] [PSCustomObject]@{ Extension = $extension FileCount = $fileInfo.FileCount LineCount = $fileInfo.LineCount } }

Export the data to a CSV file

$outputData | Export-Csv -Path $outputFilePath -NoTypeInformation

Inform the user

Write-Host "Results exported to $outputFilePath"