[feat] json: validate/try_validate — JSON Schema validation#159
Conversation
Adds json.validate / json.try_validate to lib/json (the fourth v0.2.1
increment; resolves the PKG-19 need inside the json module per user
decision): check a document against a JSON Schema, drafts 4/6/7/2019-09/
2020-12 auto-detected from $schema. data and schema each accept a JSON
string/bytes or a Starlark value, so a schema can be written as a dict
literal. validate returns None or fails with one line per violation,
each prefixed with the JSON Pointer of the offending location
("at /age: must be >= 0 but found -3"). try_validate distinguishes three
outcomes: (True, None) valid, (False, details) invalid, (None, error)
when validation could not run.
Engine: github.com/santhosh-tekuri/jsonschema/v5 v5.3.1 as a module
dependency — a deliberate, evaluated exception to the vendoring pattern:
its go.mod is exactly go1.19 with ZERO requirements, so go.sum gains two
lines and no transitive deps; Apache-2.0; measured +256 KiB on the
go1.19 floor (Docker, -trimpath -s -w), under the +312 KiB the module
survey already accepted for this capability. Hand-written validation
DSLs stay rejected per that survey.
Purity and stability: all external $ref loading (file:// and network) is
blocked via the Compiler's LoadURL hook — schemas must be self-contained.
A panic audit of the engine found no script-reachable panic (Must*
helpers are init-only and unused; Validate recovers InfiniteLoopError/
InvalidJSONTypeError into errors, which the wrapper also handles), backed
by hostile-input tests: self-referential $ref, invalid pattern regex,
200-deep nesting, uniqueItems hashing — error, never panic. Compiled
schemas are cached (bounded, dropped wholesale on overflow so scripts
cannot grow memory unboundedly).
Tests are a section in json_test.go (no new file, no third-party test
framework): conforming/violating documents, pointer-carrying messages,
the three try_ outcomes, draft-7 via $schema, blocked $refs, cache
eviction churn, the violation-list cap, and argument errors.
-race -count=2 and the go1.19 floor are green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…differently-licensed permissive deps go through the module-dependency evaluation bar Records the jsonschema decision rationale: vendoring Apache-2.0 source into this MIT repository would make it mixed-license, so the engine is a module dependency instead — acceptable because its go.mod is exactly go1.19, it has zero requirements, and the binary delta measured +256 KiB on the floor toolchain. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Up to standards ✅🟢 Issues
|
| Category | Results |
|---|---|
| BestPractice | 1 minor |
| CodeStyle | 10 minor |
🟢 Metrics 30 complexity · 7 duplication
Metric Results Complexity 30 Duplication 7
🟢 Coverage 96.00% diff coverage · +0.01% coverage variation
Metric Results Coverage variation ✅ +0.01% coverage variation (-1.00%) Diff coverage ✅ 96.00% diff coverage Coverage variation details
Coverable lines Covered lines Coverage Common ancestor commit (9749926) 7603 7192 94.59% Head commit (74389cf) 7692 (+89) 7277 (+85) 94.60% (+0.01%) Coverage variation is the difference between the coverage for the head and common ancestor commits of the pull request branch:
<coverage of head commit> - <coverage of common ancestor commit>Diff coverage details
Coverable lines Covered lines Diff coverage Pull request (#159) 100 96 96.00% Diff coverage is the percentage of lines that are covered by tests out of the coverable lines that the pull request added or modified:
<covered lines added or modified>/<coverable lines added or modified> * 100%
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #159 +/- ##
==========================================
+ Coverage 93.39% 93.41% +0.01%
==========================================
Files 48 49 +1
Lines 6105 6177 +72
==========================================
+ Hits 5702 5770 +68
- Misses 256 258 +2
- Partials 147 149 +2 ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
What
Adds
json.validate/json.try_validateto lib/json (the fourth v0.2.1 increment; resolves the PKG-19 need inside the json module per user decision): check a document against a JSON Schema — drafts 4/6/7/2019-09/2020-12, auto-detected from$schema(default 2020-12).dataandschemaeach accept a JSON string/bytes or a Starlark value, so a schema can be written as a dict literal.validate(data, schema)→None, or fails with one line per violation, each carrying the JSON Pointer of the offending location:at /age: must be >= 0 but found -3.try_validate(data, schema)→ three distinguished outcomes:(True, None)valid ·(False, details)invalid ·(None, error)could-not-run (bad schema / malformed JSON / bad args).Engine & license decision
github.com/santhosh-tekuri/jsonschema/v5v5.3.1 as a module dependency — deliberately not vendored: copying Apache-2.0 source into this MIT repository would make it mixed-license. As a module dep the repo stays pure MIT (CLAUDE.md now records this rule: vendoring is same-license/MIT only; differently-licensed permissive libraries go through the module-dependency evaluation bar).Evaluation (all on the go1.19 floor, per the bar):
go 1.19— does not lift oursrequireblock) →go.sumgains exactly 2 linesPurity & stability
$refloading is blocked (file:// and network) via the Compiler'sLoadURLhook — schemas must be self-contained; the json module staysCapPure.Must*helpers are init-only and unused;ValidaterecoversInfiniteLoopError/InvalidJSONTypeErrorinto errors (and the wrapper handles any non-ValidationErrorerror); the rest are non-script invariants. Backed by hostile-input tests: self-referential$ref, invalidpatternregex, 200-deep nesting,uniqueItemshashing — error, never panic.Tests / verification
A
TestJSONValidatesection injson_test.go(no new file, no third-party test framework): conforming/violating documents, pointer-carrying messages, the threetry_outcomes, schema-as-dict, draft-7 via$schema, blocked file/http$refs, cache-eviction churn, the violation-list cap, robustness cases, and argument errors.validate.gofunctions at 93–100%;gofmt/vetclean; full-repo-race -count=2and the go1.19 floor (Docker) green.Refs: PKG-19 / D6 (module survey: Schema validate 必做, hand-written DSL rejected); v0.2.1 increment #4.