Module: Canon::Rebaseliner::HeredocRewriter
- Defined in:
- lib/canon/rebaseliner/heredoc_rewriter.rb
Overview
Replace a heredoc's body in a spec file with new content, preserving
the heredoc's opening style (<<~ re-indented, <<-/<< verbatim).
Class Method Summary collapse
-
.format_body(new_body, style, terminator_indent) ⇒ Object
Format the new body to fit the heredoc style.
- .rewrite!(spec, new_body) ⇒ void
-
.strip_common_leading_whitespace(text) ⇒ Object
Remove the largest common leading-whitespace prefix from a multi-line string, mirroring
<<~'s own behaviour.
Class Method Details
.format_body(new_body, style, terminator_indent) ⇒ Object
Format the new body to fit the heredoc style.
:squiggly(<<~): re-indent each line to the terminator column.:dash/:strict: write verbatim (the original code is indentation-sensitive, leave it alone). Always ensures a single trailing newline before the terminator line.
27 28 29 30 31 32 33 34 35 36 37 38 39 |
# File 'lib/canon/rebaseliner/heredoc_rewriter.rb', line 27 def format_body(new_body, style, terminator_indent) normalised = new_body.dup normalised << "\n" unless normalised.end_with?("\n") case style when :squiggly indent = " " * (terminator_indent || 0) stripped = strip_common_leading_whitespace(normalised) stripped.lines.map { |line| line == "\n" ? line : "#{indent}#{line}" }.join else normalised end end |
.rewrite!(spec, new_body) ⇒ void
This method returns an undefined value.
14 15 16 17 18 19 20 |
# File 'lib/canon/rebaseliner/heredoc_rewriter.rb', line 14 def rewrite!(spec, new_body) body = format_body(new_body, spec.style, spec.terminator_indent) new_source = spec.source.byteslice(0, spec.content_start_offset) + body + spec.source.byteslice(spec.content_end_offset..-1) AtomicWriter.write(spec.spec_path, new_source) end |
.strip_common_leading_whitespace(text) ⇒ Object
Remove the largest common leading-whitespace prefix from a multi-line
string, mirroring <<~'s own behaviour. Blank lines don't constrain
the prefix.
44 45 46 47 48 49 50 51 52 53 |
# File 'lib/canon/rebaseliner/heredoc_rewriter.rb', line 44 def strip_common_leading_whitespace(text) lines = text.lines leading = lines .reject { |l| l.chomp.empty? } .map { |l| l[/\A[ \t]*/].length } .min || 0 return text if leading.zero? lines.map { |l| l.chomp.empty? ? l : l[leading..] }.join end |