Advertisement
Guest User

Untitled

a guest
Apr 20th, 2015
207
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 1.66 KB | None | 0 0
  1. require 'shellwords'
  2.  
  3. class Blamify
  4. PORCELAIN_COMMIT_HASH_RE = /^(?<hash>\h{40})\s/
  5. PORCELAIN_LINE_RE = /^\t(?<line>.*)$/
  6. COLORS = (237..255).to_a # Greyscale gradient
  7.  
  8. def initialize(filename)
  9. @filename = filename
  10. end
  11.  
  12. def print(output = $stdout)
  13. committer_times = blames.map { |blame| blame[:committer_time].to_i }
  14. min_time = committer_times.min
  15. max_time = committer_times.max
  16. timespan = max_time - min_time
  17. mid_time = min_time + timespan / 2
  18.  
  19. blames.each do |blame|
  20. committer_time = blame[:committer_time].to_i
  21. offset = committer_time - min_time
  22. Time.at(committer_time)
  23. color = color_at(offset / timespan.to_f)
  24.  
  25. author = blame.fetch(:author, "")
  26. output.puts format("\e[38;5;%dm%-14s: %s\e[0m", color, author[0, 14], blame[:line])
  27. end
  28. end
  29.  
  30. private
  31.  
  32. def color_at(x)
  33. x = 0 if x.nan?
  34. x = [[x, 0.0].max, 1.0].min # Clamp to (0.0, 1.0)
  35. COLORS[(x * COLORS.size.pred).floor]
  36. end
  37.  
  38. def blames
  39. @blames ||= load_blames
  40. end
  41.  
  42. def load_blames
  43. blame_data = {}
  44.  
  45. load_porcelain.lines.each_with_object([]) do |line, blames|
  46. case line
  47. when PORCELAIN_COMMIT_HASH_RE
  48. blame_data[:commit] = $~[:hash]
  49. when PORCELAIN_LINE_RE
  50. blames << blame_data.merge(line: $~[:line])
  51. else # Key/value
  52. key, value = line.chomp.split(' ', 2)
  53. key.tr!('-', '_')
  54.  
  55. blame_data[key.to_sym] = value
  56. end
  57. end
  58. end
  59.  
  60. def load_porcelain
  61. `#{ Shellwords.shelljoin(['git', 'blame', '-p', @filename]) }`
  62. end
  63. end
  64.  
  65. if file = ARGV.first
  66. dir = File.dirname(File.expand_path(file))
  67.  
  68. Dir.chdir(dir) do
  69. Blamify.new(File.basename(file)).print
  70. end
  71. end
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement