Class: Prism::Merge::ScaffoldChunkRemover
- Inherits:
-
Object
- Object
- Prism::Merge::ScaffoldChunkRemover
- Defined in:
- lib/prism/merge/scaffold_chunk_remover.rb
Overview
Surgically removes bundle-gem scaffold boilerplate from Rakefiles.
Each ChunkSpec describes an anchor (exact require/task call) and optional satellite nodes (matched fuzzily via Jaccard similarity). The remover finds all matching nodes in the top-level statements and removes them by line range, leaving user-added content intact.
Constant Summary collapse
- ChunkSpec =
Ruby::Merge::ScaffoldChunkSupport::ChunkSpec
- BUNDLER_GEM_TASKS_SPEC =
Ruby::Merge::ScaffoldChunkSupport::BUNDLER_GEM_TASKS_SPEC
- RSPEC_SPEC =
Ruby::Merge::ScaffoldChunkSupport::RSPEC_SPEC
- RUBOCOP_SPEC =
Ruby::Merge::ScaffoldChunkSupport::RUBOCOP_SPEC
- DEFAULT_TASK_SPEC =
Ruby::Merge::ScaffoldChunkSupport::DEFAULT_TASK_SPEC
- ALL_SPECS =
Ruby::Merge::ScaffoldChunkSupport::ALL_SPECS
Class Method Summary collapse
Instance Method Summary collapse
- #call ⇒ Object
-
#initialize(source, specs = ALL_SPECS) ⇒ ScaffoldChunkRemover
constructor
A new instance of ScaffoldChunkRemover.
Constructor Details
#initialize(source, specs = ALL_SPECS) ⇒ ScaffoldChunkRemover
Returns a new instance of ScaffoldChunkRemover.
29 30 31 32 |
# File 'lib/prism/merge/scaffold_chunk_remover.rb', line 29 def initialize(source, specs = ALL_SPECS) @source = source @specs = specs end |
Class Method Details
.remove(source, specs = ALL_SPECS) ⇒ Object
24 25 26 |
# File 'lib/prism/merge/scaffold_chunk_remover.rb', line 24 def remove(source, specs = ALL_SPECS) new(source, specs).call end |
Instance Method Details
#call ⇒ Object
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 |
# File 'lib/prism/merge/scaffold_chunk_remover.rb', line 34 def call return @source if @source.empty? parse_result = TreeHaver.with_backend(Prism::Merge::BACKEND_REFERENCE.id) do TreeHaver.parser_for(:ruby, backend_type: :prism).parse(@source).parse_result end statements = parse_result.value.statements&.body&.compact || [] return @source if statements.empty? lines_to_remove = Set.new @specs.each do |spec| anchor_idx = find_anchor(statements, spec) next unless anchor_idx nodes_to_remove = [statements[anchor_idx]] if spec.satellite_patterns.any? start_idx = [0, anchor_idx - spec.max_lookbehind].max end_idx = [statements.size - 1, anchor_idx + spec.max_lookahead].min spec.satellite_patterns.each do |pattern| p_tokens = Ruby::Merge::ScaffoldChunkSupport.jaccard_tokens(pattern) (start_idx..end_idx).each do |i| next if i == anchor_idx candidate = statements[i] c_tokens = Ruby::Merge::ScaffoldChunkSupport.jaccard_tokens(candidate.slice.to_s) score = Ruby::Merge::ScaffoldChunkSupport.jaccard(p_tokens, c_tokens) nodes_to_remove << candidate if score >= spec.jaccard_threshold end end end nodes_to_remove.each do |node| (node.location.start_line..node.location.end_line).each { |ln| lines_to_remove << ln } end end return @source if lines_to_remove.empty? lines = @source.lines # Remove up to 1 trailing blank line per contiguous removed block trailing = Set.new lines_to_remove.to_a.sort.each do |ln| next if lines_to_remove.include?(ln + 1) next_line = lines[ln] # 0-indexed: lines[ln] is line number ln+1 trailing << (ln + 1) if next_line && next_line.strip.empty? end lines_to_remove.merge(trailing) lines.reject.with_index { |_, i| lines_to_remove.include?(i + 1) }.join end |