class Git::Parsers::Diff::Patch::PatchFileParser
Stateful parser for unified diff patch output
@api private
Public Class Methods
Source
# File lib/git/parsers/diff.rb, line 676 def initialize(patch_text, numstat_map = {}) @patch_text = patch_text @numstat_map = numstat_map @files = [] @current_file = nil end
Initializes parser state for a patch text block
@param patch_text [String] unified diff patch text
@param numstat_map [Hash<String, Hash>] path to insert/delete stats
@return [void]
Public Instance Methods
Source
# File lib/git/parsers/diff.rb, line 687 def parse @patch_text.split("\n").each { |line| process_line(line) } finalize_current_file @files end
Parses patch text into file patch info objects
@return [Array<Git::DiffFilePatchInfo>]
Private Instance Methods
Source
# File lib/git/parsers/diff.rb, line 741 def append_to_current_file(line) parse_metadata_line(line) @current_file[:patch] = "#{@current_file[:patch]}\n#{line}" end
Appends metadata and patch text to the current file entry
@param line [String] a metadata or patch content line
@return [void]
Source
# File lib/git/parsers/diff.rb, line 779 def build_file_ref(side) path = @current_file[:"#{side}_path"] return nil if path.nil? Git::FileRef.new( mode: @current_file[:"#{side}_mode"] || '', sha: @current_file[:"#{side}_sha"] || '', path: path ) end
Builds a file reference for one side of the diff entry
@param side [Symbol] diff side key (‘:src` or `:dst`)
@return [Git::FileRef, nil]
Source
# File lib/git/parsers/diff.rb, line 761 def build_patch_info path = @current_file[:dst_path] || @current_file[:src_path] stats = @numstat_map.fetch(path, { insertions: 0, deletions: 0 }) Git::DiffFilePatchInfo.new( src: build_file_ref(:src), dst: build_file_ref(:dst), patch: @current_file[:patch], status: @current_file[:status], similarity: @current_file[:similarity], binary: @current_file[:binary], insertions: stats[:insertions], deletions: stats[:deletions] ) end
Builds a finalized patch info object for the current file
@return [Git::DiffFilePatchInfo]
Source
# File lib/git/parsers/diff.rb, line 730 def default_file_state { src_mode: nil, dst_mode: nil, src_sha: '', dst_sha: '', src_path: nil, dst_path: nil, status: :modified, similarity: nil, binary: false } end
Builds the default state hash for a new patch file entry
@return [Hash] default metadata for an in-progress file parse
Source
# File lib/git/parsers/diff.rb, line 750 def finalize_current_file return unless @current_file @files << build_patch_info @current_file = nil end
Finalizes and stores the current file entry
@return [void]
Source
# File lib/git/parsers/diff.rb, line 701 def process_line(line) if (match = line.match(DIFF_HEADER_PATTERN)) start_new_file(match, line) elsif @current_file append_to_current_file(line) end end
Processes one patch line and updates parser state
@param line [String] a single line from patch text
@return [void]
Source
# File lib/git/parsers/diff.rb, line 717 def start_new_file(match, line) finalize_current_file @current_file = default_file_state.merge( patch: line, src_path: Git::EscapedPath.new(match[2]).unescape, dst_path: Git::EscapedPath.new(match[4]).unescape ) end
Starts a new file section from a ‘diff –git` header
@param match [MatchData] parsed header match for current diff file
@param line [String] raw ‘diff –git` header line
@return [void]