gitlab-org--gitlab-foss/lib/gitlab/diff/file.rb

183 lines
4.3 KiB
Ruby
Raw Normal View History

module Gitlab
module Diff
class File
attr_reader :diff, :repository, :diff_refs, :fallback_diff_refs
delegate :new_file?, :deleted_file?, :renamed_file?,
:old_path, :new_path, :a_mode, :b_mode, :mode_changed?,
:submodule?, :too_large?, :collapsed?, to: :diff, prefix: false
def initialize(diff, repository:, diff_refs: nil, fallback_diff_refs: nil)
@diff = diff
@repository = repository
@diff_refs = diff_refs
@fallback_diff_refs = fallback_diff_refs
end
2016-06-20 17:17:25 +00:00
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,
diff_refs: diff_refs
2016-06-20 17:17:25 +00:00
)
end
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
2016-06-20 17:17:25 +00:00
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
def old_sha
diff_refs&.base_sha
end
def new_sha
diff_refs&.head_sha
end
def new_content_sha
return if deleted_file?
return @new_content_sha if defined?(@new_content_sha)
refs = diff_refs || fallback_diff_refs
@new_content_sha = refs&.head_sha
end
def new_content_commit
return @new_content_commit if defined?(@new_content_commit)
sha = new_content_commit
@new_content_commit = repository.commit(sha) if sha
end
def old_content_sha
return if new_file?
return @old_content_sha if defined?(@old_content_sha)
refs = diff_refs || fallback_diff_refs
@old_content_sha = refs&.base_sha
2016-06-20 16:54:53 +00:00
end
def old_content_commit
return @old_content_commit if defined?(@old_content_commit)
sha = old_content_sha
@old_content_commit = repository.commit(sha) if sha
end
def new_blob
return @new_blob if defined?(@new_blob)
sha = new_content_sha
return @new_blob = nil unless sha
@new_blob = repository.blob_at(sha, file_path)
end
def old_blob
return @old_blob if defined?(@old_blob)
sha = old_content_sha
return @old_blob = nil unless sha
@old_blob = repository.blob_at(sha, old_path)
end
def content_sha
new_content_sha || old_content_sha
end
def content_commit
new_content_commit || old_content_commit
end
def blob
new_blob || old_blob
end
attr_writer :highlighted_diff_lines
# Array of Gitlab::Diff::Line objects
def diff_lines
@diff_lines ||= Gitlab::Diff::Parser.new.parse(raw_diff.each_line).to_a
end
def highlighted_diff_lines
@highlighted_diff_lines ||= Gitlab::Diff::Highlight.new(self, repository: self.repository).highlight
end
# Array[<Hash>] with right/left keys that contains Gitlab::Diff::Line objects which text is hightlighted
def parallel_diff_lines
@parallel_diff_lines ||= Gitlab::Diff::ParallelDiff.new(self).parallelize
end
def raw_diff
diff.diff.to_s
end
def next_line(index)
diff_lines[index + 1]
end
def prev_line(index)
diff_lines[index - 1] if index > 0
end
2016-06-20 17:17:25 +00:00
def paths
[old_path, new_path].compact
end
def file_path
new_path.presence || old_path
end
def added_lines
2015-12-15 02:53:52 +00:00
diff_lines.count(&:added?)
end
def removed_lines
2015-12-15 02:53:52 +00:00
diff_lines.count(&:removed?)
end
2016-06-20 16:54:53 +00:00
def file_identifier
"#{file_path}-#{new_file?}-#{deleted_file?}-#{renamed_file?}"
end
def diffable?
repository.attributes(file_path).fetch('diff') { true }
end
def binary?
old_blob&.binary? || new_blob&.binary?
end
def text?
!binary?
end
end
end
end