Commit 9abcc0a9 authored by Douwe Maan's avatar Douwe Maan

Add Gitlab::Git::Position

parent a27462a5
......@@ -13,6 +13,20 @@ module Gitlab
@diff_refs = diff_refs
end
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,
base_sha: diff_refs.base_sha,
start_sha: diff_refs.start_sha,
head_sha: diff_refs.head_sha
)
end
def line_code(line)
return if line.meta?
......@@ -23,6 +37,20 @@ module Gitlab
diff_lines.find { |line| line_code(line) == code }
end
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 content_commit
return unless diff_refs
......@@ -66,6 +94,10 @@ module Gitlab
diff_lines[index - 1] if index > 0
end
def paths
[old_path, new_path].compact
end
def file_path
new_path.presence || old_path
end
......
# Defines a specific location, identified by paths and line numbers,
# within a specific diff, identified by start, head and base commit ids.
module Gitlab
module Diff
class Position
attr_reader :old_path
attr_reader :new_path
attr_reader :old_line
attr_reader :new_line
attr_reader :base_sha
attr_reader :start_sha
attr_reader :head_sha
def initialize(attrs = {})
@old_path = attrs[:old_path]
@new_path = attrs[:new_path]
@old_line = attrs[:old_line]
@new_line = attrs[:new_line]
if attrs[:diff_refs]
@base_sha = attrs[:diff_refs].base_sha
@start_sha = attrs[:diff_refs].start_sha
@head_sha = attrs[:diff_refs].head_sha
else
@base_sha = attrs[:base_sha]
@start_sha = attrs[:start_sha]
@head_sha = attrs[:head_sha]
end
end
def init_with(coder)
initialize(coder['attributes'])
self
end
def encode_with(coder)
coder['attributes'] = self.to_h
end
def key
@key ||= [base_sha, start_sha, head_sha, Digest::SHA1.hexdigest(old_path || ""), Digest::SHA1.hexdigest(new_path || ""), old_line, new_line]
end
def ==(other)
other.is_a?(self.class) && key == other.key
end
def to_h
{
old_path: old_path,
new_path: new_path,
old_line: old_line,
new_line: new_line,
base_sha: base_sha,
start_sha: start_sha,
head_sha: head_sha
}
end
def inspect
%(#<#{self.class}:#{object_id} #{to_h}>)
end
def complete?
file_path.present? &&
(old_line || new_line) &&
diff_refs.complete?
end
def to_json
JSON.generate(self.to_h)
end
def type
if old_line && new_line
nil
elsif new_line
'new'
else
'old'
end
end
def unchanged?
type.nil?
end
def added?
type == 'new'
end
def removed?
type == 'old'
end
def paths
[old_path, new_path].compact.uniq
end
def file_path
new_path.presence || old_path
end
def diff_refs
@diff_refs ||= DiffRefs.new(base_sha: base_sha, start_sha: start_sha, head_sha: head_sha)
end
def diff_file(repository)
@diff_file ||= begin
if RequestStore.active?
key = {
project_id: repository.project.id,
start_sha: start_sha,
head_sha: head_sha,
path: file_path
}
RequestStore.fetch(key) { find_diff_file(repository) }
else
find_diff_file(repository)
end
end
end
def diff_line(repository)
@diff_line ||= diff_file(repository).line_for_position(self)
end
def line_code(repository)
@line_code ||= diff_file(repository).line_code_for_position(self)
end
private
def find_diff_file(repository)
diffs = Gitlab::Git::Compare.new(
repository.raw_repository,
start_sha,
head_sha
).diffs(paths: paths)
diff = diffs.first
return unless diff
Gitlab::Diff::File.new(diff, repository: repository, diff_refs: diff_refs)
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment