Module: Moult::Gate::Config

Defined in:
lib/moult/gate/config.rb

Overview

Loads gate policy overrides from a project config file (.moult.yml by default) and hands them to Policy. Config is plain YAML — psych is stdlib, so the gate adds no new runtime dependency. Only the gate: section is read; everything else is ignored, leaving room for future Moult config.

IO lives here, never in the pure Policy/Evaluation models: this resolves a path and reads a file, then defers entirely to Policy.load.

Constant Summary collapse

DEFAULT_FILENAME =
".moult.yml"

Class Method Summary collapse

Class Method Details

.policy_for(root:, config_path: nil) ⇒ Policy

Returns defaults when no config is present.

Parameters:

  • root (String)

    absolute analysis root

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

    explicit --config path; nil auto-detects .moult.yml at the root

Returns:

  • (Policy)

    defaults when no config is present

Raises:

  • (Moult::Error)

    when an explicit path is missing or the file is unreadable



24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/moult/gate/config.rb', line 24

def policy_for(root:, config_path: nil)
  path = resolve(root, config_path)
  return Policy.default unless path

  data = YAML.safe_load_file(path) || {}
  unless data.is_a?(Hash)
    raise Moult::Error, "config #{relative(path, root)} must be a YAML mapping"
  end

  overrides = data["gate"] || data[:gate] || {}
  Policy.load(overrides, source: relative(path, root))
rescue Psych::SyntaxError => e
  raise Moult::Error, "could not parse config #{relative(path, root)}: #{e.message}"
end

.relative(path, root) ⇒ Object



50
51
52
# File 'lib/moult/gate/config.rb', line 50

def relative(path, root)
  SymbolId.relative_path(File.expand_path(path), root)
end

.resolve(root, config_path) ⇒ Object



39
40
41
42
43
44
45
46
47
48
# File 'lib/moult/gate/config.rb', line 39

def resolve(root, config_path)
  if config_path
    return config_path if File.file?(config_path)

    raise Moult::Error, "no such config file: #{config_path}"
  end

  default = File.join(root, DEFAULT_FILENAME)
  File.file?(default) ? default : nil
end