Module: Seams::Generators::SiblingRubocopWriter
- Defined in:
- lib/seams/generators/sibling_rubocop_writer.rb
Overview
Rewrites the OtherEngines lists inside every engine’s .rubocop.yml so each engine is configured with every OTHER engine as a boundary. Used by both the seams:engine and seams:remove generators — generation adds the new engine, removal prunes the gone one.
The replacement is scoped tightly to the OtherEngines key so we never clobber the surrounding ExposedConcerns / Enabled / OwnEngine values. The previous version of this code used a too-greedy lookahead that ate the next sibling key.
Constant Summary collapse
- MODULE_ACCESS_KEY =
"Seams/NoCrossEngineModelAccess"- DEPENDENCY_KEY =
"Seams/NoCrossEngineDependency"
Class Method Summary collapse
- .camelcase(name) ⇒ Object
- .formatted_block(values) ⇒ Object
- .other_engines_regex(cop_key) ⇒ Object
-
.replace_other_engines(content, cop_key, values) ⇒ Object
Matches ‘<cop_key>:` and the very next `OtherEngines:` line under it, replacing only the value of OtherEngines.
- .rewrite!(engines_root:, dirs:) ⇒ Object
Class Method Details
.camelcase(name) ⇒ Object
40 41 42 |
# File 'lib/seams/generators/sibling_rubocop_writer.rb', line 40 def camelcase(name) name.split("_").map(&:capitalize).join end |
.formatted_block(values) ⇒ Object
63 64 65 66 67 |
# File 'lib/seams/generators/sibling_rubocop_writer.rb', line 63 def formatted_block(values) return " OtherEngines: []" if values.empty? " OtherEngines:\n#{values.map { |v| " - #{v}" }.join("\n")}" end |
.other_engines_regex(cop_key) ⇒ Object
69 70 71 72 73 74 |
# File 'lib/seams/generators/sibling_rubocop_writer.rb', line 69 def other_engines_regex(cop_key) prefix = "#{Regexp.escape(cop_key)}:[^\\n]*\\n(?:[ \\t]+[^\\n]+\\n)*?" empty_form = "[ \\t]*\\[\\][ \\t]*\\n" list_form = "[ \\t]*\\n(?: -[ \\t]+[^\\n]+\\n)*" Regexp.new("(#{prefix}) OtherEngines:(?:#{empty_form}|#{list_form})") end |
.replace_other_engines(content, cop_key, values) ⇒ Object
Matches ‘<cop_key>:` and the very next `OtherEngines:` line under it, replacing only the value of OtherEngines. We don’t try to span multiple following keys — the regex stops as soon as it has consumed either the inline ‘[]` form or the indented list form.
48 49 50 51 52 53 54 55 56 57 58 59 60 61 |
# File 'lib/seams/generators/sibling_rubocop_writer.rb', line 48 def replace_other_engines(content, cop_key, values) regex = other_engines_regex(cop_key) formatted = formatted_block(values) unless regex.match?(content) raise ArgumentError, "SiblingRubocopWriter could not find a writable `OtherEngines:` " \ "value under `#{cop_key}`. Hand-edited or flow-style YAML " \ "(`{ OtherEngines: [Foo] }`) is not supported — restore the " \ "block-style template and retry." end content.sub(regex, "\\1#{formatted}\n") end |
.rewrite!(engines_root:, dirs:) ⇒ Object
26 27 28 29 30 31 32 33 34 35 36 37 38 |
# File 'lib/seams/generators/sibling_rubocop_writer.rb', line 26 def rewrite!(engines_root:, dirs:) dirs.each do |engine_dir| others = (dirs - [engine_dir]).sort others_module = others.map { |d| camelcase(d) } rubocop_path = File.join(engines_root, engine_dir, ".rubocop.yml") next unless File.exist?(rubocop_path) content = File.read(rubocop_path) content = replace_other_engines(content, MODULE_ACCESS_KEY, others_module) content = replace_other_engines(content, DEPENDENCY_KEY, others) File.write(rubocop_path, content) end end |