Skip to content
Snippets Groups Projects
Commit 7848d54f authored by Douwe Maan's avatar Douwe Maan
Browse files

Clean up LegacyDiffNote somewhat

parent 9a3ed265
No related branches found
No related tags found
No related merge requests found
Loading
@@ -23,42 +23,65 @@ class LegacyDiffNote < Note
Loading
@@ -23,42 +23,65 @@ class LegacyDiffNote < Note
@discussion_id ||= self.class.build_discussion_id(noteable_type, noteable_id || commit_id, line_code, active?) @discussion_id ||= self.class.build_discussion_id(noteable_type, noteable_id || commit_id, line_code, active?)
end end
   
def find_diff def diff_file_hash
return nil unless noteable line_code.split('_')[0] if line_code
return @diff if defined?(@diff)
# Don't use ||= because nil is a valid value for @diff
@diff = noteable.diffs(Commit.max_diff_options).find do |d|
Digest::SHA1.hexdigest(d.new_path) == diff_file_index if d.new_path
end
end end
   
def set_diff def diff_old_line
# First lets find notes with same diff line_code.split('_')[1].to_i if line_code
# before iterating over all mr diffs end
diff = diff_for_line_code unless for_merge_request?
diff ||= find_diff
   
self.st_diff = diff.to_hash if diff def diff_new_line
line_code.split('_')[2].to_i if line_code
end end
   
def diff def diff
@diff ||= Gitlab::Git::Diff.new(st_diff) if st_diff.respond_to?(:map) @diff ||= Gitlab::Git::Diff.new(st_diff) if st_diff.respond_to?(:map)
end end
   
def diff_for_line_code def diff_file_path
attributes = { diff.new_path.presence || diff.old_path
noteable_type: noteable_type, end
line_code: line_code
}
   
if for_commit? def diff_lines
attributes[:commit_id] = commit_id @diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.each_line)
end
def diff_line
@diff_line ||= diff_lines.find { |line| generate_line_code(line) == self.line_code }
end
def diff_line_text
diff_line.try(:text)
end
def diff_line_type
diff_line.try(:type)
end
def highlighted_diff_lines
Gitlab::Diff::Highlight.new(diff_lines).highlight
end
def truncated_diff_lines
max_number_of_lines = 16
prev_match_line = nil
prev_lines = []
highlighted_diff_lines.each do |line|
if line.type == "match"
prev_lines.clear
prev_match_line = line
else else
attributes[:noteable_id] = noteable_id prev_lines << line
break if generate_line_code(line) == self.line_code
prev_lines.shift if prev_lines.length >= max_number_of_lines
end
end end
   
self.class.where(attributes).last.try(:diff) prev_lines
end end
   
# Check if this note is part of an "active" discussion # Check if this note is part of an "active" discussion
Loading
@@ -69,17 +92,17 @@ class LegacyDiffNote < Note
Loading
@@ -69,17 +92,17 @@ class LegacyDiffNote < Note
# If the note's current diff cannot be matched in the MergeRequest's current # If the note's current diff cannot be matched in the MergeRequest's current
# diff, it's considered inactive. # diff, it's considered inactive.
def active? def active?
return @active if defined?(@active)
return true if for_commit? return true if for_commit?
return true unless self.diff return true unless self.diff
return false unless noteable return false unless noteable
return @active if defined?(@active)
   
noteable_diff = find_noteable_diff noteable_diff = find_noteable_diff
   
if noteable_diff if noteable_diff
parsed_lines = Gitlab::Diff::Parser.new.parse(noteable_diff.diff.each_line) parsed_lines = Gitlab::Diff::Parser.new.parse(noteable_diff.diff.each_line)
   
@active = parsed_lines.any? { |line_obj| line_obj.text == diff_line } @active = parsed_lines.any? { |line_obj| line_obj.text == diff_line_text }
else else
@active = false @active = false
end end
Loading
@@ -87,93 +110,45 @@ class LegacyDiffNote < Note
Loading
@@ -87,93 +110,45 @@ class LegacyDiffNote < Note
@active @active
end end
   
def diff_file_index private
line_code.split('_')[0] if line_code
end
def diff_file_name
diff.new_path if diff
end
def file_path
if diff.new_path.present?
diff.new_path
elsif diff.old_path.present?
diff.old_path
end
end
def diff_old_line
line_code.split('_')[1].to_i if line_code
end
def diff_new_line
line_code.split('_')[2].to_i if line_code
end
def generate_line_code(line)
Gitlab::Diff::LineCode.generate(file_path, line.new_pos, line.old_pos)
end
   
def diff_line def find_diff
return @diff_line if @diff_line return nil unless noteable
return @diff if defined?(@diff)
   
if diff @diff = noteable.diffs(Commit.max_diff_options).find do |d|
diff_lines.each do |line| d.new_path && Digest::SHA1.hexdigest(d.new_path) == diff_file_hash
if generate_line_code(line) == self.line_code
@diff_line = line.text
end
end
end end
@diff_line
end end
   
def diff_line_type def set_diff
return @diff_line_type if @diff_line_type # First lets find notes with same diff
# before iterating over all mr diffs
if diff diff = diff_for_line_code unless for_merge_request?
diff_lines.each do |line| diff ||= find_diff
if generate_line_code(line) == self.line_code
@diff_line_type = line.type
end
end
end
   
@diff_line_type self.st_diff = diff.to_hash if diff
end end
   
