Skip to content

feat(config): 添加YAML配置文件的JSON Schema校验功能#211

Merged
GeWuYou merged 7 commits into
mainfrom
feat/yaml-schema-validation
Apr 12, 2026
Merged

feat(config): 添加YAML配置文件的JSON Schema校验功能#211
GeWuYou merged 7 commits into
mainfrom
feat/yaml-schema-validation

Conversation

@GeWuYou

@GeWuYou GeWuYou commented Apr 12, 2026

Copy link
Copy Markdown
Owner
  • 实现了YAML配置与JSON Schema的运行时校验能力
  • 支持嵌套对象、对象数组、标量数组的递归校验
  • 提供async和sync两种模式的schema文件加载解析
  • 实现跨表引用的收集与校验机制
  • 支持enum枚举值、引用约束和深层约束校验
  • 添加了multipleOf、uniqueItems、contains等高级校验功能
  • 实现了minProperties、maxProperties对象属性数量校验
  • 提供详细的错误诊断信息和路径定位功能

由 Sourcery 提供的摘要

向宿主公开面向主机的 YAML 模式验证和序列化工具,并将其接入到生成的配置绑定中。

新功能:

  • 在现有异步加载的基础上,新增对 YAML 配置模式的同步模式加载。
  • 引入可复用的 YAML 文本验证器 API,用于在保存时将 YAML 内容与 JSON Schema 进行验证。
  • 引入共享的 YAML 文本序列化器,为生成的配置提供一致的 camelCase 命名约定。
  • 为生成的配置绑定类扩展辅助方法,用于 YAML 序列化、模式路径解析以及 YAML 验证。

增强:

  • 将模式解析逻辑重构为共享的辅助工具,供同步和异步模式加载器共同使用。
  • 改进模式验证和源代码生成器工具的代码格式和文档注释。

测试:

  • 添加集成测试,确保生成的绑定能够公开串联到运行时行为的序列化和验证辅助方法。
  • 添加单元测试,覆盖新的 YAML 文本验证器入口及其错误报告语义。
  • 扩展源代码生成器测试,以断言在生成的绑定中存在新的辅助方法。
Original summary in English

Summary by Sourcery

Expose host-facing YAML schema validation and serialization utilities and wire them into generated config bindings.

New Features:

  • Add synchronous schema loading for YAML config schemas alongside existing async loading.
  • Introduce a reusable YAML text validator API for validating YAML content against JSON Schema at save-time.
  • Introduce a shared YAML text serializer with consistent camelCase conventions for generated configs.
  • Extend generated config binding classes with helpers for YAML serialization, schema path resolution, and YAML validation.

Enhancements:

  • Refactor schema parsing logic into a shared helper used by both sync and async schema loaders.
  • Improve code formatting and documentation comments for schema validation and source generator utilities.

Tests:

  • Add integration tests ensuring generated bindings expose serializer and validator helpers wired to runtime behavior.
  • Add unit tests covering the new YAML text validator entry points and their error reporting semantics.
  • Extend source generator tests to assert presence of new helper methods in generated bindings.

Summary by CodeRabbit

  • 新功能

    • 支持将配置对象序列化为 YAML(强制以换行结尾)。
    • 提供同步/异步的 YAML 文本验证入口,返回/抛出带诊断信息的错误,能根据模式文件更新时间刷新缓存。
    • 为生成的绑定添加配置目录与模式文件路径解析、序列化与验证辅助方法。
  • 修复 / 行为改进

    • 模式加载解析改为确定性引用顺序(引用表名按序排列)。
  • 测试

    • 增加单元与集成测试,覆盖序列化、路径解析、同步/异步验证、缺失/未知字段诊断及模式刷新场景。

- 实现了YAML配置与JSON Schema的运行时校验能力
- 支持嵌套对象、对象数组、标量数组的递归校验
- 提供async和sync两种模式的schema文件加载解析
- 实现跨表引用的收集与校验机制
- 支持enum枚举值、引用约束和深层约束校验
- 添加了multipleOf、uniqueItems、contains等高级校验功能
- 实现了minProperties、maxProperties对象属性数量校验
- 提供详细的错误诊断信息和路径定位功能
@sourcery-ai

sourcery-ai Bot commented Apr 12, 2026

Copy link
Copy Markdown

Reviewer's Guide

添加可复用的 YAML 文本验证与序列化工具,并将其接入生成的配置绑定中,基于 JSON Schema 为 YAML 配置提供同步/异步验证及相关路径辅助方法,同时重构 Schema 加载逻辑以支持同步与异步两种流程,并扩展这些行为的测试覆盖率。

通过生成绑定进行 YAML 验证的时序图

sequenceDiagram
    actor Host
    participant MonsterConfigBindings
    participant YamlConfigTextValidator
    participant YamlConfigSchemaValidator
    participant FileSystem
    participant YamlConfigSchema

    Host->>MonsterConfigBindings: ValidateYaml(configRootPath, yamlPath, yamlText)
    MonsterConfigBindings->>MonsterConfigBindings: GetSchemaPath(configRootPath)
    MonsterConfigBindings->>YamlConfigTextValidator: Validate(Metadata.TableName, schemaPath, yamlPath, yamlText)

    YamlConfigTextValidator->>YamlConfigSchemaValidator: Load(tableName, schemaPath)
    YamlConfigSchemaValidator->>FileSystem: File.Exists(schemaPath)
    alt schemaFileMissing
        YamlConfigSchemaValidator-->>YamlConfigTextValidator: throw ConfigLoadException(SchemaFileNotFound)
        YamlConfigTextValidator-->>MonsterConfigBindings: exception
        MonsterConfigBindings-->>Host: exception
    else schemaFileExists
        YamlConfigSchemaValidator->>FileSystem: File.ReadAllText(schemaPath)
        YamlConfigSchemaValidator->>YamlConfigSchemaValidator: ParseLoadedSchema(tableName, schemaPath, schemaText)
        YamlConfigSchemaValidator-->>YamlConfigTextValidator: YamlConfigSchema
        YamlConfigTextValidator->>YamlConfigSchemaValidator: Validate(tableName, schema, yamlPath, yamlText)
        alt yamlInvalid
            YamlConfigSchemaValidator-->>YamlConfigTextValidator: throw ConfigLoadException(FailureKind)
            YamlConfigTextValidator-->>MonsterConfigBindings: exception
            MonsterConfigBindings-->>Host: exception
        else yamlValid
            YamlConfigSchemaValidator-->>YamlConfigTextValidator: success
            YamlConfigTextValidator-->>MonsterConfigBindings: return
            MonsterConfigBindings-->>Host: return
        end
    end

    rect rgb(235, 235, 255)
        note over Host,YamlConfigSchemaValidator: Async variant
        Host->>MonsterConfigBindings: ValidateYamlAsync(configRootPath, yamlPath, yamlText, cancellationToken)
        MonsterConfigBindings->>YamlConfigTextValidator: ValidateAsync(tableName, schemaPath, yamlPath, yamlText, cancellationToken)
        YamlConfigTextValidator->>YamlConfigSchemaValidator: LoadAsync(tableName, schemaPath, cancellationToken)
        YamlConfigSchemaValidator-->>YamlConfigTextValidator: YamlConfigSchema
        YamlConfigTextValidator->>YamlConfigSchemaValidator: Validate(tableName, schema, yamlPath, yamlText)
        YamlConfigSchemaValidator-->>YamlConfigTextValidator: success or ConfigLoadException
        YamlConfigTextValidator-->>MonsterConfigBindings: Task
        MonsterConfigBindings-->>Host: Task
    end
Loading

YAML 文本序列化与验证辅助类类图

