Hi, and thanks for spring-boot-code-guard! A small UX observation:
SpringBootRulesConfiguration.verify() already acts as a soft-assertion layer across rule IDs, which is great. Inside a single rule, though, the first violation throws an AssertionError and aborts the scan, so only one offending class per rule is reported per run.
Example in ProxyRules.noSelfInvocationOfProxyMethodsRule:
override fun verify(scope: KoScope) = proxyModels(scope).forEach { model ->
psiFactory.createFile(model.t).collectDescendantsOfType<KtClassOrObject>()
.firstOrNull { it.name == model.n }?.verifyInvocations(model)
}
verifyInvocations throws on the first hit, aborting the forEach. Most other rules follow the same shape.
The effect for adopters: enabling a new rule becomes N round-trips (fix → re-run → see next → fix → re-run) rather than a single batch, and the total scope of impact isn't visible up front.
Proposal: apply soft-assertion semantics within each rule too — collect all matches, then throw one AssertionError joining the per-class messages. Sketch:
override fun verify(scope: KoScope) {
val failures = proxyModels(scope).mapNotNull { /* message or null */ }
if (failures.isNotEmpty()) throw AssertionError(failures.joinToString("\n"))
}
Happy to PR if this aligns with the direction you'd like. Thanks again!
Hi, and thanks for spring-boot-code-guard! A small UX observation:
SpringBootRulesConfiguration.verify()already acts as a soft-assertion layer across rule IDs, which is great. Inside a single rule, though, the first violation throws anAssertionErrorand aborts the scan, so only one offending class per rule is reported per run.Example in
ProxyRules.noSelfInvocationOfProxyMethodsRule:verifyInvocationsthrows on the first hit, aborting theforEach. Most other rules follow the same shape.The effect for adopters: enabling a new rule becomes N round-trips (fix → re-run → see next → fix → re-run) rather than a single batch, and the total scope of impact isn't visible up front.
Proposal: apply soft-assertion semantics within each rule too — collect all matches, then throw one
AssertionErrorjoining the per-class messages. Sketch:Happy to PR if this aligns with the direction you'd like. Thanks again!