Class: RemLint::Config

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

Overview

Per-rule settings, merged from the shipped defaults and a .remlint.yml.

Shaped like RuboCop's: a top-level key per rule, Enabled and Severity understood for every rule, anything else passed through to the rule that asked for it. Exclude at the top level drops paths from the run.

Merging is per rule rather than per file: a project that sets TrailingWhitespace: {Severity: error} keeps every other rule's defaults instead of silently switching them all off.

Constant Summary collapse

DEFAULT_PATH =
Pathname.new(__dir__).join("../../config/default.yml").cleanpath
FILENAME =
".remlint.yml"

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(settings = {}) ⇒ Config

Returns a new instance of Config.



25
26
27
# File 'lib/remlint/config.rb', line 25

def initialize(settings = {})
  @settings = settings
end

Instance Attribute Details

#settingsObject (readonly)

Returns the value of attribute settings.



23
24
25
# File 'lib/remlint/config.rb', line 23

def settings
  @settings
end

Class Method Details

.ascend(directory) ⇒ Object



51
52
53
54
55
56
57
58
59
# File 'lib/remlint/config.rb', line 51

def ascend(directory)
  directory.ascend do |candidate|
    path = candidate.join(FILENAME)

    if path.file?
      break path
    end
  end
end

.defaultObject



30
31
32
# File 'lib/remlint/config.rb', line 30

def default
  new(load_yaml(DEFAULT_PATH))
end

.discover(directory = Dir.pwd) ⇒ Object

Walk up from directory looking for a .remlint.yml, the way every other linter finds its config, so remlint works from a subdirectory.



41
42
43
44
45
46
47
48
49
# File 'lib/remlint/config.rb', line 41

def discover(directory = Dir.pwd)
  found = ascend(Pathname.new(directory).expand_path)

  if found
    load_file(found)
  else
    default
  end
end

.load_file(path) ⇒ Object

The defaults with a project file merged over them.



35
36
37
# File 'lib/remlint/config.rb', line 35

def load_file(path)
  default.merge(load_yaml(Pathname.new(path)))
end

.load_yaml(path) ⇒ Object



61
62
63
64
65
66
67
# File 'lib/remlint/config.rb', line 61

def load_yaml(path)
  if path.file?
    YAML.safe_load(path.read, permitted_classes: [], aliases: true) || {}
  else
    {}
  end
end

Instance Method Details

#enabled?(rule_class) ⇒ Boolean

A rule runs unless it is switched off, or unless it is one of the opt-in rules and nothing switched it on.

Returns:

  • (Boolean)


86
87
88
89
90
# File 'lib/remlint/config.rb', line 86

def enabled?(rule_class)
  section = for_rule(rule_class.rule_name)

  section.fetch("Enabled", rule_class.enabled_by_default?)
end

#exclude_patternsObject



98
99
100
# File 'lib/remlint/config.rb', line 98

def exclude_patterns
  Array(settings["Exclude"])
end

#excluded?(path) ⇒ Boolean

Returns:

  • (Boolean)


92
93
94
95
96
# File 'lib/remlint/config.rb', line 92

def excluded?(path)
  exclude_patterns.any? do |pattern|
    File.fnmatch?(pattern, path.to_s, File::FNM_PATHNAME | File::FNM_EXTGLOB)
  end
end

#for_rule(rule_name) ⇒ Object



80
81
82
# File 'lib/remlint/config.rb', line 80

def for_rule(rule_name)
  settings.fetch(rule_name, {})
end

#merge(overrides) ⇒ Object



70
71
72
73
74
75
76
77
78
# File 'lib/remlint/config.rb', line 70

def merge(overrides)
  merged = settings.dup

  overrides.each do |key, value|
    merged[key] = merge_section(settings[key], value)
  end

  Config.new(merged)
end

#only(rule_names) ⇒ Object

--only on the command line: run these and nothing else, regardless of what the file says, but keep each rule's configured options.



111
112
113
114
115
116
117
118
119
120
121
122
# File 'lib/remlint/config.rb', line 111

def only(rule_names)
  wanted = Array(rule_names)
  merged = settings.dup

  Rule.all.each do |rule_class|
    section = merged.fetch(rule_class.rule_name, {}).dup
    section["Enabled"] = wanted.include?(rule_class.rule_name)
    merged[rule_class.rule_name] = section
  end

  Config.new(merged)
end

#rulesObject

Rules the config leaves running, instantiated with their own section.



103
104
105
106
107
# File 'lib/remlint/config.rb', line 103

def rules
  Rule.all.select { |rule_class| enabled?(rule_class) }.map do |rule_class|
    rule_class.new(for_rule(rule_class.rule_name))
  end
end