require_relative 'base_command_builder' module Gitlab module Triage module CommandBuilders class CommentBodyBuilder < BaseCommandBuilder SUPPORTED_PLACEHOLDERS = { created_at: "{{created_at}}".freeze, updated_at: "{{updated_at}}".freeze, closed_at: "{{closed_at}}".freeze, merged_at: "{{merged_at}}".freeze, state: "{{state}}".freeze, author: "@{{author.username}}".freeze, assignee: "@{{assignee.username}}".freeze, assignees: "@{{assignees.username}}".freeze, closed_by: "@{{closed_by.username}}".freeze, merged_by: "@{{merged_by.username}}".freeze, milestone: %(%"{{milestone.title}}").freeze, labels: %(~"{{labels}}").freeze, upvotes: "{{upvotes}}".freeze, downvotes: "{{downvotes}}".freeze }.freeze PLACEHOLDER_REGEX = /{{([\w\.]+)}}/ attr_reader :resource def initialize(items, resource: nil) super(items) @resource = resource end private def separator "\n\n" end def format_item(item) return item unless resource SUPPORTED_PLACEHOLDERS.inject(item) do |comment, (placeholder, formatted_text)| next comment unless comment.include?("{{#{placeholder}}}") methods = formatted_text.match(/.*#{PLACEHOLDER_REGEX}.*/)[1].split('.') fields = resource_fields(resource, methods) final_fields = fields.map { |field| formatted_text.sub(PLACEHOLDER_REGEX, field.to_s) } if final_fields.any? comment.gsub("{{#{placeholder}}}", final_fields.join(', ')) else comment end end end def resource_fields(resource, methods) method = methods.shift return Array(resource) unless method && resource return [] unless resource.key?(method) sub_resources = resource[method] Array.wrap(sub_resources).flat_map { |res| resource_fields(res, methods.dup) } end end end end end