summaryrefslogtreecommitdiff
path: root/app/serializers/diff_file_entity.rb
blob: a893a5a4b7c6d058e7a220f7154d5631bd15f4e2 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
class DiffFileEntity < Grape::Entity
  include RequestAwareEntity
  include ActionView::Helpers::TagHelper
  include BlobHelper
  include CommitsHelper
  include DiffHelper
  include SubmoduleHelper
  include BlobHelper
  include IconsHelper
  include TreeHelper
  include ChecksCollaboration
  include Gitlab::Utils::StrongMemoize

  expose :submodule?, as: :submodule

  expose :submodule_link do |diff_file|
    memoized_submodule_links(diff_file).first
  end

  expose :submodule_tree_url do |diff_file|
    memoized_submodule_links(diff_file).last
  end

  expose :blob, using: BlobEntity

  # TODO move this into BlobEntity?
  expose :can_modify_blob do |diff_file|
    merge_request = options[:merge_request]

    if merge_request && merge_request.source_project && current_user
      can_modify_blob?(diff_file.blob, merge_request.source_project, merge_request.source_branch)
    else
      false
    end
  end

  expose :file_hash do |diff_file|
    Digest::SHA1.hexdigest(diff_file.file_path)
  end

  expose :file_path
  expose :too_large?, as: :too_large
  expose :collapsed?, as: :collapsed
  expose :new_file?, as: :new_file

  expose :deleted_file?, as: :deleted_file
  expose :renamed_file?, as: :renamed_file
  expose :old_path
  expose :new_path
  expose :mode_changed?, as: :mode_changed
  expose :a_mode
  expose :b_mode
  expose :text?, as: :text
  expose :added_lines
  expose :removed_lines
  expose :diff_refs
  expose :content_sha
  expose :stored_externally?, as: :stored_externally
  expose :external_storage

  expose :load_collapsed_diff_url, if: -> (diff_file, options) { diff_file.text? && options[:merge_request] } do |diff_file|
    merge_request = options[:merge_request]
    project = merge_request.source_project

    if project
      diff_for_path_namespace_project_merge_request_path(
        namespace_id: project.namespace.to_param,
        project_id: project.to_param,
        id: merge_request.iid,
        old_path: diff_file.old_path,
        new_path: diff_file.new_path,
        file_identifier: diff_file.file_identifier
      )
    end
  end

  expose :formatted_external_url, if: -> (_, options) { options[:environment] } do |diff_file|
    options[:environment].formatted_external_url
  end

  # TODO imon/Fatih/Winnie - Are we using this? - if not please remove
  expose :external_url, if: -> (_, options) { options[:environment] } do |diff_file|
    options[:environment].external_url_for(diff_file.new_path, diff_file.content_sha)
  end

  expose :old_path_html do |diff_file|
    old_path = mark_inline_diffs(diff_file.old_path, diff_file.new_path)
    old_path
  end

  expose :new_path_html do |diff_file|
    _, new_path = mark_inline_diffs(diff_file.old_path, diff_file.new_path)
    new_path
  end

  expose :edit_path, if: -> (_, options) { options[:merge_request] } do |diff_file|
    merge_request = options[:merge_request]

    options = merge_request.persisted? ? { from_merge_request_iid: merge_request.iid } : {}

    if merge_request.source_project
      project_edit_blob_path(merge_request.source_project,
        tree_join(merge_request.source_branch, diff_file.new_path),
        options)
    end
  end

  expose :view_path, if: -> (_, options) { options[:merge_request] } do |diff_file|
    merge_request = options[:merge_request]

    if merge_request.source_project
      project_blob_path(merge_request.source_project, tree_join(diff_file.content_sha, diff_file.new_path))
    end
  end

  expose :replaced_view_path, if: -> (_, options) { options[:merge_request] } do |diff_file|
    image_diff = diff_file.rich_viewer && diff_file.rich_viewer.partial_name == 'image'
    image_replaced = diff_file.old_content_sha && diff_file.old_content_sha != diff_file.content_sha

    merge_request = options[:merge_request]

    if merge_request.source_project
      project_blob_path(merge_request.source_project, tree_join(diff_file.old_content_sha, diff_file.old_path)) if image_diff && image_replaced
    end
  end

  expose :context_lines_path, if: -> (diff_file, _) { diff_file.text? } do |diff_file|
    project_blob_diff_path(diff_file.repository.project, tree_join(diff_file.content_sha, diff_file.file_path))
  end

  # Used for inline diffs
  expose :highlighted_diff_lines, if: -> (diff_file, _) { diff_file.text? } do |diff_file|
    diff_file.diff_lines_for_serializer
  end

  # Used for parallel diffs
  expose :parallel_diff_lines, if: -> (diff_file, _) { diff_file.text? }

  def current_user
    request.current_user
  end

  def memoized_submodule_links(diff_file)
    strong_memoize(:submodule_links) do
      if diff_file.submodule?
        submodule_links(diff_file.blob, diff_file.content_sha, diff_file.repository)
      else
        []
      end
    end
  end
end