Files
build_infra/cloc_tokei/Code_Count.ps1.in
T
2026-07-28 17:55:29 +08:00

90 lines
3.8 KiB
Plaintext

$ErrorActionPreference = "Stop"
$inputDirs = @PSC_CODE_COUNT_INPUT_DIRS@
$excludeDirs = @PSC_CODE_COUNT_EXCLUDE_DIRS@
$outputDir = "@PSC_CODE_COUNT_OUTPUT_DIR@"
$configuredTokei = "@PSC_CODE_COUNT_TOKEI@"
$configuredCloc = "@PSC_CODE_COUNT_CLOC@"
function Resolve-Tool([string]$Configured, [string]$Name, [string[]]$Fallbacks) {
if ($Configured -and (Test-Path -LiteralPath $Configured)) {
return (Resolve-Path -LiteralPath $Configured).Path
}
$command = Get-Command $Name -ErrorAction SilentlyContinue | Select-Object -First 1
if ($command) {
return $command.Source
}
foreach ($fallback in $Fallbacks) {
if (Test-Path -LiteralPath $fallback) {
return (Resolve-Path -LiteralPath $fallback).Path
}
}
throw "$Name executable was not found"
}
$wingetLinks = Join-Path $env:LOCALAPPDATA "Microsoft\WinGet\Links"
$tokei = Resolve-Tool $configuredTokei "tokei" @((Join-Path $wingetLinks "tokei.exe"))
$cloc = Resolve-Tool $configuredCloc "cloc" @((Join-Path $wingetLinks "cloc.exe"))
New-Item -ItemType Directory -Force -Path $outputDir | Out-Null
$tokeiArguments = [Collections.Generic.List[string]]::new()
$tokeiArguments.Add("--output")
$tokeiArguments.Add("json")
foreach ($exclude in $excludeDirs) {
$tokeiArguments.Add("--exclude")
$tokeiArguments.Add(($exclude.Replace("\", "/") + "/*"))
}
foreach ($inputDir in $inputDirs) {
$tokeiArguments.Add($inputDir)
}
$tokeiPath = Join-Path $outputDir "tokei.json"
& $tokei @tokeiArguments | Set-Content -LiteralPath $tokeiPath -Encoding UTF8
if ($LASTEXITCODE -ne 0) {
throw "tokei failed with exit code $LASTEXITCODE"
}
$excludePattern = if ($excludeDirs.Count) {
($excludeDirs | ForEach-Object { [regex]::Escape(([IO.Path]::GetFullPath($_)).Replace("\", "/")) }) -join "|"
} else {
"(?!)"
}
$clocJsonPath = Join-Path $outputDir "cloc.json"
$clocXmlPath = Join-Path $outputDir "cloc.xml"
& $cloc @inputDirs "--json" "--by-file" "--fullpath" "--not-match-d=$excludePattern" "--out=$clocJsonPath"
if ($LASTEXITCODE -ne 0) {
throw "cloc JSON generation failed with exit code $LASTEXITCODE"
}
& $cloc @inputDirs "--xml" "--by-file" "--fullpath" "--not-match-d=$excludePattern" "--out=$clocXmlPath"
if ($LASTEXITCODE -ne 0) {
throw "cloc XML generation failed with exit code $LASTEXITCODE"
}
$tokeiData = Get-Content -LiteralPath $tokeiPath -Raw | ConvertFrom-Json
$languages = [Collections.Generic.List[object]]::new()
foreach ($property in $tokeiData.PSObject.Properties) {
if ($property.Name -eq "Total") {
continue
}
$value = $property.Value
$fileCount = if ($value.reports) { @($value.reports).Count } else { 0 }
$languages.Add([pscustomobject]@{
Language = $property.Name
Files = $fileCount
Code = [int64]$value.code
Comments = [int64]$value.comments
Blanks = [int64]$value.blanks
Total = [int64]$value.code + [int64]$value.comments + [int64]$value.blanks
})
}
$languageSummary = @($languages | Sort-Object Code -Descending)
$languageSummary | Export-Csv -LiteralPath (Join-Path $outputDir "languages.csv") -NoTypeInformation -Encoding UTF8
$summary = [ordered]@{
tools = [ordered]@{
tokei = (& $tokei --version | Select-Object -First 1).Trim()
cloc = (& $cloc --version | Select-Object -First 1).Trim()
}
totals = [ordered]@{
files = [int64](($languageSummary | Measure-Object Files -Sum).Sum)
code = [int64](($languageSummary | Measure-Object Code -Sum).Sum)
comments = [int64](($languageSummary | Measure-Object Comments -Sum).Sum)
blanks = [int64](($languageSummary | Measure-Object Blanks -Sum).Sum)
}
languages = $languageSummary
}
[IO.File]::WriteAllText((Join-Path $outputDir "summary.json"), ($summary | ConvertTo-Json -Depth 8), [Text.UTF8Encoding]::new($false))
Write-Output "Code count report: $outputDir"