classDiagram
    class MonsterConfigBindings {
        +const string SchemaRelativePath
        +const string ConfigRelativePath
        +static string SerializeToYaml(MonsterConfig config)
        +static string GetConfigDirectoryPath(string configRootPath)
        +static string GetSchemaPath(string configRootPath)
        +static void ValidateYaml(string configRootPath, string yamlPath, string yamlText)
        +static System.Threading.Tasks.Task ValidateYamlAsync(string configRootPath, string yamlPath, string yamlText, System.Threading.CancellationToken cancellationToken)
        -static string ResolveAbsolutePath(string configRootPath, string relativePath)
    }

    class MonsterConfig {
        +int Id
        +string Name
        +int Hp
        +string Faction
    }

    class YamlConfigTextSerializer {
        -static ISerializer Serializer
        +static string Serialize~TValue~(TValue value)
    }

    class YamlConfigTextValidator {
        +static void Validate(string tableName, string schemaPath, string yamlPath, string yamlText)
        +static System.Threading.Tasks.Task ValidateAsync(string tableName, string schemaPath, string yamlPath, string yamlText, System.Threading.CancellationToken cancellationToken)
    }

    class YamlConfigSchemaValidator {
        +static System.Threading.Tasks.Task~YamlConfigSchema~ LoadAsync(string tableName, string schemaPath, System.Threading.CancellationToken cancellationToken)
        +static YamlConfigSchema Load(string tableName, string schemaPath)
        +static void Validate(string tableName, YamlConfigSchema schema, string yamlPath, string yamlText)
        -static YamlConfigSchema ParseLoadedSchema(string tableName, string schemaPath, string schemaText)
    }

    class YamlConfigSchema {
        +string SchemaPath
        +YamlConfigSchemaNode RootNode
        +string[] ReferencedTableNames
    }

    class YamlConfigSchemaNode {
        +YamlConfigSchemaPropertyType NodeType
        +string SchemaPathHint
        +static YamlConfigSchemaNode CreateObject(System.Collections.Generic.IReadOnlyDictionary~string,YamlConfigSchemaNode~ properties, System.Collections.Generic.IReadOnlyCollection~string~ requiredProperties, YamlConfigObjectConstraints objectConstraints, string schemaPathHint)
        +static YamlConfigSchemaNode CreateArray(YamlConfigSchemaNode itemNode, YamlConfigArrayConstraints arrayConstraints, string schemaPathHint)
        +static YamlConfigSchemaNode CreateScalar(YamlConfigSchemaPropertyType nodeType, string referenceTableName, System.Collections.Generic.IReadOnlyCollection~string~ allowedValues, YamlConfigScalarConstraints constraints, string schemaPathHint)
    }

    class YamlConfigObjectConstraints
    class YamlConfigArrayConstraints
    class YamlConfigScalarConstraints
    class YamlConfigSchemaPropertyType

    class ConfigLoadException {
        +ConfigLoadDiagnostic Diagnostic
    }

    class ConfigLoadDiagnostic {
        +string TableName
        +string SchemaPath
        +string YamlPath
        +ConfigLoadFailureKind FailureKind
    }

    class ConfigLoadFailureKind

    MonsterConfigBindings ..> MonsterConfig : uses
    MonsterConfigBindings ..> YamlConfigTextSerializer : calls
    MonsterConfigBindings ..> YamlConfigTextValidator : calls
    YamlConfigTextValidator ..> YamlConfigSchemaValidator : calls
    YamlConfigSchemaValidator --> YamlConfigSchema : creates
    YamlConfigSchema --> YamlConfigSchemaNode : rootNode
    YamlConfigSchemaNode ..> YamlConfigObjectConstraints : uses
    YamlConfigSchemaNode ..> YamlConfigArrayConstraints : uses
    YamlConfigSchemaNode ..> YamlConfigScalarConstraints : uses
    YamlConfigSchemaNode ..> YamlConfigSchemaPropertyType : uses
    YamlConfigSchemaValidator ..> ConfigLoadException : throws
    ConfigLoadException --> ConfigLoadDiagnostic : has
    ConfigLoadDiagnostic ..> ConfigLoadFailureKind : uses
    YamlConfigTextSerializer ..> ISerializer : uses
    YamlConfigTextSerializer ..> CamelCaseNamingConvention : uses
    YamlConfigTextSerializer ..> DefaultValuesHandling : uses
Loading

文件级变更

Change Details Files
引入可复用的 YAML 文本验证与序列化工具,并将其接入生成的绑定,在保存前进行基于 Schema 的验证。
  • 添加 YamlConfigTextValidator,提供同步与异步方法,通过 YamlConfigSchemaValidator 加载 JSON Schema,并使用现有运行时规则验证 YAML 文本。
  • 添加 YamlConfigTextSerializer,使用 YamlDotNet(驼峰命名、禁用 alias、保留默认值),确保序列化后的 YAML 以换行结尾。
  • 扩展生成的绑定(例如 MonsterConfigBindings),对外暴露 SerializeToYaml、GetConfigDirectoryPath、GetSchemaPath、ValidateYaml 和 ValidateYamlAsync 等辅助方法,并提供共享的 ResolveAbsolutePath 实现。
GFramework.Game/Config/YamlConfigTextValidator.cs
GFramework.Game/Config/YamlConfigTextSerializer.cs
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
重构 JSON Schema 加载逻辑,以支持共享的解析路径,并在现有异步加载器之外增加同步 Schema 加载。
  • 抽取 ParseLoadedSchema,用于封装 JSON 解析、根节点校验、引用收集以及构造 YamlConfigSchema,并保证错误处理一致。
  • 在 YamlConfigSchemaValidator 中新增同步的 Load 方法,从磁盘读取 Schema 文件,提供健壮的错误报告,并委托给 ParseLoadedSchema 进行处理。
  • 更新 LoadAsync,使其在解析 Schema 文本时同样委托给 ParseLoadedSchema,从而统一同步与异步路径的行为。
GFramework.Game/Config/YamlConfigSchemaValidator.cs
加强集成测试,并为生成的辅助方法和 YAML 文本验证流程新增测试。
  • 更新 GeneratedConfigConsumerIntegrationTests,使用字段初始化的根路径,并断言新绑定辅助方法的行为(序列化、schema/config 路径解析,以及同步/异步验证)。
  • 添加 YamlConfigTextValidatorTests,验证合法 YAML 能通过验证,结构问题会作为带有正确诊断信息的 ConfigLoadException 暴露,且异步验证语义与同步一致。
  • 扩展 SchemaConfigGeneratorTests,断言生成的绑定源码包含新的辅助方法和引用。
GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
对现有验证器与 Schema 节点类型进行轻微的格式与顺序调整,以提升可读性与一致性。
  • 在 YamlConfigSchemaValidator 中重新格式化较长的插值字符串、LINQ 表达式和 switch 分支,以统一对齐和换行风格。
  • 在 YamlConfigSchemaNode 及其嵌套类型中,将静态工厂方法和静态 None 实例移动到实例成员之后,并调整 XML 文档注释的缩进。
  • 整理若干测试文件中的 using 指令与断言格式,以提升清晰度。
GFramework.Game/Config/YamlConfigSchemaValidator.cs
GFramework.Game/Config/YamlConfigSchemaValidator.cs
GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs

Tips and commands

Interacting with Sourcery

  • 触发新评审: 在 pull request 中评论 @sourcery-ai review
  • 继续讨论: 直接回复 Sourcery 的评审评论。
  • 从评审评论生成 GitHub issue: 在某条评审评论下请求 Sourcery 从该评论创建 issue。你也可以直接回复该评论 @sourcery-ai issue 来创建对应的 issue。
  • 生成 pull request 标题: 在 PR 标题任意位置写上 @sourcery-ai,即可随时生成标题。你也可以在 PR 中评论 @sourcery-ai title 来(重新)生成标题。
  • 生成 pull request 摘要: 在 PR 正文任意位置写上 @sourcery-ai summary,即可在指定位置生成 PR 摘要。你也可以在 PR 中评论 @sourcery-ai summary 来(重新)生成摘要。
  • 生成 Reviewer's Guide: 在 pull request 中评论 @sourcery-ai guide,即可(重新)生成本评审指南。
  • 一次性解决所有 Sourcery 评论: 在 pull request 中评论 @sourcery-ai resolve,将所有 Sourcery 评论标记为已解决。适用于你已处理完所有评论且不希望继续看到它们的情况。
  • 清除所有 Sourcery 评审: 在 pull request 中评论 @sourcery-ai dismiss,以清除所有现有的 Sourcery 评审。特别适用于你希望从头开始新的评审——别忘了再评论 @sourcery-ai review 触发新评审!

Customizing Your Experience

