Class: RosettAi::Engines::BaseConfigCompiler

Inherits:
Object
  • Object
show all
Defined in:
lib/rosett_ai/engines/base_config_compiler.rb

Overview

Abstract base class for engine config compilers.

Extracts shared compilation infrastructure from Claude::ConfigCompiler: file discovery, YAML loading, schema validation, checksum diffing, action determination, and result writing.

Subclasses must implement:

  • #config_dir → Pathname to scope YAML directory
  • #schema_path → Pathname to JSON Schema file
  • #scope_router → object responding to #target_path(scope)
  • #transform(data, scope) → [json_data, warnings]
  • #output_format → Symbol (:json, :yaml)

Constant Summary collapse

HEADER_KEYS =
['name', 'scope', 'version', 'status', 'compatibility',
'author', 'created_at', 'modified_at', 'modified_by'].freeze

Instance Method Summary collapse

Constructor Details

#initialize(simulate: false, secret_resolver: nil) ⇒ BaseConfigCompiler

Returns a new instance of BaseConfigCompiler.



28
29
30
31
32
# File 'lib/rosett_ai/engines/base_config_compiler.rb', line 28

def initialize(simulate: false, secret_resolver: nil)
  @simulate = simulate
  @secret_resolver = secret_resolver || RosettAi::Config::SecretResolver.new
  @schema = load_schema
end

Instance Method Details

#check_compatibility(_header, _path) ⇒ Object (protected)

Subclass may override: compatibility checks.



114
115
116
# File 'lib/rosett_ai/engines/base_config_compiler.rb', line 114

def check_compatibility(_header, _path)
  []
end

#compileObject

Compile all scope files. Returns [RosettAi::Config::CompileResult].



35
36
37
# File 'lib/rosett_ai/engines/base_config_compiler.rb', line 35

def compile
  discover_scope_files.map { |path| compile_scope(path) }
end

#compile_scope(path) ⇒ Object

Compile a single scope file. Returns RosettAi::Config::CompileResult.



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/rosett_ai/engines/base_config_compiler.rb', line 40

def compile_scope(path)
  warnings = []
  data = load_and_validate(path)
  header = extract_header(data)
  scope = header['scope']
  warnings.concat(check_compatibility(header, path))

  json_data, transform_warnings = transform(data, scope)
  warnings.concat(transform_warnings)

  json_data = @secret_resolver.resolve_all(json_data)

  target = scope_router.target_path(scope)
  action, diff = determine_action(target, json_data)

  RosettAi::Config::CompileResult.new(
    scope: scope, source_path: Pathname.new(path), target_path: target,
    json_data: json_data, warnings: warnings, action: action, diff: diff
  )
rescue RosettAi::Error, ArgumentError, JSON::Schema::ValidationError => e
  RosettAi::Config::CompileResult.new(
    scope: extract_scope_from_path(path), source_path: Pathname.new(path),
    target_path: nil, json_data: nil,
    warnings: [e.message], action: :skipped, diff: nil
  )
end

#config_dirObject (protected)

Subclass must override: path to scope YAML directory.

Raises:

  • (NotImplementedError)


90
91
92
# File 'lib/rosett_ai/engines/base_config_compiler.rb', line 90

def config_dir
  raise NotImplementedError, "#{self.class}#config_dir must be implemented"
end

#discover_scope_filesObject

Discover scope files in the engine's config directory.



68
69
70
71
72
73
# File 'lib/rosett_ai/engines/base_config_compiler.rb', line 68

def discover_scope_files
  dir = config_dir
  return [] unless dir.exist?

  Dir.glob(dir.join('*.yml'))
end

#output_formatObject (protected)

Subclass may override: output format (:json or :yaml).



111
# File 'lib/rosett_ai/engines/base_config_compiler.rb', line 111

def output_format = :json

#schema_pathObject (protected)

Subclass must override: path to JSON Schema file.

Raises:

  • (NotImplementedError)


95
96
97
# File 'lib/rosett_ai/engines/base_config_compiler.rb', line 95

def schema_path
  raise NotImplementedError, "#{self.class}#schema_path must be implemented"
end

#scope_routerObject (protected)

Subclass must override: scope router instance.

Raises:

  • (NotImplementedError)


100
101
102
# File 'lib/rosett_ai/engines/base_config_compiler.rb', line 100

def scope_router
  raise NotImplementedError, "#{self.class}#scope_router must be implemented"
end

#transform(_data, _scope) ⇒ Array(Hash, Array<String>) (protected)

Subclass must override: transform data into output format.

Returns:

  • (Array(Hash, Array<String>))

    [output_data, warnings]

Raises:

  • (NotImplementedError)


106
107
108
# File 'lib/rosett_ai/engines/base_config_compiler.rb', line 106

def transform(_data, _scope)
  raise NotImplementedError, "#{self.class}#transform must be implemented"
end

#write_results(results) ⇒ Object

Write compiled results to their target paths.



76
77
78
79
80
81
82
83
84
85
# File 'lib/rosett_ai/engines/base_config_compiler.rb', line 76

def write_results(results)
  return results if @simulate

  results.each do |result|
    next unless result.changed? && result.target_path

    write_output(result.target_path, result.json_data)
  end
  results
end