feat(validate): extract spec validation into a public 'validate' package#944
Merged
Merged
Conversation
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #944 +/- ##
==========================================
- Coverage 90.53% 88.56% -1.98%
==========================================
Files 271 272 +1
Lines 16231 16235 +4
==========================================
- Hits 14695 14378 -317
- Misses 963 1321 +358
+ Partials 573 536 -37
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
The kin-openapi error mapping logic (rule IDs, severities, source locations, fingerprints) has lived in internal/validate.go since PR #894 introduced 'oasdiff validate'. That keeps it locked inside the CLI; any other consumer (oasdiff-service, third-party tools) has no way to call it. Move the pure validation+mapping logic into a new 'validate' package with one public entry point: func Validate(spec *openapi3.T, source string) formatters.Findings This mirrors how diff.Get and checker.CheckBackwardCompatibility are callable from any consumer rather than being CLI-internal. What moves: - mapKinErrors, flattenKinErrors, dedupePreferringComponents - severityForKinError, sectionForKinError, sectionFromField - pathOperationForKinError, unwrapContext - argsForKinError, lineForKinError, columnForKinError - locationForKinError, fieldLoc - ruleIDForKinError, joinFieldsForRuleID, ruleIDFromField - unknownValidationID const What stays in internal/validate.go (CLI-only): - getValidateCmd (cobra command + flags) - runValidate (load spec, call validate.Validate, format output) - outputFindings (formatter lookup + render) Behaviour unchanged: the CLI command now calls validate.Validate(spec, source) and threads the result through the same formatter logic. All existing CLI validate tests (internal/validate_test.go, 471 lines) pass without modification. While here: renamed the local validate() helper in internal/viper.go to validateViperConfig() since 'validate' was a generic name that collided with the new package import. One call site updated. Blocks: oasdiff-service#200, which will call validate.Validate from the new /public/validate endpoint. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The 'mirrors how diff.Get and checker.CheckBackwardCompatibility are callable...' paragraph was internal-project rationale, not useful to a library user reading the package doc. Keep the first paragraph (what the package does); drop the second. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
99605b8 to
e20a786
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Extracts the kin-openapi error →
formatters.Findingmapping out ofinternal/validate.gointo a new publicvalidatepackage with one entry point:This mirrors how
diff.Getandchecker.CheckBackwardCompatibilityare publicly callable from any consumer; the validation logic now follows the same convention.Why
oasdiff validateshipped in v1.16.0 (#894) but its kin-error → Finding mapping (rule IDs, severities, source locations, dedup-preferring-components, fingerprints) lives entirely ininternal/validate.go. That locks ~800 lines of validation logic inside the CLI binary; anything else that wants the same structured output (oasdiff-service, third-party Go tools) has to either duplicate it or shell out to the CLI.The immediate driver is oasdiff-service#200: the calculator at
oasdiff.com/diffneeds a/public/validateendpoint, and the cleanest way to wire that up is to callvalidate.Validate(spec, source)the same way the diff endpoint callsdiff.Get(config, s1, s2). The longer-term driver is that any future Go consumer (a linter wrapper, an IDE extension, an enterprise pipeline tool) should be able to import oasdiff and callvalidate.Validate(...)without copying internals.What moves vs stays
Moves to
validate/validate.go(public):mapKinErrors,flattenKinErrors,dedupePreferringComponentsseverityForKinError,sectionForKinError,sectionFromFieldpathOperationForKinError,unwrapContextargsForKinError,lineForKinError,columnForKinErrorlocationForKinError,fieldLocruleIDForKinError,joinFieldsForRuleID,ruleIDFromFieldunknownValidationIDconstAll helpers stay unexported in the new package; only
Validateis the public surface.Stays in
internal/validate.go(CLI plumbing):getValidateCmd(cobra command + flag wiring)runValidate(load spec viaflags, callvalidate.Validate, route through formatter)outputFindings(formatter lookup + render to stdout)Behaviour is unchanged
All 471 lines of
internal/validate_test.goexercise the full CLI command, not the internal helpers directly. They all pass against the lifted code without modification. No fixture changes, no output changes.Full Go suite green:
The new package has no tests of its own in this PR — the existing CLI tests cover every mapping path. Direct unit tests for
validate.Validate(...)would be a useful follow-up but are not required for behaviour preservation.Small incidental rename
internal/viper.gohad a local helper namedvalidate(IViper)that validated viper-loaded config values. The new package import would collide with that name (Go does not allow a package and a top-level identifier to share a name in the same file). Renamed it tovalidateViperConfig— descriptive of what it actually validates, no external API impact (it was a package-internal function).What's next
/public/validateendpoint that callsvalidate.Validate(...)and returns findings as JSON. Will pin to a main pseudoversion of this PR.File count / line count
The +37 net is the public package's doc comment + one nil-spec guard in
Validate(returns nil rather than panicking on a nil spec, since the public surface should be defensive).