访问你的 dashboard 可以:

  • 启用或禁用评审功能,例如 Sourcery 自动生成的 pull request 摘要、本评审指南等。
  • 更改评审语言。
  • 添加、删除或编辑自定义评审说明。
  • 调整其他评审相关设置。

Getting Help

Original review guide in English

Reviewer's Guide

Adds reusable YAML text validation and serialization utilities wired into generated config bindings, exposing sync/async JSON Schema-based validation for YAML configs and associated path helpers, while refactoring schema loading to support both async and sync flows and expanding test coverage for these behaviors.

Sequence diagram for YAML validation via generated bindings

sequenceDiagram
    actor Host
    participant MonsterConfigBindings
    participant YamlConfigTextValidator
    participant YamlConfigSchemaValidator
    participant FileSystem
    participant YamlConfigSchema

    Host->>MonsterConfigBindings: ValidateYaml(configRootPath, yamlPath, yamlText)
    MonsterConfigBindings->>MonsterConfigBindings: GetSchemaPath(configRootPath)
    MonsterConfigBindings->>YamlConfigTextValidator: Validate(Metadata.TableName, schemaPath, yamlPath, yamlText)

    YamlConfigTextValidator->>YamlConfigSchemaValidator: Load(tableName, schemaPath)
    YamlConfigSchemaValidator->>FileSystem: File.Exists(schemaPath)
    alt schemaFileMissing
        YamlConfigSchemaValidator-->>YamlConfigTextValidator: throw ConfigLoadException(SchemaFileNotFound)
        YamlConfigTextValidator-->>MonsterConfigBindings: exception
        MonsterConfigBindings-->>Host: exception
    else schemaFileExists
        YamlConfigSchemaValidator->>FileSystem: File.ReadAllText(schemaPath)
        YamlConfigSchemaValidator->>YamlConfigSchemaValidator: ParseLoadedSchema(tableName, schemaPath, schemaText)
        YamlConfigSchemaValidator-->>YamlConfigTextValidator: YamlConfigSchema
        YamlConfigTextValidator->>YamlConfigSchemaValidator: Validate(tableName, schema, yamlPath, yamlText)
        alt yamlInvalid
            YamlConfigSchemaValidator-->>YamlConfigTextValidator: throw ConfigLoadException(FailureKind)
            YamlConfigTextValidator-->>MonsterConfigBindings: exception
            MonsterConfigBindings-->>Host: exception
        else yamlValid
            YamlConfigSchemaValidator-->>YamlConfigTextValidator: success
            YamlConfigTextValidator-->>MonsterConfigBindings: return
            MonsterConfigBindings-->>Host: return
        end
    end

    rect rgb(235, 235, 255)
        note over Host,YamlConfigSchemaValidator: Async variant
        Host->>MonsterConfigBindings: ValidateYamlAsync(configRootPath, yamlPath, yamlText, cancellationToken)
        MonsterConfigBindings->>YamlConfigTextValidator: ValidateAsync(tableName, schemaPath, yamlPath, yamlText, cancellationToken)
        YamlConfigTextValidator->>YamlConfigSchemaValidator: LoadAsync(tableName, schemaPath, cancellationToken)
        YamlConfigSchemaValidator-->>YamlConfigTextValidator: YamlConfigSchema
        YamlConfigTextValidator->>YamlConfigSchemaValidator: Validate(tableName, schema, yamlPath, yamlText)
        YamlConfigSchemaValidator-->>YamlConfigTextValidator: success or ConfigLoadException
        YamlConfigTextValidator-->>MonsterConfigBindings: Task
        MonsterConfigBindings-->>Host: Task
    end
Loading

Class diagram for YAML text serialization and validation helpers

classDiagram
    class MonsterConfigBindings {
        +const string SchemaRelativePath
        +const string ConfigRelativePath
        +static string SerializeToYaml(MonsterConfig config)
        +static string GetConfigDirectoryPath(string configRootPath)
        +static string GetSchemaPath(string configRootPath)
        +static void ValidateYaml(string configRootPath, string yamlPath, string yamlText)
        +static System.Threading.Tasks.Task ValidateYamlAsync(string configRootPath, string yamlPath, string yamlText, System.Threading.CancellationToken cancellationToken)
        -static string ResolveAbsolutePath(string configRootPath, string relativePath)
    }

    class MonsterConfig {
        +int Id
        +string Name
        +int Hp
        +string Faction
    }

    class YamlConfigTextSerializer {
        -static ISerializer Serializer
        +static string Serialize~TValue~(TValue value)
    }

    class YamlConfigTextValidator {
        +static void Validate(string tableName, string schemaPath, string yamlPath, string yamlText)
        +static System.Threading.Tasks.Task ValidateAsync(string tableName, string schemaPath, string yamlPath, string yamlText, System.Threading.CancellationToken cancellationToken)
    }

    class YamlConfigSchemaValidator {
        +static System.Threading.Tasks.Task~YamlConfigSchema~ LoadAsync(string tableName, string schemaPath, System.Threading.CancellationToken cancellationToken)
        +static YamlConfigSchema Load(string tableName, string schemaPath)
        +static void Validate(string tableName, YamlConfigSchema schema, string yamlPath, string yamlText)
        -static YamlConfigSchema ParseLoadedSchema(string tableName, string schemaPath, string schemaText)
    }

    class YamlConfigSchema {
        +string SchemaPath
        +YamlConfigSchemaNode RootNode
        +string[] ReferencedTableNames
    }

    class YamlConfigSchemaNode {
        +YamlConfigSchemaPropertyType NodeType
        +string SchemaPathHint
        +static YamlConfigSchemaNode CreateObject(System.Collections.Generic.IReadOnlyDictionary~string,YamlConfigSchemaNode~ properties, System.Collections.Generic.IReadOnlyCollection~string~ requiredProperties, YamlConfigObjectConstraints objectConstraints, string schemaPathHint)
        +static YamlConfigSchemaNode CreateArray(YamlConfigSchemaNode itemNode, YamlConfigArrayConstraints arrayConstraints, string schemaPathHint)
        +static YamlConfigSchemaNode CreateScalar(YamlConfigSchemaPropertyType nodeType, string referenceTableName, System.Collections.Generic.IReadOnlyCollection~string~ allowedValues, YamlConfigScalarConstraints constraints, string schemaPathHint)
    }

    class YamlConfigObjectConstraints
    class YamlConfigArrayConstraints
    class YamlConfigScalarConstraints
    class YamlConfigSchemaPropertyType

    class ConfigLoadException {
        +ConfigLoadDiagnostic Diagnostic
    }

    class ConfigLoadDiagnostic {
        +string TableName
        +string SchemaPath
        +string YamlPath
        +ConfigLoadFailureKind FailureKind
    }

    class ConfigLoadFailureKind

    MonsterConfigBindings ..> MonsterConfig : uses
    MonsterConfigBindings ..> YamlConfigTextSerializer : calls
    MonsterConfigBindings ..> YamlConfigTextValidator : calls
    YamlConfigTextValidator ..> YamlConfigSchemaValidator : calls
    YamlConfigSchemaValidator --> YamlConfigSchema : creates
    YamlConfigSchema --> YamlConfigSchemaNode : rootNode
    YamlConfigSchemaNode ..> YamlConfigObjectConstraints : uses
    YamlConfigSchemaNode ..> YamlConfigArrayConstraints : uses
    YamlConfigSchemaNode ..> YamlConfigScalarConstraints : uses
    YamlConfigSchemaNode ..> YamlConfigSchemaPropertyType : uses
    YamlConfigSchemaValidator ..> ConfigLoadException : throws
    ConfigLoadException --> ConfigLoadDiagnostic : has
    ConfigLoadDiagnostic ..> ConfigLoadFailureKind : uses
    YamlConfigTextSerializer ..> ISerializer : uses
    YamlConfigTextSerializer ..> CamelCaseNamingConvention : uses
    YamlConfigTextSerializer ..> DefaultValuesHandling : uses
Loading

File-Level Changes

