Files
BakNRet/PSScriptAnalyzerSettings.psd1
Shuery 42f02d0eca refactor: 公共面补 BakNRet 前缀,产品名大小写全仓统一
16 个没有前缀的公共函数补上 BakNRet(Write-Log → Write-BakNRetLog、Resolve-BackupEntry →
Resolve-BakNRetBackupEntry、Find-ChildDirectoryByName → Find-BakNRetChildDirectoryByName 等),
另外把全仓的 Baknret 统一成 BakNRet(47 个文件、940 处、65 个定义文件重命名)。

这不是审美问题:静态分析直接拓出一条实据 —— Write-Log 与本机某个已装模块导出的命令
**重名**(PSAvoidOverwritingBuiltInCmdlets),而重名的后果是导入两个模块时有一方的命令被
静默遮蔽。补前缀正是这条规则的解法,改名后它归零。

为什么敢做这个规模:PowerShell 的函数名解析大小写不敏感,所以 Baknret → BakNRet 在功能
上是零风险;真正要验证的是 16 个补前缀的调用点,而 276 个断言几乎覆盖了每个函数。另外
"名字与文件名一致"这条不变式有断言盯着(加载器点源的文件集合 vs 磁盘)。

踩到并记下的坑:Windows 文件系统大小写不敏感,所以**只改大小写**的重命名会被 Move-Item
当成同一个文件而静默跳过 —— 同一批里同时改了名字的那 16 个文件却成功了,于是"看起来能跑"。
最后用"先移到临时名、再移到目标名"的两步走解决,判断与替换全部改用显式大小写敏感的形式
(-creplace / -cmatch)。

顺带把名录指纹缓存从 MD5 换成 SHA256(PSAvoidUsingBrokenHashAlgorithms):它只是缓存键,
没有兼容负担。

验收:test.ps1 9/9 全绿(7 与 5.1)、100 个文件两版解析零错、276 个断言全过、
构建工具仍能合回单文件(3300 行)。
2026-09-27 09:56:36 +08:00

107 lines
5.0 KiB
PowerShell
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<#
PSScriptAnalyzer 的配置。
为什么这个文件是必要的,而不是"跑一下默认规则就算按规范了":
默认规则集**不含**格式规则 —— PSPlaceOpenBrace / PSPlaceCloseBrace /
PSUseConsistentWhitespace / PSUseConsistentIndentation / PSAlignAssignmentStatement /
PSUseCorrectCasing 这六条默认都是 Disabled。所以
`Invoke-ScriptAnalyzer -Severity Warning,Error`(不带 -Settings)
会**静默漏掉全部排版问题**。
这里用 `Rules` 把格式规则**打开**,而不是用 `IncludeRules` 换一套:不带 IncludeRules 时
默认规则集照常生效,Rules 只是逐条改设置,于是"默认规则 + 格式规则"同时跑。
逐条决策(都在本次改造里确认过,理由另见 docs/adr/):
* PSAvoidUsingWriteHost 全局排除 —— Write-BakNRetLog 的彩色控制台输出是这份工具的**刻意设计**,
不是疏忽。这是架构性选择,所以在配置里排除掉,而不是逐处 Suppress 假装它是例外。
* PSUseSingularNouns 放行 SecurityRecords / MapKeys / ArchiveTopLevelNames ——
单数名 Get-BakNretSecurityRecord 已被"单对象版本"占用,为了规则把两个语义搅在一起
不值得。Data / Windows 是规则自带的默认放行项,显式写上以免被本条覆盖掉。
* PSAvoidLongLines 上限 160,而**不是**官方默认的 120:本仓库的中文注释与测试夹具
里的一行式目录让 120 意味着 270 处改动,而 160 意味着 41 处(并且 160 仍是
「宽但可读」)。这是一次有意的偏离,理由记在这里而不是悄悄放宽:如果哪天要收
紧到 120,先看 tools\Invoke-Analyzer.ps1 的输出里还有多少条。
* PSUseShouldProcessForStateChangingFunctions 全局排除 —— 本模块是库,不是入口:
WhatIf 的边界在 Backup.ps1 / Restore.ps1(它们自己管 -DryRun / -WhatIf)。
给库里 27 个改状态的函数都加 SupportsShouldProcess 会更糟:入口把 $WhatIfPreference
置真之后,这些函数会**静默跳过自己的工作**,备份看起来成功却什么都没做。
* PSAvoidUsingPlainTextForPassword 全局排除 —— 7z 只接受命令行口令(这是 7z 自身
的限制,README 的「加密」一节写明了取舍)。口令在这个工具里必然是明文字符串,
规则说的"用 SecureString"在这里没有可用的落点。
真正要守的两条已经另有措施:口令不进日志(遮蔽 + 断言)、口令不进版本库
(.gitignore + 出厂默认值留空)。
* PSUseConsistentIndentation 用 space + 4,与 .editorconfig 一致。
#>
@{
Severity = @('Error', 'Warning')
ExcludeRules = @(
'PSAvoidUsingWriteHost',
'PSUseShouldProcessForStateChangingFunctions',
'PSAvoidUsingPlainTextForPassword'
)
Rules = @{
# ---------------------------------------------------------------- 格式规则
PSPlaceOpenBrace = @{
Enable = $true
OnSameLine = $true
NewLineAfter = $true
IgnoreOneLineBlock = $true
}
PSPlaceCloseBrace = @{
Enable = $true
NewLineAfter = $true
IgnoreOneLineBlock = $true
NoEmptyLineBefore = $false
}
PSUseConsistentIndentation = @{
Enable = $true
Kind = 'space'
IndentationSize = 4
PipelineIndentation = 'IncreaseIndentationForFirstPipeline'
}
PSUseConsistentWhitespace = @{
Enable = $true
CheckInnerBrace = $true
CheckOpenBrace = $true
CheckOpenParen = $true
CheckOperator = $true
CheckPipe = $true
CheckPipeForRedundantWhitespace = $false
CheckSeparator = $true
CheckParameter = $false
IgnoreAssignmentOperatorInsideHashTable = $true
}
PSAlignAssignmentStatement = @{
Enable = $true
CheckHashtable = $true
}
PSUseCorrectCasing = @{
Enable = $true
}
# ---------------------------------------------------------------- 行长
PSAvoidLongLines = @{
Enable = $true
MaximumLineLength = 160
}
# ---------------------------------------------------------------- 名词白名单
PSUseSingularNouns = @{
Enable = $true
NounAllowList = @('Data', 'Windows', 'SecurityRecords', 'MapKeys', 'ArchiveTopLevelNames')
}
}
}