Sha256: 621783577ab727c9a38b37a45a1c5d807242e4bfc9553e3264f56049c6cb219b

Contents?: true

Size: 1.55 KB

Versions: 3

Compression:

Stored size: 1.55 KB

Contents

require_relative 'diff/file'

module GitCrecord
  module Diff
    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

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

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

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

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

    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

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

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

Version data entries

3 entries across 3 versions & 1 rubygems

Version Path
git-crecord-1.0.5 lib/git_crecord/diff.rb
git-crecord-1.0.4 lib/git_crecord/diff.rb
git-crecord-1.0.3 lib/git_crecord/diff.rb