Class: Ace::Review::Atoms::PresetValidator
- Inherits:
-
Object
- Object
- Ace::Review::Atoms::PresetValidator
- Defined in:
- lib/ace/review/atoms/preset_validator.rb
Overview
Validates preset references and detects circular dependencies
Constant Summary collapse
- MAX_DEPTH =
Maximum recursion depth for preset composition A sane limit to prevent stack overflows from deep, non-circular nesting
10
Class Method Summary collapse
-
.check_circular_dependency(preset_name, preset_chain) ⇒ Object
Detect circular dependencies in preset composition Returns { success: true } if no circular dependency Returns { success: false, error: “…” } if circular dependency found.
-
.extract_preset_references(preset_data) ⇒ Object
Extract preset references from a preset’s configuration Returns array of preset names referenced in the ‘presets:’ key at root level.
-
.preset_exists?(preset_name, preset_manager) ⇒ Boolean
Check if a preset exists in the preset manager.
-
.validate_preset_name(preset_name) ⇒ Object
Validate preset name format Returns { success: true } if valid Returns { success: false, error: “…” } if invalid.
-
.validate_presets(preset_names, preset_manager) ⇒ Object
Validate a list of preset names Returns { success: true, valid: [], missing: [] }.
Class Method Details
.check_circular_dependency(preset_name, preset_chain) ⇒ Object
Detect circular dependencies in preset composition Returns { success: true } if no circular dependency Returns { success: false, error: “…” } if circular dependency found
52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 |
# File 'lib/ace/review/atoms/preset_validator.rb', line 52 def self.check_circular_dependency(preset_name, preset_chain) if preset_chain.include?(preset_name) { success: false, error: "Circular dependency detected: #{(preset_chain + [preset_name]).join(" -> ")}" } elsif preset_chain.size >= MAX_DEPTH { success: false, error: "Maximum preset nesting depth (#{MAX_DEPTH}) exceeded: #{preset_chain.join(" -> ")}" } else {success: true} end end |
.extract_preset_references(preset_data) ⇒ Object
Extract preset references from a preset’s configuration Returns array of preset names referenced in the ‘presets:’ key at root level
91 92 93 94 95 96 97 98 99 |
# File 'lib/ace/review/atoms/preset_validator.rb', line 91 def self.extract_preset_references(preset_data) return [] unless preset_data # Look for root-level 'presets' key (both string and symbol) presets = preset_data["presets"] || preset_data[:presets] || [] # Ensure we return an array of strings Array(presets).map(&:to_s) end |
.preset_exists?(preset_name, preset_manager) ⇒ Boolean
Check if a preset exists in the preset manager
45 46 47 |
# File 'lib/ace/review/atoms/preset_validator.rb', line 45 def self.preset_exists?(preset_name, preset_manager) preset_manager.preset_exists?(preset_name) end |
.validate_preset_name(preset_name) ⇒ Object
Validate preset name format Returns { success: true } if valid Returns { success: false, error: “…” } if invalid
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/ace/review/atoms/preset_validator.rb', line 15 def self.validate_preset_name(preset_name) return {success: false, error: "Preset name cannot be nil or empty"} if preset_name.nil? || preset_name.empty? # Check for path traversal attempts if preset_name.start_with?("/", "\\") return { success: false, error: "Invalid preset name '#{preset_name}': absolute paths are not allowed" } end if preset_name.include?("..") || preset_name.include?("/") || preset_name.include?("\\") return { success: false, error: "Invalid preset name '#{preset_name}': cannot contain path separators or '..' sequences" } end # Check for reasonable length if preset_name.length > 100 return { success: false, error: "Preset name too long (max 100 characters): '#{preset_name[0..20]}...'" } end {success: true} end |
.validate_presets(preset_names, preset_manager) ⇒ Object
Validate a list of preset names Returns { success: true, valid: [], missing: [] }
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
# File 'lib/ace/review/atoms/preset_validator.rb', line 70 def self.validate_presets(preset_names, preset_manager) valid = [] missing = [] preset_names.each do |name| if preset_exists?(name, preset_manager) valid << name else missing << name end end { success: missing.empty?, valid: valid, missing: missing } end |