def truncated_diff_lines def diff_for_line_code
max_number_of_lines = 16 attributes = {
prev_match_line = nil noteable_type: noteable_type,
prev_lines = [] line_code: line_code
}
   
highlighted_diff_lines.each do |line| if for_commit?
if line.type == "match" attributes[:commit_id] = commit_id
prev_lines.clear
prev_match_line = line
else else
prev_lines << line attributes[:noteable_id] = noteable_id
break if generate_line_code(line) == self.line_code
prev_lines.shift if prev_lines.length >= max_number_of_lines
end
end
prev_lines
end end
   
def diff_lines self.class.where(attributes).last.try(:diff)
@diff_lines ||= Gitlab::Diff::Parser.new.parse(diff.diff.each_line)
end end
   
def highlighted_diff_lines def generate_line_code(line)
Gitlab::Diff::Highlight.new(diff_lines).highlight Gitlab::Diff::LineCode.generate(diff_file_path, line.new_pos, line.old_pos)
end end
   
private
# Find the diff on noteable that matches our own # Find the diff on noteable that matches our own
def find_noteable_diff def find_noteable_diff
diffs = noteable.diffs(Commit.max_diff_options) diffs = noteable.diffs(Commit.max_diff_options)
Loading
Loading
Loading
@@ -112,6 +112,10 @@ class Note < ActiveRecord::Base
Loading
@@ -112,6 +112,10 @@ class Note < ActiveRecord::Base
false false
end end
   
def active?
true
end
def discussion_id def discussion_id
@discussion_id ||= @discussion_id ||=
if for_merge_request? if for_merge_request?
Loading
Loading
- if @note.legacy_diff_note? - if @note.legacy_diff_note?
%p.details %p.details
New comment on diff for New comment on diff for
= link_to @note.diff_file_name, @target_url = link_to @note.diff_file_path, @target_url
\: \:
   
= render 'note_message' = render 'note_message'
Loading
@@ -15,7 +15,7 @@
Loading
@@ -15,7 +15,7 @@
%table %table
- note.truncated_diff_lines.each do |line| - note.truncated_diff_lines.each do |line|
- type = line.type - type = line.type
- line_code = generate_line_code(note.file_path, line) - line_code = generate_line_code(note.diff_file_path, line)
%tr.line_holder{ id: line_code, class: "#{type}" } %tr.line_holder{ id: line_code, class: "#{type}" }
- if type == "match" - if type == "match"
%td.old_line.diff-line-num= "..." %td.old_line.diff-line-num= "..."
Loading
Loading
Loading
@@ -227,7 +227,7 @@ module API
Loading
@@ -227,7 +227,7 @@ module API
   
class CommitNote < Grape::Entity class CommitNote < Grape::Entity
expose :note expose :note
expose(:path) { |note| note.diff_file_name if note.legacy_diff_note? } expose(:path) { |note| note.diff_file_path if note.legacy_diff_note? }
expose(:line) { |note| note.diff_new_line if note.legacy_diff_note? } expose(:line) { |note| note.diff_new_line if note.legacy_diff_note? }
expose(:line_type) { |note| note.diff_line_type if note.legacy_diff_note? } expose(:line_type) { |note| note.diff_line_type if note.legacy_diff_note? }
expose :author, using: Entities::UserBasic expose :author, using: Entities::UserBasic
Loading
Loading
require 'spec_helper'
describe LegacyDiffNote, models: true do
describe "Commit diff line notes" do
let!(:note) { create(:note_on_commit_diff, note: "+1 from me") }
let!(:commit) { note.noteable }
it "should save a valid note" do
expect(note.commit_id).to eq(commit.id)
expect(note.noteable.id).to eq(commit.id)
end
it "should be recognized by #legacy_diff_note?" do
expect(note).to be_legacy_diff_note
end
end
describe '#active?' do
it 'is always true when the note has no associated diff' do
note = build(:note_on_merge_request_diff)
expect(note).to receive(:diff).and_return(nil)
expect(note).to be_active
end
it 'is never true when the note has no noteable associated' do
note = build(:note_on_merge_request_diff)
expect(note).to receive(:diff).and_return(double)
expect(note).to receive(:noteable).and_return(nil)
expect(note).not_to be_active
end
it 'returns the memoized value if defined' do
note = build(:note_on_merge_request_diff)
note.instance_variable_set(:@active, 'foo')
expect(note).not_to receive(:find_noteable_diff)
expect(note.active?).to eq 'foo'
end
context 'for a merge request noteable' do
it 'is false when noteable has no matching diff' do
merge = build_stubbed(:merge_request, :simple)
note = build(:note_on_merge_request_diff, noteable: merge)
allow(note).to receive(:diff).and_return(double)
expect(note).to receive(:find_noteable_diff).and_return(nil)
expect(note).not_to be_active
end
it 'is true when noteable has a matching diff' do
merge = create(:merge_request, :simple)
# Generate a real line_code value so we know it will match. We use a
# random line from a random diff just for funsies.
diff = merge.diffs.to_a.sample
line = Gitlab::Diff::Parser.new.parse(diff.diff.each_line).to_a.sample
code = Gitlab::Diff::LineCode.generate(diff.new_path, line.new_pos, line.old_pos)
# We're persisting in order to trigger the set_diff callback
note = create(:note_on_merge_request_diff, noteable: merge, line_code: code)
# Make sure we don't get a false positive from a guard clause
expect(note).to receive(:find_noteable_diff).and_call_original
expect(note).to be_active
end
end
end
end
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment