summaryrefslogtreecommitdiff
path: root/lib/banzai/filter/references/commit_reference_filter.rb
blob: 457921bd07d09fb6b32996b8b73c2c7c18effd7c (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
# frozen_string_literal: true

module Banzai
  module Filter
    module References
      # HTML filter that replaces commit references with links.
      #
      # This filter supports cross-project references.
      class CommitReferenceFilter < AbstractReferenceFilter
        self.reference_type = :commit

        def self.object_class
          Commit
        end

        def self.references_in(text, pattern = Commit.reference_pattern)
          text.gsub(pattern) do |match|
            yield match, $~[:commit], $~[:project], $~[:namespace], $~
          end
        end

        def find_object(project, id)
          return unless project.is_a?(Project) && project.valid_repo?

          _, record = records_per_parent[project].detect { |k, _v| Gitlab::Git.shas_eql?(k, id) }

          record
        end

        def referenced_merge_request_commit_shas
          return [] unless noteable.is_a?(MergeRequest)

          @referenced_merge_request_commit_shas ||= begin
            referenced_shas = references_per_parent.values.reduce(:|).to_a
            noteable.all_commit_shas.select do |sha|
              referenced_shas.any? { |ref| Gitlab::Git.shas_eql?(sha, ref) }
            end
          end
        end

        # The default behaviour is `#to_i` - we just pass the hash through.
        def self.parse_symbol(sha_hash, _match)
          sha_hash
        end

        def url_for_object(commit, project)
          h = Gitlab::Routing.url_helpers

          if referenced_merge_request_commit_shas.include?(commit.id)
            h.diffs_project_merge_request_url(project,
                                              noteable,
                                              commit_id: commit.id,
                                              only_path: only_path?)
          else
            h.project_commit_url(project,
                                 commit,
                                 only_path: only_path?)
          end
        end

        def object_link_text_extras(object, matches)
          extras = super

          path = matches[:path] if matches.names.include?("path")
          if path == '/builds'
            extras.unshift "builds"
          end

          extras
        end

        private

        def parent_records(parent, ids)
          parent.commits_by(oids: ids.to_a)
        end

        def noteable
          context[:noteable]
        end

        def only_path?
          context[:only_path]
        end
      end
    end
  end
end