110 lines
5.8 KiB
Plaintext
110 lines
5.8 KiB
Plaintext
$ErrorActionPreference = "Stop"
|
|
$outputDir = "@PSC_REPORT_OUTPUT_DIR@"
|
|
$projectName = "@PSC_REPORT_PROJECT_NAME@"
|
|
$paths = [ordered]@{
|
|
llvm = "@PSC_REPORT_LLVM_DIR@"
|
|
cppcheck = "@PSC_REPORT_CPPCHECK_DIR@"
|
|
lizard = "@PSC_REPORT_LIZARD_DIR@"
|
|
code_count = "@PSC_REPORT_CODE_COUNT_DIR@"
|
|
coupling = "@PSC_REPORT_COUPLING_DIR@"
|
|
}
|
|
function Read-Summary([string]$Directory) {
|
|
$path = Join-Path $Directory "summary.json"
|
|
if (!(Test-Path -LiteralPath $path)) {
|
|
throw "Metrics summary was not found at $path"
|
|
}
|
|
return Get-Content -LiteralPath $path -Raw | ConvertFrom-Json
|
|
}
|
|
function H([object]$Value) {
|
|
return [Net.WebUtility]::HtmlEncode([string]$Value)
|
|
}
|
|
function Metric-Table([string]$Title, [object[]]$Rows, [string[]]$Columns) {
|
|
$builder = [Text.StringBuilder]::new()
|
|
[void]$builder.Append("<section><h2>$(H $Title)</h2><div class=`"table-wrap`"><table><thead><tr>")
|
|
foreach ($column in $Columns) {
|
|
[void]$builder.Append("<th>$(H $column)</th>")
|
|
}
|
|
[void]$builder.Append("</tr></thead><tbody>")
|
|
foreach ($row in @($Rows)) {
|
|
[void]$builder.Append("<tr>")
|
|
foreach ($column in $Columns) {
|
|
[void]$builder.Append("<td>$(H $row.$column)</td>")
|
|
}
|
|
[void]$builder.Append("</tr>")
|
|
}
|
|
[void]$builder.Append("</tbody></table></div></section>")
|
|
return $builder.ToString()
|
|
}
|
|
$data = [ordered]@{}
|
|
foreach ($entry in $paths.GetEnumerator()) {
|
|
$data[$entry.Key] = Read-Summary $entry.Value
|
|
}
|
|
New-Item -ItemType Directory -Force -Path $outputDir | Out-Null
|
|
$generatedAt = [DateTimeOffset]::Now.ToString("yyyy-MM-dd HH:mm:ss zzz")
|
|
$html = [Text.StringBuilder]::new()
|
|
[void]$html.Append(@"
|
|
<!doctype html>
|
|
<html lang="zh-CN">
|
|
<head>
|
|
<meta charset="utf-8">
|
|
<meta name="viewport" content="width=device-width,initial-scale=1">
|
|
<title>$(H $projectName) Engineering Metrics</title>
|
|
<style>
|
|
:root{font-family:"Segoe UI","Microsoft YaHei",sans-serif;color:#18212b;background:#f4f6f8}
|
|
body{margin:0}main{max-width:1500px;margin:auto;padding:28px}
|
|
header{display:flex;justify-content:space-between;align-items:flex-end;border-bottom:3px solid #1b6b5a;padding-bottom:16px}
|
|
h1{font-size:30px;margin:0}h2{font-size:20px;margin:0 0 12px}
|
|
.meta{color:#5d6975}.summary{display:grid;grid-template-columns:repeat(auto-fit,minmax(180px,1fr));gap:12px;margin:20px 0}
|
|
.metric{background:white;border:1px solid #d7dde3;border-left:4px solid #1b6b5a;padding:14px}.metric strong{display:block;font-size:24px}.metric span{color:#5d6975}
|
|
section{background:white;border:1px solid #d7dde3;margin:14px 0;padding:16px}.table-wrap{overflow:auto;max-height:520px}
|
|
table{border-collapse:collapse;width:100%;font-size:13px}th{position:sticky;top:0;background:#e8eef1;text-align:left}th,td{border-bottom:1px solid #e1e5e9;padding:7px 9px;white-space:nowrap}tr:nth-child(even){background:#fafbfc}
|
|
a{color:#075f52}footer{color:#68737d;padding:12px 0}
|
|
</style>
|
|
</head>
|
|
<body><main>
|
|
<header><div><h1>$(H $projectName) 软件工程指标</h1><div class="meta">静态分析、复杂度、代码规模与耦合度统一报告</div></div><div class="meta">$(H $generatedAt)</div></header>
|
|
<div class="summary">
|
|
<div class="metric"><strong>$($data.code_count.totals.code)</strong><span>代码行</span></div>
|
|
<div class="metric"><strong>$($data.lizard.functions)</strong><span>函数数</span></div>
|
|
<div class="metric"><strong>$($data.lizard.average_ccn)</strong><span>平均圈复杂度</span></div>
|
|
<div class="metric"><strong>$($data.llvm.findings)</strong><span>认知复杂度记录</span></div>
|
|
<div class="metric"><strong>$($data.coupling.include_edges)</strong><span>内部 include 边</span></div>
|
|
<div class="metric"><strong>$($data.cppcheck.findings)</strong><span>Cppcheck 发现</span></div>
|
|
</div>
|
|
"@)
|
|
[void]$html.Append((Metric-Table "语言与代码规模" @($data.code_count.languages) @("Language", "Files", "Code", "Comments", "Blanks", "Total")))
|
|
[void]$html.Append((Metric-Table "圈复杂度 Top" @($data.lizard.cyclomatic_top) @("CCN", "NLOC", "Function", "File", "StartLine")))
|
|
[void]$html.Append((Metric-Table "认知复杂度 Top" @($data.llvm.top) @("Score", "Function", "File", "Line")))
|
|
[void]$html.Append((Metric-Table "文件耦合度 Top" @($data.coupling.file_top) @("Coupling", "Afferent", "Efferent", "Instability", "File")))
|
|
[void]$html.Append((Metric-Table "模块耦合度 Top" @($data.coupling.module_top) @("Coupling", "Afferent", "Efferent", "Instability", "Module")))
|
|
[void]$html.Append((Metric-Table "Cppcheck 发现" @($data.cppcheck.top) @("Severity", "Id", "Message", "File", "Line")))
|
|
[void]$html.Append(@"
|
|
<section><h2>依赖图</h2><p><a href="coupling/module_coupling.svg">打开模块耦合 SVG</a></p><p class="meta">循环依赖组件数:$(@($data.coupling.cycles).Count)</p></section>
|
|
<footer>原始 JSON、CSV、XML、DOT 和 SVG 均保留在各子目录,可供 CI 或后续基准比较。</footer>
|
|
</main></body></html>
|
|
"@)
|
|
[IO.File]::WriteAllText((Join-Path $outputDir "index.html"), $html.ToString(), [Text.UTF8Encoding]::new($false))
|
|
$combined = [ordered]@{
|
|
project = $projectName
|
|
generated_at = $generatedAt
|
|
code_count = $data.code_count
|
|
lizard = $data.lizard
|
|
llvm = $data.llvm
|
|
cppcheck = $data.cppcheck
|
|
coupling = $data.coupling
|
|
}
|
|
[IO.File]::WriteAllText((Join-Path $outputDir "metrics.json"), ($combined | ConvertTo-Json -Depth 12), [Text.UTF8Encoding]::new($false))
|
|
$markdown = @(
|
|
"# $projectName 软件工程指标"
|
|
""
|
|
"- 代码行:$($data.code_count.totals.code)"
|
|
"- 函数数:$($data.lizard.functions)"
|
|
"- 平均圈复杂度:$($data.lizard.average_ccn)"
|
|
"- Cppcheck 发现:$($data.cppcheck.findings)"
|
|
"- 内部 include 边:$($data.coupling.include_edges)"
|
|
""
|
|
"详细表格请打开 `index.html`。"
|
|
)
|
|
[IO.File]::WriteAllLines((Join-Path $outputDir "README.md"), $markdown, [Text.UTF8Encoding]::new($false))
|
|
Write-Output "Engineering metrics report: $outputDir"
|