Class: Ukiryu::Definition::DefinitionValidator

Inherits:
Object
  • Object
show all
Defined in:
lib/ukiryu/definition/definition_validator.rb

Overview

Validate tool definitions against JSON Schema

This class provides validation functionality for tool definitions using JSON Schema. The json-schema gem is optional; if not available, basic structural validation is performed instead.

Constant Summary collapse

DEFAULT_SCHEMA_VERSION =

Default schema version

'1.0'
REMOTE_SCHEMA_URL =

Remote schema URL

'https://raw.githubusercontent.com/ukiryu/schemas/refs/heads/main/v1/tool.schema.yaml'

Class Method Summary collapse

Class Method Details

.find_schema(_version = DEFAULT_SCHEMA_VERSION) ⇒ String?

Find schema file

Parameters:

  • version (String)

    schema version

Returns:

  • (String, nil)

    path to schema file from UKIRYU_SCHEMA_PATH env var, or nil



40
41
42
43
44
45
46
# File 'lib/ukiryu/definition/definition_validator.rb', line 40

def find_schema(_version = DEFAULT_SCHEMA_VERSION)
  # Only check environment variable for local schema path
  schema_path = ENV['UKIRYU_SCHEMA_PATH']
  return schema_path if schema_path && File.exist?(schema_path)

  nil
end

.load_schema(schema_path) ⇒ Hash?

Load schema

Parameters:

  • schema_path (String)

    path to schema file

Returns:

  • (Hash, nil)

    parsed schema, or nil if not available



52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/ukiryu/definition/definition_validator.rb', line 52

def load_schema(schema_path)
  return nil unless schema_path && File.exist?(schema_path)

  case File.extname(schema_path)
  when '.json'
    JSON.parse(File.read(schema_path))
  when '.yaml', '.yml'
    YAML.safe_load(File.read(schema_path), permitted_classes: [Symbol])
  end
rescue JSON::ParserError, Psych::SyntaxError, Errno::ENOENT
  nil
end

.schema_validation_available?Boolean

Check if JSON Schema validation is available

Returns:

  • (Boolean)

    true if json-schema gem is available



25
26
27
28
29
30
31
32
33
34
# File 'lib/ukiryu/definition/definition_validator.rb', line 25

def schema_validation_available?
  return @schema_validation_available if defined?(@schema_validation_available)

  @schema_validation_available = begin
    require 'json-schema'
    true
  rescue LoadError
    false
  end
end

.validate(definition, schema_path: nil) ⇒ ValidationResult

Validate a definition hash

Parameters:

  • definition (Hash)

    the definition to validate

  • schema_path (String, nil) (defaults to: nil)

    optional schema path

Returns:



70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
# File 'lib/ukiryu/definition/definition_validator.rb', line 70

def validate(definition, schema_path: nil)
  errors = []
  warnings = []

  # Basic structural validation (always available)
  structural_result = validate_structure(definition)
  errors.concat(structural_result[:errors])
  warnings.concat(structural_result[:warnings])

  # JSON Schema validation (if available)
  if schema_validation_available?
    schema = schema_path ? load_schema(schema_path) : find_and_load_schema
    if schema
      schema_result = validate_against_schema(definition, schema)
      errors.concat(schema_result[:errors])
      warnings.concat(schema_result[:warnings])
    end
    # If schema file not found, silently skip JSON schema validation
    # Structural validation is sufficient
  else
    warnings << 'json-schema gem not available, only structural validation performed'
  end

  if errors.empty?
    warnings.empty? ? Ukiryu::Definition::ValidationResult.success : Ukiryu::Definition::ValidationResult.with_warnings(warnings)
  else
    Ukiryu::Definition::ValidationResult.failure(errors, warnings)
  end
end

.validate_file(file_path, schema_path: nil) ⇒ ValidationResult

Validate a definition file

Parameters:

  • file_path (String)

    path to definition file

  • schema_path (String, nil) (defaults to: nil)

    optional schema path

Returns:



105
106
107
108
109
110
111
112
113
114
115
116
117
# File 'lib/ukiryu/definition/definition_validator.rb', line 105

def validate_file(file_path, schema_path: nil)
  # Load raw YAML hash for validation
  definition = YAML.safe_load(File.read(file_path), permitted_classes: [Symbol, Date, Time])
  validate(definition, schema_path: schema_path)
rescue Ukiryu::Errors::DefinitionNotFoundError
  Ukiryu::Definition::ValidationResult.failure(["File not found: #{file_path}"])
rescue Ukiryu::Errors::DefinitionLoadError, Ukiryu::Errors::DefinitionValidationError => e
  Ukiryu::Definition::ValidationResult.failure([e.message])
rescue Errno::ENOENT
  Ukiryu::Definition::ValidationResult.failure(["File not found: #{file_path}"])
rescue Psych::SyntaxError => e
  Ukiryu::Definition::ValidationResult.failure(["Invalid YAML: #{e.message}"])
end

.validate_string(yaml_string, schema_path: nil) ⇒ ValidationResult

Validate a YAML string

Parameters:

  • yaml_string (String)

    YAML content

  • schema_path (String, nil) (defaults to: nil)

    optional schema path

Returns:



124
125
126
127
128
129
# File 'lib/ukiryu/definition/definition_validator.rb', line 124

def validate_string(yaml_string, schema_path: nil)
  definition = YAML.safe_load(yaml_string, permitted_classes: [Symbol, Date, Time])
  validate(definition, schema_path: schema_path)
rescue Psych::SyntaxError => e
  Ukiryu::Definition::ValidationResult.failure(["Invalid YAML: #{e.message}"])
end