Class: Audition::Config

Inherits:
Object
  • Object
show all
Defined in:
lib/audition/config.rb

Overview

Project configuration from .audition.yml at the target root:

fail_on: warning
timeout: 60
exclude:
- legacy/**
- db/schema.rb
checks:
disable:
  - at-exit

CLI flags always win over config values.

Constant Summary collapse

FILE =
".audition.yml"
EMPTY =
Ractor.make_shareable(
  {fail_on: nil, timeout: nil, exclude: [],
   disabled_checks: []}
)
FAIL_ON_LEVELS =
%w[error warning info].freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(fail_on:, timeout:, exclude:, disabled_checks:) ⇒ Config

Returns a new instance of Config.



67
68
69
70
71
72
# File 'lib/audition/config.rb', line 67

def initialize(fail_on:, timeout:, exclude:, disabled_checks:)
  @fail_on = fail_on
  @timeout = timeout
  @exclude = exclude
  @disabled_checks = disabled_checks
end

Instance Attribute Details

#disabled_checksObject (readonly)

Returns the value of attribute disabled_checks.



28
29
30
# File 'lib/audition/config.rb', line 28

def disabled_checks
  @disabled_checks
end

#excludeObject (readonly)

Returns the value of attribute exclude.



28
29
30
# File 'lib/audition/config.rb', line 28

def exclude
  @exclude
end

#fail_onObject (readonly)

Returns the value of attribute fail_on.



28
29
30
# File 'lib/audition/config.rb', line 28

def fail_on
  @fail_on
end

#timeoutObject (readonly)

Returns the value of attribute timeout.



28
29
30
# File 'lib/audition/config.rb', line 28

def timeout
  @timeout
end

Class Method Details

.load(root) ⇒ Config

Returns empty config when the file is absent.

Parameters:

  • root (String)

    directory that may contain .audition.yml

Returns:

  • (Config)

    empty config when the file is absent

Raises:

  • (Audition::Error)

    on malformed YAML, a non-mapping document, or an unknown fail_on level



34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
# File 'lib/audition/config.rb', line 34

def self.load(root)
  path = File.join(root.to_s, FILE)
  return new(**EMPTY) unless File.file?(path)

  data = YAML.safe_load_file(path) || {}
  validate!(path, data)
  new(
    fail_on: data["fail_on"]&.to_sym,
    timeout: data["timeout"],
    exclude: Array(data["exclude"]).map(&:to_s),
    disabled_checks:
      Array(data.dig("checks", "disable")).map(&:to_s)
  )
rescue Psych::Exception => e
  raise Error, "#{path}: #{e.message}"
end

Instance Method Details

#check_disabled?(check) ⇒ Boolean

Returns:

  • (Boolean)


88
89
90
# File 'lib/audition/config.rb', line 88

def check_disabled?(check)
  disabled_checks.include?(check)
end

#excluded?(relative_path) ⇒ Boolean

Globs follow .gitignore-style expectations: * stays within one directory level, dir/** covers the whole subtree, and a leading ./ is tolerated.

Returns:

  • (Boolean)


77
78
79
80
81
82
83
84
85
86
# File 'lib/audition/config.rb', line 77

def excluded?(relative_path)
  exclude.any? do |raw|
    pattern = raw.delete_prefix("./")
    next true if File.fnmatch?(pattern, relative_path,
      File::FNM_PATHNAME | File::FNM_EXTGLOB)

    prefix = pattern[%r{\A(.+?)/\*\*(?:/\*+)?\z}, 1]
    prefix && relative_path.start_with?("#{prefix}/")
  end
end