Change Details Files
Introduce reusable YAML text validation and serialization utilities and wire them into generated bindings for schema-based validation before save.
  • Add YamlConfigTextValidator with sync and async methods that load JSON Schema via YamlConfigSchemaValidator and validate YAML text using the existing runtime rules.
  • Add YamlConfigTextSerializer that uses YamlDotNet with camelCase naming, alias disabling, and preserved default values, ensuring a trailing newline in serialized YAML.
  • Extend generated bindings (e.g., MonsterConfigBindings) to expose SerializeToYaml, GetConfigDirectoryPath, GetSchemaPath, ValidateYaml, and ValidateYamlAsync helpers, plus a shared ResolveAbsolutePath implementation.
GFramework.Game/Config/YamlConfigTextValidator.cs
GFramework.Game/Config/YamlConfigTextSerializer.cs
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
Refactor JSON Schema loading to support a shared parsing path and add synchronous schema loading alongside the existing async loader.
  • Extract ParseLoadedSchema to encapsulate JSON parsing, root node validation, reference collection, and YamlConfigSchema construction with consistent error handling.
  • Add a synchronous Load method to YamlConfigSchemaValidator that reads schema files from disk with robust error reporting and delegates to ParseLoadedSchema.
  • Update LoadAsync to delegate schema-text parsing to ParseLoadedSchema for consistency between sync and async paths.
GFramework.Game/Config/YamlConfigSchemaValidator.cs
Tighten integration tests and add new tests for generated helpers and YAML text validation flows.
  • Update GeneratedConfigConsumerIntegrationTests to use a field-initialized root path and to assert behavior of the new binding helpers (serialization, schema/config path resolution, and sync/async validation).
  • Add YamlConfigTextValidatorTests to verify that valid YAML passes validation, structural issues surface as ConfigLoadException with correct diagnostics, and async validation mirrors sync semantics.
  • Extend SchemaConfigGeneratorTests to assert that generated bindings source includes the new helper methods and references.
GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
Apply minor formatting and ordering adjustments to existing validators and schema node types for readability and consistency.
  • Reformat long interpolated strings, LINQ expressions, and switch arms in YamlConfigSchemaValidator for alignment and line-wrapping consistency.
  • Move static factory methods and static None instances in YamlConfigSchemaNode and its nested types to follow instance members consistently and adjust XML doc indentation.
  • Tidy using directives and assertion formatting in various test files for clarity.
GFramework.Game/Config/YamlConfigSchemaValidator.cs
GFramework.Game/Config/YamlConfigSchemaValidator.cs
GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@coderabbitai

coderabbitai Bot commented Apr 12, 2026

Copy link
Copy Markdown
Contributor

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

新增基于文本的 YAML 序列化与验证 API;引入同步/异步 schema 加载并抽取解析逻辑以保证引用表名的确定性排序;源生成器为每个生成的 ConfigBindings 添加 YAML 序列化/路径/验证辅助方法;新增多项单元与集成测试覆盖新行为与诊断。

Changes

Cohort / File(s) Summary
运行时 YAML 序列化/验证
GFramework.Game/Config/YamlConfigTextSerializer.cs, GFramework.Game/Config/YamlConfigTextValidator.cs
新增公共静态类 YamlConfigTextSerializer.Serialize<T>(验证非空、统一 YamlDotNet 配置并确保返回文本以 \n 结尾)和 YamlConfigTextValidator.Validate/ValidateAsync(缓存 schema 并基于文件时间戳刷新,委托到 YamlConfigSchemaValidator)。
同步 Schema 加载与解析重构
GFramework.Game/Config/YamlConfigSchemaValidator.cs
新增同步 Load(string tableName, string schemaPath),提取 ParseLoadedSchema(...) 并由 LoadAsync 复用;改进 JSON 解析错误映射与引用表名的确定性排序(OrderBy)。
源生成器与生成绑定扩展
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs, GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt, GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/GeneratedConfigCatalog.g.txt
生成器开始在每个 *ConfigBindings 中插入 YAML 辅助方法:SerializeToYamlGetConfigDirectoryPathGetSchemaPathValidateYamlValidateYamlAsync;并在 GeneratedConfigCatalog 中添加 ResolveAbsolutePath(string, string) 内部实现。
测试 — 集成与单元
GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs, GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs, GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs, GFramework.Game.Tests/Config/YamlConfigTextSerializerTests.cs
新增/扩展测试覆盖:生成绑定的序列化/路径/验证行为;YamlConfigTextValidator 的同步/异步检验及异常诊断字段;YamlConfigSchemaValidator.Load 的引用表名排序稳定性;YamlConfigTextSerializer 输出与 null 参数行为。
生成器测试断言更新
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
测试断言扩展,验证生成的绑定包含新增的 YAML 序列化/路径/验证公开 API(以及 GeneratedConfigCatalog.ResolveAbsolutePath 的生成)。
代码格式与小幅调整
GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
移除未使用 using、调整多处断言的换行/格式,并新增集成测试方法。

Sequence Diagram(s)

sequenceDiagram
    participant Test as 测试/调用者
    participant Generated as 生成的 Bindings
    participant Serializer as YamlConfigTextSerializer
    participant YamlLib as Yaml 库

    Test->>Generated: SerializeToYaml(config)
    Generated->>Serializer: Serialize<T>(config)
    Serializer->>YamlLib: 调用序列化(配置 CamelCase、禁用别名)
    YamlLib-->>Serializer: 返回 YAML 文本
    Serializer->>Serializer: 确保尾部有 "\n"
    Serializer-->>Generated: 返回 YAML 文本
    Generated-->>Test: 返回 YAML 文本
Loading
sequenceDiagram
    participant Test as 测试/调用者
    participant Generated as 生成的 Bindings
    participant TextValidator as YamlConfigTextValidator
    participant SchemaValidator as YamlConfigSchemaValidator
    participant FileSystem as 文件系统
    participant Parser as JSON 解析器

    Test->>Generated: ValidateYaml(configRoot, yamlPath, yamlText)
    Generated->>Generated: ResolveAbsolutePath(configRoot, relativeSchemaPath)
    Generated->>TextValidator: Validate(tableName, schemaPath, yamlPath, yamlText)
    TextValidator->>SchemaValidator: Load/LoadAsync(tableName, schemaPath)
    SchemaValidator->>FileSystem: 读取 schema 文件
    FileSystem-->>SchemaValidator: 返回 schema JSON 文本
    SchemaValidator->>Parser: 解析 JSON 并收集引用表名(并排序)
    Parser-->>SchemaValidator: 返回 YamlConfigSchema
    SchemaValidator-->>TextValidator: 返回 Schema
    TextValidator->>SchemaValidator: 验证 YAML 文本(或抛出 ConfigLoadException 包含 Diagnostic)
    SchemaValidator-->>TextValidator: 验证结果或异常
    TextValidator-->>Generated: 验证完成或抛出
    Generated-->>Test: 验证结果或异常
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed PR标题清晰准确地概括了主要变更:添加YAML配置文件的JSON Schema校验功能,与changeset的核心目标完全对应。
Docstring Coverage ✅ Passed Docstring coverage is 94.44% which is sufficient. The required threshold is 80.00%.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/yaml-schema-validation

Comment @coderabbitai help to get the list of available commands and usage tips.

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey - 我发现了 1 个问题,并留下了一些整体性的反馈:

  • YamlConfigTextValidator.Validate/ValidateAsync 在每次调用时都会加载并解析 schema 文件;如果这些辅助方法会在高频保存路径中被调用,建议考虑提供一个接受预加载好的 YamlConfigSchema 的重载,或者增加一个简单的缓存层,以避免对相同的表/Schema 路径进行重复的磁盘 IO 和 JSON 解析。
给 AI Agent 的提示词
Please address the comments from this code review:

## Overall Comments
- YamlConfigTextValidator.Validate/ValidateAsync load and parse the schema file on every call; if these helpers are used on hot save paths, consider exposing an overload that accepts a preloaded YamlConfigSchema or adding a simple caching layer to avoid repeated disk IO and JSON parsing for the same table/schema path.

## Individual Comments

