BigW Consortium Gitlab

issuable_extractor.rb 1.33 KB
Newer Older
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
module Banzai
  # Extract references to issuables from multiple documents

  # This populates RequestStore cache used in Banzai::ReferenceParser::IssueParser
  # and Banzai::ReferenceParser::MergeRequestParser
  # Populating the cache should happen before processing documents one-by-one
  # so we can avoid N+1 queries problem

  class IssuableExtractor
    QUERY = %q(
      descendant-or-self::a[contains(concat(" ", @class, " "), " gfm ")]
      [@data-reference-type="issue" or @data-reference-type="merge_request"]
    ).freeze

    attr_reader :project, :user

    def initialize(project, user)
      @project = project
      @user = user
    end

    # Returns Hash in the form { node => issuable_instance }
    def extract(documents)
      nodes = documents.flat_map do |document|
        document.xpath(QUERY)
      end

      issue_parser = Banzai::ReferenceParser::IssueParser.new(project, user)
      merge_request_parser = Banzai::ReferenceParser::MergeRequestParser.new(project, user)

31
      issuables_for_nodes = issue_parser.issues_for_nodes(nodes).merge(
32 33
        merge_request_parser.merge_requests_for_nodes(nodes)
      )
34

35
      # The project for the issue/MR might be pending for deletion!
36
      # Filter them out because we don't care about them.
37
      issuables_for_nodes.select { |node, issuable| issuable.project }
38 39 40
    end
  end
end