Module: StillActive::LockfileIndexer
- Extended by:
- LockfileIndexer
- Included in:
- LockfileIndexer
- Defined in:
- lib/helpers/lockfile_indexer.rb
Overview
Maps gem names to line numbers in a Bundler-generated Gemfile.lock. Used by SARIF output so findings annotate the correct lockfile line.
We hand-roll the parsing rather than delegating to Bundler::LockfileParser because the latter is not side-effect-free —it tries to resolve PLUGIN SOURCE blocks against the installed plugin registry and raises Bundler::Plugin::UnknownSourceError if a plugin isn’t present in the consuming environment. We just want names + lines.
Constant Summary collapse
- TOP_LEVEL_SPEC =
Bundler indents top-level specs with exactly 4 spaces; nested deps get 6+. S+ matches what Bundler’s own parser accepts (any non-space).
/\A (\S+) \(/- BLOCK_HEADER =
Source blocks Bundler emits — see bundler/lockfile_parser.rb SOURCE constant.
/\A(GEM|GIT|PATH|PLUGIN SOURCE)\b/- SECTION_BREAK =
/\A[A-Z]/
Instance Method Summary collapse
-
#gem_line_index(content) ⇒ Object
Returns a Hash mapping gem name -> 1-based line number in ‘content`.
-
#ruby_version_line(content) ⇒ Object
Returns the 1-based line number of the Ruby version inside the RUBY VERSION block (the line after the header).
Instance Method Details
#gem_line_index(content) ⇒ Object
Returns a Hash mapping gem name -> 1-based line number in ‘content`. When a gem appears as both a top-level spec and a nested dep, the top-level entry wins. Lines outside GEM/GIT/PATH/PLUGIN SOURCE blocks are ignored.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/helpers/lockfile_indexer.rb', line 26 def gem_line_index(content) index = {} in_block = false content.each_line.with_index(1) do |line, lineno| if line.match?(BLOCK_HEADER) in_block = true next end if line.match?(SECTION_BREAK) in_block = false next end next unless in_block match = line.match(TOP_LEVEL_SPEC) index[match[1]] = lineno if match end index end |
#ruby_version_line(content) ⇒ Object
Returns the 1-based line number of the Ruby version inside the RUBY VERSION block (the line after the header). Falls back to 1.
48 49 50 51 52 53 |
# File 'lib/helpers/lockfile_indexer.rb', line 48 def ruby_version_line(content) content.each_line.with_index(1) do |line, lineno| return lineno + 1 if line.start_with?("RUBY VERSION") end 1 end |