### Comment 1
<location path="GFramework.Game/Config/YamlConfigTextSerializer.cs" line_range="8-12" />
<code_context>
+/// </summary>
+public static class YamlConfigTextSerializer
+{
+    private static readonly ISerializer Serializer = new SerializerBuilder()
+        .WithNamingConvention(CamelCaseNamingConvention.Instance)
+        .DisableAliases()
+        .ConfigureDefaultValuesHandling(DefaultValuesHandling.Preserve)
+        .Build();
+
+    /// <summary>
</code_context>
<issue_to_address>
**question (bug_risk):** 请澄清或验证共享 `Serializer` 实例在被多个调用方使用时的线程安全假设。

静态的 `Serializer` 实例会被所有调用 `Serialize` 的代码共享,包括来自多个线程的调用。这依赖于 `YamlDotNet``ISerializer` 对并发使用是安全的。

如果这一点没有被明确保证,要么在这里文档化该线程安全前提,要么改为每次调用(或使用对象池)创建独立的 serializer,以避免在这个共享辅助方法中出现隐蔽的并发问题。
</issue_to_address>

Sourcery 对开源项目是免费的——如果你喜欢我们的代码审查,请考虑分享它们 ✨
帮我变得更有用!请在每条评论上点击 👍 或 👎,我会根据你的反馈改进后续的审查。
Original comment in English

Hey - I've found 1 issue, and left some high level feedback:

  • YamlConfigTextValidator.Validate/ValidateAsync load and parse the schema file on every call; if these helpers are used on hot save paths, consider exposing an overload that accepts a preloaded YamlConfigSchema or adding a simple caching layer to avoid repeated disk IO and JSON parsing for the same table/schema path.
Prompt for AI Agents
Please address the comments from this code review:

## Overall Comments
- YamlConfigTextValidator.Validate/ValidateAsync load and parse the schema file on every call; if these helpers are used on hot save paths, consider exposing an overload that accepts a preloaded YamlConfigSchema or adding a simple caching layer to avoid repeated disk IO and JSON parsing for the same table/schema path.

## Individual Comments

### Comment 1
<location path="GFramework.Game/Config/YamlConfigTextSerializer.cs" line_range="8-12" />
<code_context>
+/// </summary>
+public static class YamlConfigTextSerializer
+{
+    private static readonly ISerializer Serializer = new SerializerBuilder()
+        .WithNamingConvention(CamelCaseNamingConvention.Instance)
+        .DisableAliases()
+        .ConfigureDefaultValuesHandling(DefaultValuesHandling.Preserve)
+        .Build();
+
+    /// <summary>
</code_context>
<issue_to_address>
**question (bug_risk):** Clarify or verify thread-safety assumptions of the shared `Serializer` instance used from multiple callers.

The static `Serializer` instance will be shared by all callers of `Serialize`, including from multiple threads. This relies on `YamlDotNet`’s `ISerializer` being safe for concurrent use.

If that’s not explicitly guaranteed, either document the thread-safety requirement here or switch to per-call (or pooled) serializers to avoid subtle concurrency issues in this shared helper.
</issue_to_address>

Sourcery is free for open source - if you like our reviews please consider sharing them ✨
Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.

Comment thread GFramework.Game/Config/YamlConfigTextSerializer.cs Outdated
- 集成YamlDotNet库实现YAML配置文件的序列化功能
- 在配置消费者集成测试中添加抽象配置接口引用
- 在YAML配置验证测试中添加抽象配置接口引用
- 统一配置模块的依赖注入和接口抽象层次

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 5

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs`:
- Around line 271-289: The async validation test only asserts the success path
for MonsterConfigBindings.ValidateYamlAsync but lacks a failing-branch
assertion; add an Assert.ThrowsAsync<ConfigLoadException> call that invokes
MonsterConfigBindings.ValidateYamlAsync(_rootPath, "monster/generated.yaml",
invalidYaml) (using the existing invalidYaml) and assert the thrown exception's
Diagnostic.SchemaPath and Diagnostic.FailureKind match the same expectations
used for the synchronous test (SchemaPath equals schemaPath and FailureKind
equals ConfigLoadFailureKind.UnknownProperty) to cover the async failure branch.

In `@GFramework.Game/Config/YamlConfigSchemaValidator.cs`:
- Around line 268-271: The current code builds referencedTableNames as a
HashSet<string> in CollectReferencedTableNames and passes
referencedTableNames.ToArray() into the YamlConfigSchema ctor, producing an
unstable iteration order; before creating the YamlConfigSchema, convert the set
to a stable ordered sequence (e.g., sort the entries using
StringComparer.Ordinal) and pass that sorted array to the YamlConfigSchema
constructor so the exported referenced table list is deterministic.

In `@GFramework.Game/Config/YamlConfigTextSerializer.cs`:
- Around line 14-20: 为公开方法 Serialize<TValue> 补充 XML 文档中的 <exception>
标签,明确说明该方法在何种情况下会抛出 ArgumentNullException(例如当传入的 value 为 null 或方法内部依赖的必需参数为 null
时),并在异常说明中给出简短的上下文(“当 value 为 null 时抛出”),将该 <exception> 元素添加到现有的
<summary>/<typeparam>/<param>/<returns> 注释中以满足文档要求。

In `@GFramework.Game/Config/YamlConfigTextValidator.cs`:
- Around line 8-43: Add full XML documentation to the public methods Validate
and ValidateAsync: include <summary> (existing), <param> entries for tableName,
schemaPath, yamlPath, yamlText and cancellationToken (for ValidateAsync), a
<returns> describing that ValidateAsync returns a Task that completes when
validation finishes, and <exception> tags listing the specific exceptions these
methods may throw (e.g. ArgumentNullException/ArgumentException for invalid
params, ConfigLoadException from YamlConfigSchemaValidator.Load/LoadAsync, and
OperationCanceledException for ValidateAsync when cancellationToken is
triggered). Also add a brief <remarks> note about synchronous vs asynchronous
behavior and mention that Validate delegates to
YamlConfigSchemaValidator.Validate and ValidateAsync calls LoadAsync before
validation.

In `@GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs`:
- Around line 1687-1765: 生成的 YAML helper 注释缺少 <exception> 标签:Update
AppendYamlSerializationHelpers so the generated docs for GetConfigDirectoryPath,
GetSchemaPath, ValidateYaml and ValidateYamlAsync include appropriate
<exception> entries (e.g. ArgumentNullException / ArgumentException for
invalid/null configRootPath and ArgumentNullException for null yamlText/yamlPath
where applicable). Locate AppendYamlSerializationHelpers in
SchemaConfigGenerator.cs and add builder.AppendLine(...) calls to emit
<exception> XML for each method (matching the runtime throws) directly beneath
the corresponding <param> blocks so the generated API docs reflect the actual
contract for GetConfigDirectoryPath, GetSchemaPath, ValidateYaml and
ValidateYamlAsync.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 61000ea9-1e64-4a30-a6f4-8f0e1d12559e

📥 Commits

Reviewing files that changed from the base of the PR and between 5e9a9de and 1fac276.

📒 Files selected for processing (8)
  • GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
  • GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
  • GFramework.Game/Config/YamlConfigSchemaValidator.cs
  • GFramework.Game/Config/YamlConfigTextSerializer.cs
  • GFramework.Game/Config/YamlConfigTextValidator.cs
  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
  • GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Code Quality & Security
  • GitHub Check: Analyze (C#)
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: LoggerGenerator must automatically generate log fields and logging helper methods for classes decorated with [Log] attribute
PriorityGenerator must generate priority comparison implementations for classes decorated with [Priority] attribute
EnumExtensionsGenerator must generate enum extension capabilities for enums decorated with [GenerateEnumExtensions] attribute
ContextAwareGenerator must automatically implement IContextAware boilerplate logic for classes decorated with [ContextAware] attribute

**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with <summary>, <param>, <returns>, <exception>, and <remarks> tags where applicable
XML documentation comments must explain intent, contract, and usage constraints instead of restating syntax
Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds, compatibility constraints, edge cases, registration order, lifecycle sequencing, and generated code assumptions
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interactions with other components, why the abstraction exists, and when to use it instead of alternatives
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling
Do not rely on implicit imports; declare every required using explicitly
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use namespace pattern GFramework.{Module}.{Feature} with PascalCase segments
Follow standard C# naming: Types/methods/properties/events/constants use PascalCase, interfaces use I prefix, parame...

Files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
  • GFramework.Game/Config/YamlConfigTextSerializer.cs
  • GFramework.Game/Config/YamlConfigTextValidator.cs
  • GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
  • GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
  • GFramework.Game/Config/YamlConfigSchemaValidator.cs
🧠 Learnings (11)
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Source generator changes MUST be covered by generator tests

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
  • GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
  • GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Preserve snapshot-based verification patterns already used in the repository for source generator tests

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
  • GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
  • GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Public API changes must be covered by unit or integration tests

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
  • GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
  • GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Regression fixes should include a test that fails before the fix and passes after it

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
  • GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
  • GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : When generator behavior changes intentionally, update snapshots together with the implementation

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Keep tests focused on observable behavior, not implementation trivia

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
  • GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : When a public API defines multiple contract branches, tests MUST cover the meaningful variants including null, empty, default, and filtered inputs when those branches change behavior

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Keep source generators deterministic and free of hidden environment or network dependencies

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.

Applied to files:

  • GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs
  • GFramework.Game/Config/YamlConfigTextSerializer.cs
  • GFramework.Game/Config/YamlConfigTextValidator.cs
  • GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
  • GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
  • GFramework.Game/Config/YamlConfigSchemaValidator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical

Applied to files:

  • GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs
🪛 GitHub Check: Build and Test
GFramework.Game/Config/YamlConfigTextSerializer.cs

[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)


[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)


[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)


[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)


[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)


[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)

🔇 Additional comments (4)
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs (1)

449-456: 这组新增断言很到位。

覆盖了新生成 API 的可见性契约(序列化、schema 路径、同步/异步校验),与当前生成器测试模式一致。

Based on learnings "Applies to **/.Tests.cs : Source generator changes MUST be covered by generator tests" and "Applies to **/.Tests.cs : Preserve snapshot-based verification patterns already used in the repository for source generator tests".

GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs (1)

36-143: 测试覆盖质量很好。

同步/异步入口及关键诊断字段都被断言到了,和这次公开 API 变更匹配。

Based on learnings "Applies to **/.Tests.cs : Public API changes must be covered by unit or integration tests" and "Applies to **/.cs : Every non-trivial feature, bug fix, or behavior change MUST include tests or an explicit justification for why a test is not practical".

GFramework.Game/Config/YamlConfigTextSerializer.cs (1)

8-12: 代码已正确声明了必需的命名空间导入。

YamlDotNet.SerializationYamlDotNet.Serialization.NamingConventionsusing 指令已在文件顶部显式声明,YamlDotNet 包(版本 16.3.0)已在项目配置中引用。Lines 8-12 的代码无需任何修改。

			> Likely an incorrect or invalid review comment.
GFramework.Game/Config/YamlConfigSchemaValidator.cs (1)

92-143: 同步/异步加载复用同一解析链路,这个改动方向很好。

LoadAsync 与新加的 Load 最终都走 ParseLoadedSchema(...),能有效避免两条解析逻辑后续漂移。

Comment thread GFramework.Game/Config/YamlConfigSchemaValidator.cs Outdated
Comment thread GFramework.Game/Config/YamlConfigTextSerializer.cs
Comment thread GFramework.Game/Config/YamlConfigTextValidator.cs
Comment thread GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
@greptile-apps

greptile-apps Bot commented Apr 12, 2026

Copy link
Copy Markdown

Greptile Summary

This PR adds YAML text validation and serialization utilities for the config system, wiring them into generated bindings. It introduces YamlConfigTextValidator (sync/async schema-cached validation), YamlConfigTextSerializer (shared camelCase serializer), and extends source generator output with SerializeToYaml, GetSchemaPath, GetConfigDirectoryPath, ValidateYaml, and ValidateYamlAsync helpers per binding class. A shared ResolveAbsolutePath helper is centralized in the generated catalog (addressing the previous review comment), and the schema-parsing path is refactored into a sync overload (YamlConfigSchemaValidator.Load) alongside the existing async path.

Key changes:

  • YamlConfigTextValidator: timestamp-before-load pattern correctly addresses the TOCTOU cache-poisoning concern from the previous review round.
  • YamlConfigSchemaValidator.ParseLoadedSchema: extracted as a shared helper; ReferencedTableNames now sorted by ordinal order for deterministic output.
  • Generated GeneratedConfigCatalog.ResolveAbsolutePath is internal, shared by all generated binding helpers — eliminating the per-class duplication flagged in the prior review.
  • Test coverage includes sync/async validation, cache invalidation, schema-refresh on timestamp change, and source-generator snapshot assertions.

Confidence Score: 4/5

PR is safe to merge; previous P0/P1 concerns are resolved and remaining items are non-blocking P2 suggestions.

The TOCTOU cache-poisoning issue from the prior review round is correctly fixed (timestamp captured before the Load call). The ResolveAbsolutePath duplication concern is resolved by centralizing it in GeneratedConfigCatalog as an internal helper. Test coverage is solid across unit and integration tests. The two remaining P2 items — double filesystem stat per cache miss and per-call serializer construction — are minor efficiency opportunities that do not affect correctness.

GFramework.Game/Config/YamlConfigTextValidator.cs — double-stat pattern per cache miss is worth a follow-up cleanup.

Important Files Changed

Filename Overview
GFramework.Game/Config/YamlConfigTextValidator.cs New public static validator with a ConcurrentDictionary schema cache; timestamp is captured before the Load call (TOCTOU fix), but TryGetCachedSchema also reads the timestamp independently, causing a double stat per cache miss.
GFramework.Game/Config/YamlConfigTextSerializer.cs New shared YAML serializer using camelCase convention; creates a new ISerializer on every call (documented as intentional for thread safety), returns LF-terminated output consistently.
GFramework.Game/Config/YamlConfigSchemaValidator.cs Refactored: sync Load overload added, ParseLoadedSchema extracted as shared private helper, ReferencedTableNames now ordered ordinally for determinism. Code formatting improved throughout.
GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs Generator extended with AppendYamlSerializationHelpers and a shared ResolveAbsolutePath emitted once into GeneratedConfigCatalog (not per-binding), eliminating prior duplication concern.
GFramework.Game.Tests/Config/YamlConfigTextValidatorTests.cs Good unit test coverage for sync/async validation, unknown-field errors, missing-required-field errors, and cache-invalidation on file timestamp change.
GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs New integration test verifies SerializeToYaml, GetSchemaPath, GetConfigDirectoryPath, ValidateYaml, and ValidateYamlAsync with both valid and invalid YAML inputs.
GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs New test verifying deterministic (ordinal-sorted) ReferencedTableNames output; clear setup/teardown with unique temp directories.
GFramework.Game.Tests/Config/YamlConfigTextSerializerTests.cs Tests LF-trailing newline contract and null-argument guard; straightforward and correct.
GFramework.SourceGenerators.Tests/Config/SchemaConfigGeneratorTests.cs Snapshot and assertion tests extended to verify new helper method signatures and that ResolveAbsolutePath is generated once in the catalog (not per-binding).
GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/GeneratedConfigCatalog.g.txt Snapshot updated with internal ResolveAbsolutePath helper in GeneratedConfigCatalog; implementation looks correct.
GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt Snapshot updated with all five new helpers (SerializeToYaml, GetConfigDirectoryPath, GetSchemaPath, ValidateYaml, ValidateYamlAsync); signatures and implementations look correct.

Sequence Diagram

sequenceDiagram
    participant Host as Host / Editor
    participant Binding as GeneratedBinding
    participant Validator as YamlConfigTextValidator
    participant Cache as SchemaCache
    participant FS as File System
    participant SchemaVal as YamlConfigSchemaValidator

    Host->>Binding: ValidateYaml(rootPath, yamlPath, yamlText)
    Binding->>Binding: GetSchemaPath(rootPath)
    Binding->>Validator: Validate(tableName, schemaPath, yamlPath, yamlText)
    Validator->>FS: GetLastWriteTimeUtc(schemaPath)
    FS-->>Validator: T1
    alt Cache hit
        Validator->>Cache: TryGetValue(key)
        Cache-->>Validator: schema
    else Cache miss or stale
        Validator->>FS: GetLastWriteTimeUtc(schemaPath)
        FS-->>Validator: T2
        Validator->>SchemaVal: Load(tableName, schemaPath)
        SchemaVal->>FS: ReadAllText(schemaPath)
        FS-->>SchemaVal: schemaText
        SchemaVal-->>Validator: YamlConfigSchema
        Validator->>Cache: Store(key, T2, schema)
    end
    Validator->>SchemaVal: Validate(tableName, schema, yamlPath, yamlText)
    SchemaVal-->>Validator: throws ConfigLoadException on failure
    Validator-->>Host: throws or returns
Loading

Reviews (6): Last reviewed commit: "feat(config): 添加YAML配置文本校验器" | Re-trigger Greptile

Comment thread GFramework.Game/Config/YamlConfigTextSerializer.cs
Comment thread GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs Outdated
- 实现了 YAML 配置与 JSON Schema 的运行时校验功能
- 支持嵌套对象、对象数组、标量数组的递归校验
- 集成了 enum 和引用约束的深度校验机制
- 实现了 multipleOf、uniqueItems 等扩展约束规则
- 添加了跨表引用收集和校验能力
- 提供了异步和同步两种加载校验接口
- 支持 minContains/maxContains 数组匹配计数规则
- 实现了 minProperties/maxProperties 对象属性数量校验
- 集成了日期时间、邮箱、URI 等字符串格式校验
- 提供了详细的错误诊断信息和定位功能

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
GFramework.Game/Config/YamlConfigSchemaValidator.cs (1)

77-90: ⚠️ Potential issue | 🟠 Major

修复文件读取异常捕获以避免吞掉取消信号

Line 80 的异步读取显式传入了 cancellationToken,但后续 catch (Exception) 会将 OperationCanceledException 包装成 SchemaReadFailed,破坏协作取消语义。同时宽泛的异常捕获范围超过了必要的文件 I/O 异常(IOExceptionUnauthorizedAccessException)。Line 132 的同步版本也有相同的捕获范围问题。

修复建议
         string schemaText;
         try
         {
             schemaText = await File.ReadAllTextAsync(schemaPath, cancellationToken).ConfigureAwait(false);
         }
-        catch (Exception exception)
+        catch (OperationCanceledException) when (cancellationToken.IsCancellationRequested)
+        {
+            throw;
+        }
+        catch (Exception exception) when (exception is IOException or UnauthorizedAccessException)
         {
             throw ConfigLoadExceptionFactory.Create(
                 ConfigLoadFailureKind.SchemaReadFailed,
                 tableName,
                 $"Failed to read schema file '{schemaPath}'.",
                 schemaPath: schemaPath,
                 innerException: exception);
         }

         string schemaText;
         try
         {
             schemaText = File.ReadAllText(schemaPath);
         }
-        catch (Exception exception)
+        catch (Exception exception) when (exception is IOException or UnauthorizedAccessException)
         {
             throw ConfigLoadExceptionFactory.Create(
                 ConfigLoadFailureKind.SchemaReadFailed,
                 tableName,
                 $"Failed to read schema file '{schemaPath}'.",
                 schemaPath: schemaPath,
                 innerException: exception);
         }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@GFramework.Game/Config/YamlConfigSchemaValidator.cs` around lines 77 - 90,
The current catch around File.ReadAllTextAsync(schemaPath, cancellationToken) in
YamlConfigSchemaValidator.cs swallows cancellation and is too broad; change the
exception handling so OperationCanceledException is rethrown (or not caught) and
only IO-related exceptions are wrapped into
ConfigLoadExceptionFactory.Create(SchemaReadFailed). Concretely, replace the
broad catch (Exception exception) with a catch (OperationCanceledException) {
throw; } followed by catch blocks for IOException and
UnauthorizedAccessException that call ConfigLoadExceptionFactory.Create
(referencing schemaText/File.ReadAllTextAsync, cancellationToken,
ConfigLoadFailureKind.SchemaReadFailed, and the existing
ConfigLoadExceptionFactory.Create call), and apply the same pattern to the
synchronous read path in the same class.
🧹 Nitpick comments (1)
GFramework.Game/Config/YamlConfigTextSerializer.cs (1)

8-12: 建议为缓存的序列化器实例添加线程安全注释。

Serializer 是静态共享实例,按照编码规范,应记录线程安全假设。YamlDotNet 的 ISerializer 在不可变配置下是线程安全的,建议补充注释说明。

📝 建议补充
+    // Thread-safety: YamlDotNet ISerializer is thread-safe when built with immutable configuration.
+    // The instance is created once and reused for all serialization calls.
     private static readonly ISerializer Serializer = new SerializerBuilder()

Based on learnings: "When adding caching, pooling, or shared mutable state, document thread-safety assumptions and failure modes"

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@GFramework.Game/Config/YamlConfigTextSerializer.cs` around lines 8 - 12, The
static field Serializer (type ISerializer) in YamlConfigTextSerializer.cs is a
shared cached instance and needs a thread-safety comment: add a concise doc
comment immediately above the private static readonly ISerializer Serializer
declaration stating the thread-safety assumption (e.g., that YamlDotNet's
ISerializer built with an immutable SerializerBuilder is safe for concurrent
reads), mention that the instance is immutable/configured once via
SerializerBuilder
(WithNamingConvention/DisableAliases/ConfigureDefaultValuesHandling) and note
any failure modes or when it would not be safe (if reconfigured or made
mutable); this documents why the static Serializer can be reused across threads.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@GFramework.Game/Config/YamlConfigTextSerializer.cs`:
- Around line 1-12: The file YamlConfigTextSerializer fails to compile because
types ISerializer, SerializerBuilder, CamelCaseNamingConvention and
DefaultValuesHandling are from YamlDotNet and missing namespace imports; add the
appropriate using directives (e.g., using YamlDotNet.Serialization; and using
YamlDotNet.Serialization.NamingConventions;) at the top of the file so the
YamlConfigTextSerializer static class can resolve ISerializer,
SerializerBuilder, CamelCaseNamingConvention and DefaultValuesHandling.

---

Outside diff comments:
In `@GFramework.Game/Config/YamlConfigSchemaValidator.cs`:
- Around line 77-90: The current catch around File.ReadAllTextAsync(schemaPath,
cancellationToken) in YamlConfigSchemaValidator.cs swallows cancellation and is
too broad; change the exception handling so OperationCanceledException is
rethrown (or not caught) and only IO-related exceptions are wrapped into
ConfigLoadExceptionFactory.Create(SchemaReadFailed). Concretely, replace the
broad catch (Exception exception) with a catch (OperationCanceledException) {
throw; } followed by catch blocks for IOException and
UnauthorizedAccessException that call ConfigLoadExceptionFactory.Create
(referencing schemaText/File.ReadAllTextAsync, cancellationToken,
ConfigLoadFailureKind.SchemaReadFailed, and the existing
ConfigLoadExceptionFactory.Create call), and apply the same pattern to the
synchronous read path in the same class.

---

Nitpick comments:
In `@GFramework.Game/Config/YamlConfigTextSerializer.cs`:
- Around line 8-12: The static field Serializer (type ISerializer) in
YamlConfigTextSerializer.cs is a shared cached instance and needs a
thread-safety comment: add a concise doc comment immediately above the private
static readonly ISerializer Serializer declaration stating the thread-safety
assumption (e.g., that YamlDotNet's ISerializer built with an immutable
SerializerBuilder is safe for concurrent reads), mention that the instance is
immutable/configured once via SerializerBuilder
(WithNamingConvention/DisableAliases/ConfigureDefaultValuesHandling) and note
any failure modes or when it would not be safe (if reconfigured or made
mutable); this documents why the static Serializer can be reused across threads.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0aa1b2af-c4f1-49c0-bebd-e1003bd8c387

📥 Commits

Reviewing files that changed from the base of the PR and between 925b6ce and e40703c.

📒 Files selected for processing (7)
  • GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
  • GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs
  • GFramework.Game/Config/YamlConfigSchemaValidator.cs
  • GFramework.Game/Config/YamlConfigTextSerializer.cs
  • GFramework.Game/Config/YamlConfigTextValidator.cs
  • GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
🚧 Files skipped from review as they are similar to previous changes (3)
  • GFramework.Game/Config/YamlConfigTextValidator.cs
  • GFramework.SourceGenerators.Tests/Config/snapshots/SchemaConfigGenerator/MonsterConfigBindings.g.txt
  • GFramework.Game.Tests/Config/GeneratedConfigConsumerIntegrationTests.cs
📜 Review details
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Analyze (C#)
  • GitHub Check: Code Quality & Security
🧰 Additional context used
📓 Path-based instructions (1)
**/*.cs

📄 CodeRabbit inference engine (CLAUDE.md)

**/*.cs: LoggerGenerator must automatically generate log fields and logging helper methods for classes decorated with [Log] attribute
PriorityGenerator must generate priority comparison implementations for classes decorated with [Priority] attribute
EnumExtensionsGenerator must generate enum extension capabilities for enums decorated with [GenerateEnumExtensions] attribute
ContextAwareGenerator must automatically implement IContextAware boilerplate logic for classes decorated with [ContextAware] attribute

**/*.cs: All public, protected, and internal types and members MUST include XML documentation comments (///) with <summary>, <param>, <returns>, <exception>, and <remarks> tags where applicable
XML documentation comments must explain intent, contract, and usage constraints instead of restating syntax
Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds, compatibility constraints, edge cases, registration order, lifecycle sequencing, and generated code assumptions
Core framework components (Architecture, Module, System, Context, Registry, Service Module, Lifecycle types) MUST include high-level explanations of responsibilities, lifecycle, interactions with other components, why the abstraction exists, and when to use it instead of alternatives
Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior
Methods with non-trivial logic MUST document the core idea, key decisions, and edge case handling
Do not rely on implicit imports; declare every required using explicitly
Write null-safe code that respects nullable annotations instead of suppressing warnings by default
Use namespace pattern GFramework.{Module}.{Feature} with PascalCase segments
Follow standard C# naming: Types/methods/properties/events/constants use PascalCase, interfaces use I prefix, parame...

Files:

  • GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
  • GFramework.Game/Config/YamlConfigSchemaValidator.cs
  • GFramework.Game/Config/YamlConfigTextSerializer.cs
🧠 Learnings (13)
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Public API changes must be covered by unit or integration tests

Applied to files:

  • GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Source generator changes MUST be covered by generator tests

Applied to files:

  • GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Regression fixes should include a test that fails before the fix and passes after it

Applied to files:

  • GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.Tests.cs : Preserve snapshot-based verification patterns already used in the repository for source generator tests

Applied to files:

  • GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs
📚 Learning: 2026-04-06T12:45:43.921Z
Learnt from: GeWuYou
Repo: GeWuYou/GFramework PR: 190
File: GFramework.Game/Config/GameConfigBootstrap.cs:1-3
Timestamp: 2026-04-06T12:45:43.921Z
Learning: In the GeWuYou/GFramework repository, C# files may omit explicit `using System*` imports because the project-wide `GlobalUsings.cs` (referenced via manual global `using` directives) supplies common namespaces (e.g., `System`, `System.Threading`, `System.Threading.Tasks`). During code review, do not flag missing `using System...` directives in `.cs` files as long as `GlobalUsings.cs` is present/used to provide those namespaces.

Applied to files:

  • GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs
  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
  • GFramework.Game/Config/YamlConfigSchemaValidator.cs
  • GFramework.Game/Config/YamlConfigTextSerializer.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : When generator behavior changes intentionally, update snapshots together with the implementation

Applied to files:

  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : All public, protected, and internal types and members MUST include XML documentation comments (`///`) with `<summary>`, `<param>`, `<returns>`, `<exception>`, and `<remarks>` tags where applicable

Applied to files:

  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Any change to public API, lifecycle semantics, module behavior, or extension points MUST update the related XML docs

Applied to files:

  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Add inline comments for non-trivial logic, concurrency/threading behavior, performance-sensitive paths, workarounds, compatibility constraints, edge cases, registration order, lifecycle sequencing, and generated code assumptions

Applied to files:

  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : XML documentation comments must explain intent, contract, and usage constraints instead of restating syntax

Applied to files:

  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Generated logic and source generator pipelines MUST explain what is generated, why it is generated, semantic assumptions the generator relies on, and any diagnostics or fallback behavior

Applied to files:

  • GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : Preserve deterministic behavior in registries, lifecycle orchestration, and generated outputs

Applied to files:

  • GFramework.Game/Config/YamlConfigSchemaValidator.cs
📚 Learning: 2026-04-10T09:05:17.290Z
Learnt from: CR
Repo: GeWuYou/GFramework PR: 0
File: AGENTS.md:0-0
Timestamp: 2026-04-10T09:05:17.290Z
Learning: Applies to **/*.cs : When adding caching, pooling, or shared mutable state, document thread-safety assumptions and failure modes

Applied to files:

  • GFramework.Game/Config/YamlConfigTextSerializer.cs
🪛 GitHub Check: Build and Test
GFramework.Game/Config/YamlConfigTextSerializer.cs

[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)


[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)


[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)


[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)


[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)


[failure] 8-8:
The type or namespace name 'ISerializer' could not be found (are you missing a using directive or an assembly reference?)

🔇 Additional comments (4)
GFramework.Game/Config/YamlConfigSchemaValidator.cs (2)

268-276: 引用表名排序实现正确,确保输出稳定性

这里将 HashSet 结果按 StringComparer.Ordinal 排序后再构建 YamlConfigSchema,能稳定热重载依赖推导与测试结果。

Based on learnings "Preserve deterministic behavior in registries, lifecycle orchestration, and generated outputs".


3285-3365: 节点工厂方法重排后可读性更好,语义保持清晰

CreateObject / CreateArray / CreateScalar 的组织更直观,且 XML 注释与参数契约完整。

GFramework.Game.Tests/Config/YamlConfigSchemaValidatorTests.cs (1)

41-71: 回归测试覆盖点准确,能锁定排序确定性行为

这个用例对引用表收集后的序数排序结果做了直接断言,和本次修复目标一致。

Based on learnings "Regression fixes should include a test that fails before the fix and passes after it".

GFramework.SourceGenerators/Config/SchemaConfigGenerator.cs (1)

1678-1806: LGTM! YAML 序列化辅助方法生成逻辑正确。

新增的 AppendYamlSerializationHelpers 方法为生成的绑定类输出完整的 YAML 序列化与验证辅助 API,包括:

  • SerializeToYaml:委托到共享序列化器
  • GetConfigDirectoryPath / GetSchemaPath:路径解析
  • ValidateYaml / ValidateYamlAsync:委托到运行时验证器

生成的 XML 文档包含了 <exception> 契约,符合编码规范要求。路径规范化逻辑(Lines 1799-1804)正确处理了正斜杠和反斜杠到平台目录分隔符的转换。

Comment thread GFramework.Game/Config/YamlConfigTextSerializer.cs Outdated
- 新增YamlConfigTextSerializer类提供统一的YAML序列化功能
- 集成测试中添加配置抽象接口引用
- 序列化器使用驼峰命名约定和默认值保留策略
- 自动确保YAML输出以换行符结尾
- 配置对象序列化时验证空值并抛出异常
GeWuYou added 2 commits April 12, 2026 15:41
- 实现YamlConfigTextSerializer提供YAML文本序列化功能
- 实现YamlConfigTextValidator提供YAML文本校验功能
- 添加缓存机制优化schema文件加载性能
- 实现同步和异步校验接口支持
- 添加集成测试验证生成配置绑定功能
- 扩展SchemaConfigGenerator支持配置类型生成
- 实现GeneratedConfigConsumerIntegrationTests完整测试覆盖
- 为Validate方法添加详细的remarks文档说明同步加载schema的特性
- 为ValidateAsync方法添加cancellation token异常说明和异步加载schema的详细文档
- 补充异步验证方法的I/O密集场景适用性说明
Comment thread GFramework.Game/Config/YamlConfigTextValidator.cs
- 实现同步和异步YAML文本校验功能
- 添加基于schema文件的配置校验支持
- 实现schema缓存机制避免重复磁盘IO
- 提供配置表名称和文件路径参数验证
- 集成取消令牌支持异步操作取消
- 添加详细的异常处理和诊断信息
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant