refactor: Common.psm1 拆成 BakNRet/{Public,Private},一函数一文件 + 薄加载器
3152 行、66 个函数的单文件模块拆成: BakNRet\BakNRet.psd1 模块清单:FunctionsToExport 是显式白名单(62 个名字) BakNRet\BakNRet.psm1 加载器:点源顺序的唯一一处声明 BakNRet\Public\*.ps1 62 个对外函数,一函数一文件,文件名 = 函数名 BakNRet\Private\*.ps1 4 个内部函数 + State.ps1(模块级状态集中一处) 为什么是一函数一文件:这是社区里脚本模块的主流形态(调研实测:winutil 79 个、 Terminal-Icons 24 个、ModuleBuilder 23 个,全部如此)。收益是改动落在小文件里、diff 按职责 可读、模块级状态有唯一去处。 为什么这不算"打散":模块内 dot-source 的文件共享同一个模块作用域(实测确认),所以 "按顺序点源 67 个文件"与"点源一个大文件"在语义上等价;顺序只在加载器里出现一次, tools\Build-BakNRetModule.ps1 从那里读出顺序就能拼回单文件 —— 本次产物 dist\BakNRet.psm1 3240 行、两个版本都解析零错。 新增一条断言把这条承诺钉住:加载器点源的文件集合必须与磁盘一致、导出名单必须与 Public\ 一一对应。漏一个文件或漏一个名字就是静默少一个函数 —— 而那种错在运行时只表现为 "找不到命令"。 引用更新:11 个文件里的 Common.psm1 改成 BakNRet\BakNRet.psd1(走清单导入, FunctionsToExport 才真的说了算);Common.psm1 直接删除,不留转发垫片。 验收:test.ps1 9/9 全绿(7 与 5.1),98 个文件两版解析零错,276 个断言原样通过 —— 这次搬家没有改变任何可观察行为。
This commit is contained in:
1 parent
78f43c8cc9
commit
2ad7987ffe
83 files changed
+3547
-3310
No files matched your search
+42
-1
@@ -35,7 +35,7 @@ $ErrorActionPreference = 'Stop'
|
||||
# 参数绑定阶段还没有给 $PSScriptRoot 赋值,默认值表达式会拿到空串(实测:带
|
||||
# [CmdletBinding()] -> 空串,不带 -> 正常;PowerShell 7 两种都正常)。所以默认值
|
||||
# 一律在这里补 —— 这也是本仓库对 -BackupDir / -ConfigPath 一直在用的写法。
|
||||
if (-not $ModulePath) { $ModulePath = Join-Path (Split-Path -Parent $PSScriptRoot) 'Common.psm1' }
|
||||
if (-not $ModulePath) { $ModulePath = Join-Path (Split-Path -Parent $PSScriptRoot) 'BakNRet\BakNRet.psd1' }
|
||||
Import-Module $ModulePath -Force
|
||||
Import-Module (Join-Path $PSScriptRoot 'TestHelpers.psm1') -Force
|
||||
|
||||
@@ -1314,6 +1314,47 @@ Test-Case '运行锁:释放之后可以重新取得' {
|
||||
}
|
||||
}
|
||||
|
||||
Test-Case '模块可以合回单文件:加载器的顺序声明完整、导出名单与 Public\ 一一对应' {
|
||||
# 这是"拆分可逆"那条承诺的守卫。顺序只在加载器里出现一次、导出面只在清单里出现一次,
|
||||
# 两者都必须与磁盘上的文件对得上 —— 否则哪天有人加了文件却忘了点源,工具照样能跑,
|
||||
# 而"合回单文件"会静默少一个函数。
|
||||
$repoRoot = Split-Path -Parent $PSScriptRoot
|
||||
$moduleRoot = Join-Path $repoRoot 'BakNRet'
|
||||
$loaderPath = Join-Path $moduleRoot 'BakNRet.psm1'
|
||||
Assert-FileExists $loaderPath
|
||||
$loader = @(Get-Content -Encoding UTF8 -LiteralPath $loaderPath)
|
||||
|
||||
# 用 Split 取路径,不用正则:这一行里同时有引号与反斜杠,正则嵌进测试文件之后
|
||||
# 多一层转义,很容易取到 0 个(第一版就是这样,而手工核对是 67 个)。
|
||||
$sources = @()
|
||||
foreach ($line in $loader) {
|
||||
if ($line -like '*Join-Path*' -and $line -like "*.ps1')*") {
|
||||
$quoted = $line.Split("'")
|
||||
if ($quoted.Count -ge 3) { $sources += $quoted[1] }
|
||||
}
|
||||
}
|
||||
Assert-True ($sources.Count -ge 60) "加载器里只点源了 $($sources.Count) 个文件,太少"
|
||||
foreach ($rel in $sources) { Assert-FileExists (Join-Path $moduleRoot ($rel -replace '/', '\')) }
|
||||
|
||||
# 磁盘上的每个函数文件都必须被点源到 —— 漏掉一个就是静默少一个函数
|
||||
$onDisk = @(Get-ChildItem -LiteralPath (Join-Path $moduleRoot 'Public'), (Join-Path $moduleRoot 'Private') -Filter *.ps1 |
|
||||
ForEach-Object { "$($_.Directory.Name)\$($_.Name)" })
|
||||
$missingFromLoader = @($onDisk | Where-Object { $sources -notcontains $_ })
|
||||
Assert-Equal 0 $missingFromLoader.Count ("这些文件没被加载器点源:" + ($missingFromLoader -join '、'))
|
||||
|
||||
# 导出名单必须与 Public\ 下的文件一一对应(少一个就是静默不导出)
|
||||
$exported = @()
|
||||
foreach ($line in $loader) {
|
||||
$trimmed = $line.Trim()
|
||||
if ($trimmed.StartsWith("'")) { $exported += $trimmed.TrimStart("'").TrimEnd("'", ',') }
|
||||
}
|
||||
$publicNames = @(Get-ChildItem -LiteralPath (Join-Path $moduleRoot 'Public') -Filter *.ps1 | ForEach-Object { $_.BaseName })
|
||||
$notExported = @($publicNames | Where-Object { $exported -notcontains $_ })
|
||||
Assert-Equal 0 $notExported.Count ("Public\ 下有文件没写进导出名单:" + ($notExported -join '、'))
|
||||
$noFile = @($exported | Where-Object { $publicNames -notcontains $_ })
|
||||
Assert-Equal 0 $noFile.Count ("导出名单里有名字没有对应文件:" + ($noFile -join '、'))
|
||||
}
|
||||
|
||||
# ============================================================================
|
||||
Remove-Item -LiteralPath $sandbox -Recurse -Force -ErrorAction SilentlyContinue
|
||||
Remove-Item -LiteralPath $itemSandbox -Recurse -Force -ErrorAction SilentlyContinue
|
||||
|
||||
Reference in new issue
Block a user