file.rb 3.0 KB
Newer Older
D
Dmitriy Zaporozhets 已提交
1 2 3
module Gitlab
  module Diff
    class File
4
      attr_reader :diff, :repository, :diff_refs
D
Dmitriy Zaporozhets 已提交
5 6

      delegate :new_file, :deleted_file, :renamed_file,
7
        :old_path, :new_path, :a_mode, :b_mode,
8
        :submodule?, :too_large?, :collapsed?, to: :diff, prefix: false
D
Dmitriy Zaporozhets 已提交
9

10
      def initialize(diff, repository:, diff_refs: nil)
D
Dmitriy Zaporozhets 已提交
11
        @diff = diff
12
        @repository = repository
13 14 15
        @diff_refs = diff_refs
      end

D
Douwe Maan 已提交
16 17 18 19 20 21 22 23
      def position(line)
        return unless diff_refs

        Position.new(
          old_path: old_path,
          new_path: new_path,
          old_line: line.old_line,
          new_line: line.new_line,
24
          diff_refs: diff_refs
D
Douwe Maan 已提交
25 26 27
        )
      end

28 29 30 31 32 33 34 35 36 37
      def line_code(line)
        return if line.meta?

        Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
      end

      def line_for_line_code(code)
        diff_lines.find { |line| line_code(line) == code }
      end

D
Douwe Maan 已提交
38 39 40 41 42 43 44 45 46 47 48 49 50 51
      def line_for_position(pos)
        diff_lines.find { |line| position(line) == pos }
      end

      def position_for_line_code(code)
        line = line_for_line_code(code)
        position(line) if line
      end

      def line_code_for_position(pos)
        line = line_for_position(pos)
        line_code(line) if line
      end

D
Douwe Maan 已提交
52 53
      def content_commit
        return unless diff_refs
54

D
Douwe Maan 已提交
55 56 57
        repository.commit(deleted_file ? old_ref : new_ref)
      end

58
      def old_ref
59
        diff_refs.try(:base_sha)
60 61 62
      end

      def new_ref
63
        diff_refs.try(:head_sha)
D
Dmitriy Zaporozhets 已提交
64 65
      end

66
      attr_writer :highlighted_diff_lines
67

68
      # Array of Gitlab::Diff::Line objects
D
Dmitriy Zaporozhets 已提交
69
      def diff_lines
70
        @diff_lines ||= Gitlab::Diff::Parser.new.parse(raw_diff.each_line).to_a
71 72
      end

73
      def highlighted_diff_lines
74
        @highlighted_diff_lines ||= Gitlab::Diff::Highlight.new(self, repository: self.repository).highlight
75 76
      end

77
      # Array[<Hash>] with right/left keys that contains Gitlab::Diff::Line objects which text is hightlighted
78
      def parallel_diff_lines
79
        @parallel_diff_lines ||= Gitlab::Diff::ParallelDiff.new(self).parallelize
80 81
      end

D
Dmitriy Zaporozhets 已提交
82
      def mode_changed?
83
        a_mode && b_mode && a_mode != b_mode
D
Dmitriy Zaporozhets 已提交
84 85
      end

86
      def raw_diff
87
        diff.diff.to_s
88 89
      end

D
Dmitriy Zaporozhets 已提交
90 91 92 93 94
      def next_line(index)
        diff_lines[index + 1]
      end

      def prev_line(index)
95
        diff_lines[index - 1] if index > 0
D
Dmitriy Zaporozhets 已提交
96
      end
97

D
Douwe Maan 已提交
98 99 100 101
      def paths
        [old_path, new_path].compact
      end

102
      def file_path
103
        new_path.presence || old_path
104
      end
105 106

      def added_lines
G
Gabriel Mazetto 已提交
107
        diff_lines.count(&:added?)
108 109 110
      end

      def removed_lines
G
Gabriel Mazetto 已提交
111
        diff_lines.count(&:removed?)
112
      end
D
Douwe Maan 已提交
113 114 115 116 117 118 119 120 121 122 123 124

      def old_blob(commit = content_commit)
        return unless commit

        parent_id = commit.parent_id
        return unless parent_id

        repository.blob_at(parent_id, old_path)
      end

      def blob(commit = content_commit)
        return unless commit
125

D
Douwe Maan 已提交
126 127
        repository.blob_at(commit.id, file_path)
      end
128 129 130 131

      def cache_key
        "#{file_path}-#{new_file}-#{deleted_file}-#{renamed_file}"
      end
D
Dmitriy Zaporozhets 已提交
132 133 134
    end
  end
end