Files
BakNRet/SoftwareCatalog.psd1
Shuery 187d2759fd style: 按微软规范落地静态分析,并全仓机械重排
三件事:

1) tools\Install-TestDependencies.ps1 现在也把 PSScriptAnalyzer 装进仓库内的 .tools\modules
(不动机器上的全局模块,与 Pester 同一策略)。

2) PSScriptAnalyzerSettings.psd1:这是必要的,不是装饰 —— 那 6 条格式规则
(括号、缩进、空格、对齐、大小写)默认全是 Disabled,所以不带 -Settings 的
`Invoke-ScriptAnalyzer -Severity Warning,Error` 会**静默漏掉全部排版问题**。本文件用 Rules
把它们打开(而不是用 IncludeRules 换一套),于是默认规则与格式规则同时生效。
三条有意的排除都写明了理由:PSAvoidUsingWriteHost(彩色控制台输出是这份工具的刻意设计)、
PSUseShouldProcessForStateChangingFunctions(WhatIf 的边界在入口脚本,给库里 27 个改状态的
函数都加上反而会"静默跳过",备份看着成功却什么都没做)、PSAvoidUsingPlainTextForPassword
(7z 只接受命令行口令,这是 7z 的限制,README 里写明了取舍)。

3) tools\Invoke-Analyzer.ps1:独立门禁(不塞进 Pester 用例 —— 套件跑一次二十多秒,
混进去会让"测试红了"这句话失去分辨力),路径过滤与验收门槛的 Encode/Parse 两层一致。

全仓重排结果:706 条告警 -> 67 条。修掉的 639 条全部是格式(闭括号 168、空格 80、
对齐 68、缩进 60、行长 229)。重排后 9/9 验收全绿、100 个文件两版解析零错、
276 个断言原样通过 —— 机械重排没有改变任何可观察行为。

如实说明两件事:

  * 行长上限设成 160,**不是**官方默认的 120。120 在本仓库意味着 270 处改动(主要是
    中文注释与测试夹具里的一行式目录),160 意味着 41 处。160 仍是"宽但可读",而理由是写在
    配置文件里的:这不是悄悄放宽,想收紧到 120 时那份清单就在分析器输出里。

  * 剩余 67 条里,41 条是上面那批行长,其余 26 条是分析器找出的真问题(未使用参数 6、
    空 catch 6、MD5 指纹 1、覆盖内置命令 1、switch 默认值 1 等)。其中
    Find-ChildDirectoryByName 的 MaxDepth 参数从未被使用 —— 也就是配置里的
    CatalogMaxDepth = 5 是假的,前缀补全实际只查 1 层。这条要改行为、且影响真实名录的解析
    结果,留给你拍板,不在本提交里动手。
2026-09-27 09:46:08 +08:00

232 lines
8.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.
<#
.SYNOPSIS
软件目录清单(SoftwareCatalog)。
.DESCRIPTION
定义每个软件在归档内的槽位(Slot)结构,供备份与恢复共用。
一个软件 = 一个归档(归档名就是软件名),包内的顶层目录就是这里定义的 Slot。
结构:
SoftWareName = @{
Slot = @{
Path = 'Absolute\Path'
Exclude = 'Relative\Path'
Include = 'Relative\Path:Absolute\Path'
Encrypt = $false
Description = 'Some information about this slot.'
}
}
.NOTES
字段说明:
SoftWareName 软件名称。不含空格,遵循驼峰大小写。
Slot 插槽。归档内的一层目录:内容进 `<Slot>\`;
Path 是文件时,存成名为 `<Slot>` 的文件本身。
同一软件里不能有两个同名 Slot。规则同 SoftWareName。
Path 路径。需备份或恢复的来源路径,为宿主机上的绝对路径。
Exclude 排除。不需备份的目录,为压缩包内的相对路径。
多个以逗号分隔。相对于本 Slot 的根(即归档内的 `<Slot>\`)。
以“!”打头即“任意层级匹配”(7z 的 -xr!,通配符 `*` / `?`);
要按正则排除写成 `!re:<正则>`(脚本自己展开成精确路径)。
Include 包含。需要追加的目录。
语法:<压缩包内相对路径>:<宿主机绝对路径>。
多个以逗号分隔。
Encrypt 是否加密此归档。默认:$false。
同一个条目里各 Slot 不一致时,整个归档按加密处理。
Description 描述。
#>
@{
AutoDarkMode = @{
DefaultData = @{
Path = '%AppData%\AutoDarkMode'
Encrypt = $true
Description = 'AutoDarkMode 数据。'
}
}
DeepSeekHarness = @{
DefaultData = @{
Path = '%UserProfile%\.dsh'
Encrypt = $true
Description = 'DSH(深度求索)数据。'
}
}
DSHDesktop = @{
DefaultData = @{
Path = '%AppData%\dsh-desktop'
Encrypt = $true
Description = 'DSH 桌面版数据。'
}
}
MicrosoftEdge = @{
DefaultData = @{
Path = '%LocalAppData%\Microsoft\Edge\User Data'
Exclude = '!*Cache,!BrowserMetrics,!component_crx_cache,' +
'!Crashpad,!optimization_guide,!ProvenanceData,' +
'Default\ExtensionActivityEdge,Default\Extensions,Default\Service Worker,' +
'Snapshots,Edge Sidebar,Edge Shopping'
Encrypt = $true
Description = '微软 Edge 浏览器用户数据。
保留:书签/密码/偏好/历史,以及站点数据(IndexedDB / Local Storage)。
排除:缓存、组件缓存、Service Worker、扩展本体(可从商店重装)、遥测与优化数据。
可选排除:Default\IndexedDB、Default\Local Storage、Default\Session Storage、Default\blob_storage、Default\WebStorage。
注意:Edge 常驻时打包会有上百个文件读不到(含 Login Data / Cookies),脚本检测到警告后不会用这份不完整的归档覆盖已有的完整归档。备份前建议先退出 Edge。'
}
}
FastNodeManager = @{
DefaultData = @{
Path = '%UserProfile%\fnm'
Encrypt = $true
Description = 'FNM(Node 版本管理器)数据。'
}
}
INZONEHub = @{
DefaultData = @{
Path = '%AppData%\Sony\INZONE Hub'
Description = '索尼英纵数据。'
}
}
Kazumi = @{
DefaultData = @{
Path = '%AppData%\com.example\Kazumi'
Encrypt = $true
Description = 'Kazumi 数据。'
}
}
Legendary = @{
DefaultConfig = @{
Path = '%UserProfile%\.config\legendary'
Encrypt = $true
Description = 'Legendary(Epic 的开源客户端)的配置。'
}
}
Mnemon = @{
DefaultData = @{
Path = '%UserProfile%\.mnemon'
Encrypt = $true
Description = 'Mnemon(LLM 智能体的持久记忆系统)数据。'
}
}
Obsidian = @{
DefaultData = @{
Path = '%AppData%\obsidian'
Encrypt = $true
Description = 'Obsidian 数据。'
}
}
OpenCode = @{
DefaultConfig = @{
Path = '%UserProfile%\.config\opencode'
Encrypt = $true
Description = 'OpenCode 的配置。'
}
}
OpenSSH = @{
DefaultData = @{
Path = '%UserProfile%\.ssh'
Encrypt = $true
Description = 'SSH 私钥 / 公钥 / known_hosts 等文件。'
}
}
PiliPlus = @{
DefaultData = @{
Path = '%AppData%\com.example\piliplus'
Encrypt = $true
Description = 'PiliPlus 数据。'
}
}
PowerShell = @{
DefaultData = @{
Path = '%UserProfile%\Documents\PowerShell'
Encrypt = $true
Description = 'PowerShell 7 的用户配置与模块。'
}
}
PowerToys = @{
DefaultBackup = @{
Path = '%UserProfile%\Documents\PowerToys\Backup'
Encrypt = $true
Description = 'PowerToys 备份。'
}
}
Scoop = @{
DefaultConfig = @{
Path = '%UserProfile%\.config\scoop'
Encrypt = $true
Description = 'Scoop 配置。'
}
GlobalPersist = @{
Path = '$(if ($env:SCOOP_GLOBAL) { $env:SCOOP_GLOBAL } else { Join-Path $env:ProgramData "scoop" })\persist'
Encrypt = $true
Description = 'Scoop 里各全局应用的持久化数据。'
}
UserPersist = @{
Path = '$(if ($env:SCOOP) { $env:SCOOP } else { Join-Path $env:USERPROFILE "scoop" })\persist'
Encrypt = $true
Description = 'Scoop 里各用户应用的持久化数据。'
}
}
Startup = @{
GlobalLink = @{
Path = '%ProgramData%\Microsoft\Windows\Start Menu\Programs\Startup'
Description = '全局开机启动项(快捷方式)。'
}
UserLink = @{
Path = '%AppData%\Microsoft\Windows\Start Menu\Programs\Startup'
Description = '用户开机启动项(快捷方式)。'
}
}
SteamRomManager = @{
DefaultData = @{
Path = '%AppData%\steam-rom-manager'
Description = 'Steam Rom Manager 数据。'
}
}
TranslucentTB = @{
ScoopData = @{
Path = '$(scoop prefix translucenttb)\settings.json'
Description = 'TranslucentTB 的设置文件(Scoop 安装)。'
}
}
TwinkleTray = @{
DefaultData = @{
Path = '%AppData%\twinkle-tray'
Description = 'Twinkle Tray 数据。'
}
}
WindowsPowerShell = @{
DefaultData = @{
Path = '%UserProfile%\Documents\WindowsPowerShell'
Encrypt = $true
Description = 'Windows PowerShell 5.1 的用户配置与模块。'
}
}
WindowsTerminal = @{
DefaultData = @{
Path = '%LocalAppData%\Packages\Microsoft.WindowsTerminal_8wekyb3d8bbwe\LocalState\settings.json'
Encrypt = $true
Description = 'Windows Terminal 的设置文件。'
}
}
}