Class: Dolt::Git::Blame::PorcelainParser

Inherits:
Object
  • Object
show all
Defined in:
lib/libdolt/git/blame.rb

Instance Method Summary collapse

Constructor Details

#initialize(output) ⇒ PorcelainParser

Returns a new instance of PorcelainParser.



36
37
38
39
# File 'lib/libdolt/git/blame.rb', line 36

def initialize(output)
  @output = output
  @commits = {}
end

Instance Method Details

#extract(lines, thing) ⇒ Object



110
111
112
# File 'lib/libdolt/git/blame.rb', line 110

def extract(lines, thing)
  lines.shift.split("#{thing} ")[1]
end

#extract_hash(lines, type) ⇒ Object



101
102
103
104
105
106
107
108
# File 'lib/libdolt/git/blame.rb', line 101

def extract_hash(lines, type)
  {
    :name => extract(lines, "#{type}"),
    :mail => extract(lines, "#{type}-mail").gsub(/[<>]/, ""),
    :time => (Time.at(extract(lines, "#{type}-time").to_i).utc +
              Time.zone_offset(extract(lines, "#{type}-tz")))
  }
end

#extract_header(lines) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
# File 'lib/libdolt/git/blame.rb', line 66

def extract_header(lines)
  header = lines.shift
  pieces = header.scan(/^([0-9a-f]{40}) (\d+) (\d+) (\d+)$/).first
  header = { :oid => pieces.first, :num_lines => pieces[3].to_i }

  if lines.first =~ /^author/
    header[:author] = extract_hash(lines, :author)
    header[:committer] = extract_hash(lines, :committer)
    header[:summary] = extract(lines, "summary")
    throwaway = lines.shift until throwaway =~ /^filename/
    @commits[header[:oid]] = header
  else
    header[:author] = @commits[header[:oid]][:author]
    header[:committer] = @commits[header[:oid]][:committer]
    header[:summary] = @commits[header[:oid]][:summary]
  end

  header
end

#extract_lines(lines, num) ⇒ Object



86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/libdolt/git/blame.rb', line 86

def extract_lines(lines, num)
  extracted = []

  num.times do
    if extracted.length > 0
      line = lines.shift # Header for next line
    end

    content = lines.shift # Actual content
    extracted.push(content[1..content.length]) # 8 spaces padding
  end

  extracted
end

#is_header?(line) ⇒ Boolean

Returns:

  • (Boolean)


62
63
64
# File 'lib/libdolt/git/blame.rb', line 62

def is_header?(line)
  line =~ /^[0-9a-f]{40} \d+ \d+ \d+$/
end

#parseObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/libdolt/git/blame.rb', line 41

def parse
  lines = @output.split("\n")
  chunks = []

  while lines.length > 0
    chunk = extract_header(lines)
    affected_lines = extract_lines(lines, chunk[:num_lines])

    if chunks.last && chunk[:oid] == chunks.last[:oid]
      chunks.last[:lines].concat(affected_lines)
    else
      chunk[:lines] = affected_lines
      chunks << chunk
    end
  end

  chunks
rescue Exception => error
  raise InvalidBlameFormat.new("Failed parsing Procelain: #{error.message}")
end