Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGitLab Bot <gitlab-bot@gitlab.com>2022-06-15 18:09:20 +0300
committerGitLab Bot <gitlab-bot@gitlab.com>2022-06-15 18:09:20 +0300
commit9440c17f554424cc77aff8afadc61adbe23524d1 (patch)
treebc2b4213d845e5fd6d43eb71d21cfce28c81e440 /lib/gitlab/diff
parent3e0c035fe3a10436be36b4e22a4986479821b8e4 (diff)
Add latest changes from gitlab-org/gitlab@master
Diffstat (limited to 'lib/gitlab/diff')
-rw-r--r--lib/gitlab/diff/rendered/notebook/diff_file.rb36
-rw-r--r--lib/gitlab/diff/rendered/notebook/diff_file_helper.rb135
2 files changed, 94 insertions, 77 deletions
diff --git a/lib/gitlab/diff/rendered/notebook/diff_file.rb b/lib/gitlab/diff/rendered/notebook/diff_file.rb
index 99631d90ce6..0795e0acebb 100644
--- a/lib/gitlab/diff/rendered/notebook/diff_file.rb
+++ b/lib/gitlab/diff/rendered/notebook/diff_file.rb
@@ -50,12 +50,14 @@ module Gitlab
end
def highlighted_diff_lines
- @highlighted_diff_lines ||= begin
- removal_line_maps, addition_line_maps = map_diff_block_to_source_line(
- source_diff.highlighted_diff_lines, source_diff.new_file?, source_diff.deleted_file?)
- Gitlab::Diff::Highlight.new(self, repository: self.repository).highlight.map do |line|
- mutate_line(line, addition_line_maps, removal_line_maps)
- end
+ strong_memoize(:highlighted_diff_lines) do
+ lines = Gitlab::Diff::Highlight.new(self, repository: self.repository).highlight
+ lines_in_source = lines_in_source_diff(
+ source_diff.highlighted_diff_lines, source_diff.deleted_file?, source_diff.new_file?
+ )
+
+ lines.zip(line_positions_at_source_diff(lines, transformed_blocks))
+ .map { |line, positions| mutate_line(line, positions, lines_in_source)}
end
end
@@ -91,6 +93,10 @@ module Gitlab
diff
end
+ def transformed_blocks
+ { from: notebook_diff.from.blocks, to: notebook_diff.to.blocks }
+ end
+
def rendered_timeout
@rendered_timeout ||= Gitlab::Metrics.counter(
:ipynb_semantic_diff_timeouts_total,
@@ -108,21 +114,13 @@ module Gitlab
nil
end
- def compute_line_numbers(transformed_old_pos, transformed_new_pos, addition_line_maps, removal_line_maps)
- new_pos = map_transformed_line_to_source(transformed_new_pos, notebook_diff.to.blocks)
- old_pos = map_transformed_line_to_source(transformed_old_pos, notebook_diff.from.blocks)
-
- old_pos = addition_line_maps[new_pos] if old_pos == 0 && new_pos != 0
- new_pos = removal_line_maps[old_pos] if new_pos == 0 && old_pos != 0
-
- [old_pos, new_pos]
- end
-
- def mutate_line(line, addition_line_maps, removal_line_maps)
- line.old_pos, line.new_pos = compute_line_numbers(line.old_pos, line.new_pos, addition_line_maps, removal_line_maps)
+ def mutate_line(line, mapped_positions, source_diff_lines)
+ line.old_pos, line.new_pos = mapped_positions
# Lines that do not appear on the original diff should not be commentable
- line.type = "#{line.type || 'unchanged'}-nomappinginraw" unless addition_line_maps[line.new_pos] || removal_line_maps[line.old_pos]
+ unless source_diff_lines[:to].include?(line.new_pos) || source_diff_lines[:from].include?(line.old_pos)
+ line.type = "#{line.type || 'unchanged'}-nomappinginraw"
+ end
line.line_code = line_code(line)
diff --git a/lib/gitlab/diff/rendered/notebook/diff_file_helper.rb b/lib/gitlab/diff/rendered/notebook/diff_file_helper.rb
index 822b3771276..2e1b5ea301d 100644
--- a/lib/gitlab/diff/rendered/notebook/diff_file_helper.rb
+++ b/lib/gitlab/diff/rendered/notebook/diff_file_helper.rb
@@ -4,75 +4,94 @@ module Gitlab
module Rendered
module Notebook
module DiffFileHelper
+ require 'set'
+
EMBEDDED_IMAGE_PATTERN = ' ![](data:image'
def strip_diff_frontmatter(diff_content)
diff_content.scan(/.*\n/)[2..]&.join('') if diff_content.present?
end
- def map_transformed_line_to_source(transformed_line, transformed_blocks)
- transformed_blocks.empty? ? 0 : ( transformed_blocks[transformed_line - 1][:source_line] || -1 ) + 1
- end
-
- # line_codes are used for assigning notes to diffs, and these depend on the line on the new version and the
- # line that would have been that one in the previous version. However, since we do a transformation on the
- # file, that mapping gets lost. To overcome this, we look at the original source lines and build two maps:
- # - For additions, we look at the latest line change for that line and pick the old line for that id
- # - For removals, we look at the first line in the old version, and pick the first line on the new version
- #
- # Note: ipynb files never change the first or last line (open and closure of the
- # json object), unless the file is removed or deleted
- #
- # Example: Additions and removals
- # Old: New:
- # A A
- # B D
- # C E
- # F F
+ # line_positions_at_source_diff: given the transformed lines,
+ # what are the correct values for old_pos and new_pos?
#
- # Diff:
- # 1 A A 1 | line code: 1_1
- # 2 -B | line code: 2_2 -> new line is what it is after been without the removal, 2
- # 3 -C | line code: 3_2
- # + D 2 | line code: 4_2 -> old line is what would have been before the addition, 4
- # + E 3 | line code: 4_3
- # 4 F F 4 | line code: 4_4
+ # Example:
#
- # Example: only additions
- # Old: New:
- # A A
- # F B
- # C
- # F
+ # Original
+ # from | to
+ # A | A
+ # B | D
+ # C | E
+ # F | F
#
- # Diff:
- # A A | line code: 1_1
- # + B | line code: 2_2 -> old line is the next after the additions, 2
- # + C | line code: 2_3
- # F F | line code: 2_4
+ # Original Diff
+ # A A
+ # - B
+ # - C
+ # + D
+ # + E
+ # F F
#
- # Example: only removals
- # Old: New:
- # A A
- # B F
- # C
- # F
+ # Transformed
+ # from | to
+ # A | A
+ # C | D
+ # B | J
+ # L | E
+ # K | K
+ # F | F
#
- # Diff:
- # A A | line code: 1_1
- # -B | line code: 2_2 -> new line is what it is after been without the removal, 2
- # -C | line code: 3_2
- # F F | line code: 4_2
- def map_diff_block_to_source_line(lines, file_added, file_deleted)
- removals = {}
- additions = {}
-
- lines.each do |line|
- removals[line.old_pos] = line.new_pos unless file_added
- additions[line.new_pos] = line.old_pos unless file_deleted
- end
-
- [removals, additions]
+ # Transformed diff | transf old, new | OG old_pos, new_pos |
+ # A A | 1, 1 | 1, 1 |
+ # -C | 2, 2 | 3, 2 |
+ # -B | 3, 2 | 2, 2 |
+ # -L | 4, 2 | 0, 0 |
+ # + D | 5, 2 | 4, 2 |
+ # + J | 5, 3 | 0, 0 |
+ # + E | 5, 4 | 4, 3 |
+ # K K | 5, 5 | 0, 0 |
+ # F F | 6, 6 | 4, 4 |
+ def line_positions_at_source_diff(lines, blocks)
+ last_mapped_old_pos = 0
+ last_mapped_new_pos = 0
+
+ lines.reverse_each.map do |line|
+ old_pos = source_line_from_block(line.old_pos, blocks[:from])
+ new_pos = source_line_from_block(line.new_pos, blocks[:to])
+
+ old_has_no_mapping = old_pos == 0
+ new_has_no_mapping = new_pos == 0
+
+ next [0, 0] if old_has_no_mapping && (new_has_no_mapping || line.type == 'old')
+ next [0, 0] if new_has_no_mapping && line.type == 'new'
+
+ new_pos = last_mapped_new_pos if new_has_no_mapping && line.type == 'old'
+ old_pos = last_mapped_old_pos if old_has_no_mapping && line.type == 'new'
+
+ last_mapped_old_pos = old_pos
+ last_mapped_new_pos = new_pos
+
+ [old_pos, new_pos]
+ end.reverse
+ end
+
+ def lines_in_source_diff(source_diff_lines, is_deleted_file, is_added_file)
+ {
+ from: is_added_file ? Set[] : source_diff_lines.map {|l| l.old_pos}.to_set,
+ to: is_deleted_file ? Set[] : source_diff_lines.map {|l| l.new_pos}.to_set
+ }
+ end
+
+ def source_line_from_block(transformed_line, transformed_blocks)
+ # Blocks are the lines returned from the library and are a hash with {text:, source_line:}
+ # Blocks source_line are 0 indexed
+ return 0 if transformed_blocks.empty?
+
+ line_in_source = transformed_blocks[transformed_line - 1][:source_line]
+
+ return 0 unless line_in_source.present?
+
+ line_in_source + 1
end
def image_as_rich_text(line_text)