mirror of
https://github.com/GeWuYou/GFramework.git
synced 2026-05-09 10:19:00 +08:00
refactor(game): 收敛版本化迁移运行器长方法 warning
- 重构 VersionedMigrationRunner 的迁移主循环,拆分版本校验、迁移解析与结果校验 helper - 更新 analyzer warning reduction 的 active tracking 与 trace,记录新的 649 条根构建基线
This commit is contained in:
parent
be26640b58
commit
1b85b53292
@ -92,11 +92,7 @@ internal static class VersionedMigrationRunner
|
||||
ArgumentException.ThrowIfNullOrWhiteSpace(migrationKind);
|
||||
|
||||
var currentVersion = getVersion(data);
|
||||
if (currentVersion > targetVersion)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{subjectName} is version {currentVersion}, which is newer than the current runtime version {targetVersion}.");
|
||||
}
|
||||
EnsureRuntimeVersionIsSupported(currentVersion, targetVersion, subjectName);
|
||||
|
||||
if (currentVersion == targetVersion)
|
||||
{
|
||||
@ -107,43 +103,148 @@ internal static class VersionedMigrationRunner
|
||||
|
||||
while (currentVersion < targetVersion)
|
||||
{
|
||||
var migration = resolveMigration(currentVersion);
|
||||
if (migration is null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"No {migrationKind} is registered for {subjectName} from version {currentVersion}.");
|
||||
}
|
||||
|
||||
current = applyMigration(migration, current)
|
||||
?? throw new InvalidOperationException(
|
||||
$"{migrationKind} for {subjectName} from version {currentVersion} returned null.");
|
||||
|
||||
var migratedVersion = getVersion(current);
|
||||
var declaredTargetVersion = getToVersion(migration);
|
||||
|
||||
if (declaredTargetVersion != migratedVersion)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{migrationKind} for {subjectName} declared target version {declaredTargetVersion} " +
|
||||
$"but returned version {migratedVersion}.");
|
||||
}
|
||||
|
||||
if (migratedVersion <= currentVersion)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{migrationKind} for {subjectName} must advance beyond version {currentVersion}.");
|
||||
}
|
||||
|
||||
if (migratedVersion > targetVersion)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{migrationKind} for {subjectName} produced version {migratedVersion}, " +
|
||||
$"which exceeds the current runtime version {targetVersion}.");
|
||||
}
|
||||
|
||||
currentVersion = migratedVersion;
|
||||
var migration = GetRequiredMigration(resolveMigration, currentVersion, subjectName, migrationKind);
|
||||
var result = ApplyMigrationStep(
|
||||
migration,
|
||||
current,
|
||||
currentVersion,
|
||||
targetVersion,
|
||||
getVersion,
|
||||
getToVersion,
|
||||
applyMigration,
|
||||
subjectName,
|
||||
migrationKind);
|
||||
current = result.Data;
|
||||
currentVersion = result.Version;
|
||||
}
|
||||
|
||||
return current;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 拒绝比当前运行时更高的数据版本,避免迁移器在未知版本上继续执行。
|
||||
/// </summary>
|
||||
/// <param name="currentVersion">数据当前版本。</param>
|
||||
/// <param name="targetVersion">运行时支持的目标版本。</param>
|
||||
/// <param name="subjectName">迁移主体名称。</param>
|
||||
/// <exception cref="InvalidOperationException">数据版本高于运行时版本时抛出。</exception>
|
||||
private static void EnsureRuntimeVersionIsSupported(int currentVersion, int targetVersion, string subjectName)
|
||||
{
|
||||
if (currentVersion > targetVersion)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{subjectName} is version {currentVersion}, which is newer than the current runtime version {targetVersion}.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析当前版本必须存在的下一步迁移器,避免在调用循环中重复拼接相同错误。
|
||||
/// </summary>
|
||||
/// <typeparam name="TMigration">迁移描述类型。</typeparam>
|
||||
/// <param name="resolveMigration">迁移解析委托。</param>
|
||||
/// <param name="currentVersion">当前版本。</param>
|
||||
/// <param name="subjectName">迁移主体名称。</param>
|
||||
/// <param name="migrationKind">迁移类别名称。</param>
|
||||
/// <returns>已解析的迁移器。</returns>
|
||||
/// <exception cref="InvalidOperationException">缺少迁移器时抛出。</exception>
|
||||
private static TMigration GetRequiredMigration<TMigration>(
|
||||
Func<int, TMigration?> resolveMigration,
|
||||
int currentVersion,
|
||||
string subjectName,
|
||||
string migrationKind)
|
||||
{
|
||||
var migration = resolveMigration(currentVersion);
|
||||
if (migration is null)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"No {migrationKind} is registered for {subjectName} from version {currentVersion}.");
|
||||
}
|
||||
|
||||
return migration;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 执行单步迁移并验证声明目标版本、结果版本与运行时上限之间的一致性。
|
||||
/// </summary>
|
||||
/// <typeparam name="TData">迁移数据类型。</typeparam>
|
||||
/// <typeparam name="TMigration">迁移描述类型。</typeparam>
|
||||
/// <param name="migration">当前步骤的迁移器。</param>
|
||||
/// <param name="current">迁移前数据。</param>
|
||||
/// <param name="currentVersion">迁移前版本。</param>
|
||||
/// <param name="targetVersion">运行时目标版本。</param>
|
||||
/// <param name="getVersion">数据版本读取委托。</param>
|
||||
/// <param name="getToVersion">迁移器目标版本读取委托。</param>
|
||||
/// <param name="applyMigration">迁移执行委托。</param>
|
||||
/// <param name="subjectName">迁移主体名称。</param>
|
||||
/// <param name="migrationKind">迁移类别名称。</param>
|
||||
/// <returns>迁移后的数据与新版本号。</returns>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// 迁移结果为空、声明目标版本不匹配、版本未前进或超出运行时版本时抛出。
|
||||
/// </exception>
|
||||
private static (TData Data, int Version) ApplyMigrationStep<TData, TMigration>(
|
||||
TMigration migration,
|
||||
TData current,
|
||||
int currentVersion,
|
||||
int targetVersion,
|
||||
Func<TData, int> getVersion,
|
||||
Func<TMigration, int> getToVersion,
|
||||
Func<TMigration, TData, TData> applyMigration,
|
||||
string subjectName,
|
||||
string migrationKind)
|
||||
where TData : class
|
||||
{
|
||||
var migratedData = applyMigration(migration, current)
|
||||
?? throw new InvalidOperationException(
|
||||
$"{migrationKind} for {subjectName} from version {currentVersion} returned null.");
|
||||
var migratedVersion = getVersion(migratedData);
|
||||
ValidateMigrationResult(
|
||||
currentVersion,
|
||||
targetVersion,
|
||||
migratedVersion,
|
||||
getToVersion(migration),
|
||||
subjectName,
|
||||
migrationKind);
|
||||
return (migratedData, migratedVersion);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 校验单步迁移结果与声明目标版本一致,并确保版本严格单调递增且不越过运行时版本。
|
||||
/// </summary>
|
||||
/// <param name="currentVersion">迁移前版本。</param>
|
||||
/// <param name="targetVersion">运行时目标版本。</param>
|
||||
/// <param name="migratedVersion">迁移后实际版本。</param>
|
||||
/// <param name="declaredTargetVersion">迁移器声明的目标版本。</param>
|
||||
/// <param name="subjectName">迁移主体名称。</param>
|
||||
/// <param name="migrationKind">迁移类别名称。</param>
|
||||
/// <exception cref="InvalidOperationException">
|
||||
/// 声明目标版本不匹配、版本未前进或超出运行时版本时抛出。
|
||||
/// </exception>
|
||||
private static void ValidateMigrationResult(
|
||||
int currentVersion,
|
||||
int targetVersion,
|
||||
int migratedVersion,
|
||||
int declaredTargetVersion,
|
||||
string subjectName,
|
||||
string migrationKind)
|
||||
{
|
||||
if (declaredTargetVersion != migratedVersion)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{migrationKind} for {subjectName} declared target version {declaredTargetVersion} " +
|
||||
$"but returned version {migratedVersion}.");
|
||||
}
|
||||
|
||||
if (migratedVersion <= currentVersion)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{migrationKind} for {subjectName} must advance beyond version {currentVersion}.");
|
||||
}
|
||||
|
||||
if (migratedVersion > targetVersion)
|
||||
{
|
||||
throw new InvalidOperationException(
|
||||
$"{migrationKind} for {subjectName} produced version {migratedVersion}, " +
|
||||
$"which exceeds the current runtime version {targetVersion}.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -6,38 +6,35 @@
|
||||
|
||||
## 当前恢复点
|
||||
|
||||
- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-066`
|
||||
- 当前阶段:`Phase 66`
|
||||
- 恢复点编号:`ANALYZER-WARNING-REDUCTION-RP-067`
|
||||
- 当前阶段:`Phase 67`
|
||||
- 当前焦点:
|
||||
- `2026-04-25` 已先提交 `6a704f3` `fix(analyzer): 固化沙箱外验证并清理测试噪音`,把 AGENTS / active ai-plan 真值修正与 4 文件测试噪音批次一起收口
|
||||
- 当前单文件批次聚焦 `GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs`,已收敛 4 个根构建直接确认的 `MA0051`
|
||||
- 提权后的直接仓库根基线已从 `656 Warning(s)` 降至 `652 Warning(s)`,说明本轮单文件批次有效
|
||||
- `GFramework.Game.Tests` 的直接受影响 Release build 当前为 `0 Warning(s)`、`0 Error(s)`
|
||||
- 本批次落地后,branch diff 相对 `origin/main` 将从 `7 files` 推进到 `8 files`,仍显著低于 `$gframework-batch-boot 50` 阈值
|
||||
- `2026-04-25` 已连续提交 `6a704f3` `fix(analyzer): 固化沙箱外验证并清理测试噪音` 与 `be26640` `test(game-tests): 收敛热重载长方法 warning`
|
||||
- 当前单文件批次聚焦 `GFramework.Game/Internal/VersionedMigrationRunner.cs`,通过拆分迁移主循环中的职责收敛根构建直接确认的 `MA0051`
|
||||
- 提权后的直接仓库根基线已从 `652 Warning(s)` 降至 `649 Warning(s)`,说明本轮 runtime 单文件批次继续有效
|
||||
- `GFramework.Game` 的直接受影响 `Release` build 当前为 `0 Warning(s)`、`0 Error(s)`
|
||||
- 本轮只新增 1 个源码唯一文件,branch diff 仍显著低于 `$gframework-batch-boot 50` 阈值
|
||||
|
||||
## 当前活跃事实
|
||||
|
||||
- 当前 `origin/main` 基线提交为 `4ad880c`(`2026-04-25T14:35:38+08:00`)。
|
||||
- `6a704f3` 落地后,当前 committed branch diff 相对 `origin/main` 为:
|
||||
- `git diff --name-only origin/main...HEAD | wc -l`:`7`
|
||||
- `git diff --numstat origin/main...HEAD`:累计 `104` added、`123` deleted
|
||||
- 提权后的直接仓库根验证当前确认为:
|
||||
- `dotnet clean`
|
||||
- 结果:成功;此前沙箱内 “Build FAILED but 0 errors” 的 clean 结果不是仓库真值
|
||||
- `dotnet build`
|
||||
- 最新结果:成功;`652 Warning(s)`、`0 Error(s)`
|
||||
- 最新结果:成功;`649 Warning(s)`、`0 Error(s)`
|
||||
- 已提交的低风险批次文件:
|
||||
- `AGENTS.md`
|
||||
- `GFramework.Ecs.Arch.Tests/Ecs/EcsAdvancedTests.cs`
|
||||
- `GFramework.Game.Tests/Config/GameConfigBootstrapTests.cs`
|
||||
- `GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs`
|
||||
- `GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs`
|
||||
- `GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs`
|
||||
- `GFramework.Game/Internal/VersionedMigrationRunner.cs`
|
||||
- `ai-plan/public/analyzer-warning-reduction/todos/analyzer-warning-reduction-tracking.md`
|
||||
- `ai-plan/public/analyzer-warning-reduction/traces/analyzer-warning-reduction-trace.md`
|
||||
- 当前待提交批次文件:
|
||||
- `GFramework.Game.Tests/Config/YamlConfigLoaderTests.cs`
|
||||
- 当前批次验证结果:
|
||||
- `dotnet build GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release`
|
||||
- `dotnet build GFramework.Game/GFramework.Game.csproj -c Release`
|
||||
- 最新主线程结果:成功;`0 Warning(s)`、`0 Error(s)`
|
||||
|
||||
## 当前风险
|
||||
@ -66,16 +63,12 @@
|
||||
- `dotnet clean`
|
||||
- 当前结果:成功;在提权后的直接 shell 中可正常完成仓库根 clean
|
||||
- `dotnet build`
|
||||
- 当前结果:成功;`652 Warning(s)`、`0 Error(s)`
|
||||
- `dotnet build GFramework.Game.Tests/GFramework.Game.Tests.csproj -c Release`
|
||||
- 当前结果:成功;`649 Warning(s)`、`0 Error(s)`
|
||||
- `dotnet build GFramework.Game/GFramework.Game.csproj -c Release`
|
||||
- 当前结果:成功;`0 Warning(s)`、`0 Error(s)`
|
||||
- `git diff --name-only origin/main...HEAD | wc -l`
|
||||
- 当前结果:`7`
|
||||
- `git diff --numstat origin/main...HEAD`
|
||||
- 当前结果:累计 `104` added、`123` deleted
|
||||
|
||||
## 下一步建议
|
||||
|
||||
1. 提交当前 `YamlConfigLoaderTests.cs` 单文件批次后,继续按 `$gframework-batch-boot 50` 规则重算 branch diff,并挑选下一个 1-3 文件的低风险热点。
|
||||
2. 下一轮优先从 `GFramework.Cqrs.Tests` 或 `GFramework.Game` 中继续选择单文件 `MA0051` / 测试噪音切片,避免过早推高 review 范围。
|
||||
1. 以当前 `649 Warning(s)` 根基线为新恢复点,继续按 `$gframework-batch-boot 50` 规则重算 branch diff,并挑选下一个 1-3 文件的低风险热点。
|
||||
2. 下一轮优先从 `GFramework.Cqrs.Tests` 或 `GFramework.Game` 中继续选择单文件 `MA0051`、`MA0016` 或测试噪音切片,避免过早推高 review 范围。
|
||||
3. 后续凡是沙箱内 `.NET` 验证再次出现无诊断失败、pipe/socket 权限问题或与普通 shell 不一致的结果,直接申请沙箱外重跑同一命令,不再扩散 workaround 型命令噪音。
|
||||
|
||||
@ -1,5 +1,28 @@
|
||||
# Analyzer Warning Reduction 追踪
|
||||
|
||||
## 2026-04-25 — RP-067
|
||||
|
||||
### 阶段:收口 Game runtime 单文件长方法切片,并继续压低根构建 warning 基线
|
||||
|
||||
- 触发背景:
|
||||
- `RP-066` 收尾后,当前分支已通过 `be26640` 把 `YamlConfigLoaderTests.cs` 的 4 个 `MA0051` 落地,仓库根基线降到 `652 Warning(s)`
|
||||
- 主线程随后切到 `GFramework.Game/Internal/VersionedMigrationRunner.cs`,继续挑选单文件、低风险、可独立验证的 runtime warning 切片
|
||||
- 主线程实施:
|
||||
- 将 `MigrateToTargetVersion` 中的运行时版本校验、迁移解析、单步应用与结果一致性校验拆分为具名 helper
|
||||
- 为新增 helper 补齐 XML 注释,保持该共享迁移执行器的职责边界可读,并避免仅靠机械拆分留下语义不清的私有方法
|
||||
- 保持外部行为不变,只收敛长方法 warning,不扩展到存储或日志相关调用方
|
||||
- 验证里程碑:
|
||||
- `dotnet clean`
|
||||
- 结果:成功
|
||||
- `dotnet build`
|
||||
- 结果:成功;`649 Warning(s)`、`0 Error(s)`,相较 `RP-066` 的 `652` 再下降 `3`
|
||||
- `dotnet build GFramework.Game/GFramework.Game.csproj -c Release`
|
||||
- 结果:成功;`0 Warning(s)`、`0 Error(s)`
|
||||
- 当前结论:
|
||||
- `VersionedMigrationRunner.cs` 这个 runtime 单文件批次已被主线程收口,并继续压低仓库根 warning 基线
|
||||
- 本轮只新增 1 个源码唯一文件,branch diff 仍显著低于 `$gframework-batch-boot 50` 的主停止阈值
|
||||
- 下一轮可以继续挑选 `GFramework.Cqrs.Tests` 或 `GFramework.Game` 的单文件轻量切片,并保持主线程验证、subagent 并行探索的节奏
|
||||
|
||||
## 2026-04-25 — RP-066
|
||||
|
||||
### 阶段:主线程回收停滞的单文件批次,并继续压低根构建 warning 基线
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user