Module: GitCrecord::Diff

Defined in:
lib/git_crecord/diff.rb,
lib/git_crecord/diff/file.rb,
lib/git_crecord/diff/hunk.rb,
lib/git_crecord/diff/line.rb,
lib/git_crecord/diff/difference.rb

Defined Under Namespace

Classes: Difference, File, Hunk, Line, PseudoLine

Class Method Summary collapse

Class Method Details

.file_encoding(filename) ⇒ Object



60
61
62
# File 'lib/git_crecord/diff.rb', line 60

def self.file_encoding(filename)
  `file --mime-encoding #{filename}`.split(': ', 2)[1].chomp
end

.file_lines(filename) ⇒ Object



64
65
66
67
68
# File 'lib/git_crecord/diff.rb', line 64

def self.file_lines(filename)
  encoding = file_encoding(filename)
  return [[], 'binary'] if encoding == 'binary'
  [::File.open(filename, "r:#{encoding}", &:readlines), nil]
end

.file_start?(line) ⇒ Boolean

Returns:

  • (Boolean)


18
19
20
# File 'lib/git_crecord/diff.rb', line 18

def self.file_start?(line)
  line.start_with?('diff')
end

.hunk_start?(line) ⇒ Boolean

Returns:

  • (Boolean)


22
23
24
# File 'lib/git_crecord/diff.rb', line 22

def self.hunk_start?(line)
  line.start_with?('@@')
end

.parse(diff) ⇒ Object



5
6
7
8
9
10
11
12
13
14
15
16
# File 'lib/git_crecord/diff.rb', line 5

def self.parse(diff)
  files = []
  enum = diff.lines.each
  loop do
    line = enum.next
    line.chomp!
    next files << parse_file_header(line, enum) if file_start?(line)
    next files[-1] << line if hunk_start?(line)
    files[-1].add_hunk_line(line)
  end
  files
end

.parse_file_header(line, enum) ⇒ Object



26
27
28
29
30
31
# File 'lib/git_crecord/diff.rb', line 26

def self.parse_file_header(line, enum)
  enum.next # index ...
  enum.next # --- ...
  enum.next # +++ ...
  File.new(*parse_filenames(line))
end

.parse_filenames(line) ⇒ Object



33
34
35
# File 'lib/git_crecord/diff.rb', line 33

def self.parse_filenames(line)
  line.match(%r{a/(.*) b/(.*)$})[1..2]
end

.untracked_dir(path) ⇒ Object



54
55
56
57
58
# File 'lib/git_crecord/diff.rb', line 54

def self.untracked_dir(path)
  Dir.glob(::File.join(path, '**/*')).map do |filename|
    untracked_file(filename) unless ::File.directory?(filename)
  end
end

.untracked_file(filename) ⇒ Object



44
45
46
47
48
49
50
51
52
# File 'lib/git_crecord/diff.rb', line 44

def self.untracked_file(filename)
  File.new(filename, filename, type: :untracked).tap do |file|
    lines, err = file_lines(filename)
    file << "@@ -0,0 +1,#{lines.size} @@"
    file.subs[0].subs << PseudoLine.new(err) if lines.empty?
    lines.each{ |line| file.add_hunk_line("+#{line.chomp}") }
    file.selected = false
  end
end

.untracked_files(git_status) ⇒ Object



37
38
39
40
41
42
# File 'lib/git_crecord/diff.rb', line 37

def self.untracked_files(git_status)
  git_status.lines.select{ |l| l.start_with?('??') }.flat_map do |path|
    path = path.chomp[3..-1]
    ::File.directory?(path) ? untracked_dir(path) : untracked_file(path)
  end.compact
end