diff options
Diffstat (limited to 'lib/gitlab/diff/custom_diff.rb')
-rw-r--r-- | lib/gitlab/diff/custom_diff.rb | 58 |
1 files changed, 58 insertions, 0 deletions
diff --git a/lib/gitlab/diff/custom_diff.rb b/lib/gitlab/diff/custom_diff.rb new file mode 100644 index 00000000000..3928ece9281 --- /dev/null +++ b/lib/gitlab/diff/custom_diff.rb @@ -0,0 +1,58 @@ +# frozen_string_literal: true +module Gitlab + module Diff + module CustomDiff + class << self + def preprocess_before_diff(path, old_blob, new_blob) + return unless path.ends_with? '.ipynb' + + transformed_diff(old_blob&.data, new_blob&.data)&.tap do + transformed_for_diff(new_blob, old_blob) + Gitlab::AppLogger.info({ message: 'IPYNB_DIFF_GENERATED' }) + end + rescue IpynbDiff::InvalidNotebookError => e + Gitlab::ErrorTracking.log_exception(e) + nil + end + + def transformed_diff(before, after) + transformed_diff = IpynbDiff.diff(before, after, + diff_opts: { context: 5, include_diff_info: true }, + transform_options: { cell_decorator: :percent }, + raise_if_invalid_notebook: true) + strip_diff_frontmatter(transformed_diff) + end + + def transformed_blob_language(blob) + 'md' if transformed_for_diff?(blob) + end + + def transformed_blob_data(blob) + if transformed_for_diff?(blob) + IpynbDiff.transform(blob.data, + raise_errors: true, + options: { include_metadata: false, cell_decorator: :percent }) + end + end + + def strip_diff_frontmatter(diff_content) + diff_content.scan(/.*\n/)[2..]&.join('') if diff_content.present? + end + + def blobs_with_transformed_diffs + @blobs_with_transformed_diffs ||= {} + end + + def transformed_for_diff?(blob) + blobs_with_transformed_diffs[blob] + end + + def transformed_for_diff(*blobs) + blobs.each do |b| + blobs_with_transformed_diffs[b] = true if b + end + end + end + end + end +end |