Class: Gitlab::Triage::CommandBuilders::TextContentBuilder

Inherits:
BaseCommandBuilder show all
Defined in:
lib/gitlab/triage/command_builders/text_content_builder.rb

Constant Summary collapse

SUPPORTED_PLACEHOLDERS =
{
  created_at: "{{created_at}}",
  updated_at: "{{updated_at}}",
  closed_at: "{{closed_at}}",
  merged_at: "{{merged_at}}",
  state: "{{state}}",
  author: "@{{author.username}}",
  assignee: "@{{assignee.username}}",
  assignees: "@{{assignees.username}}",
  reviewers: "@{{reviewers.username}}",
  source_branch: "{{source_branch}}",
  target_branch: "{{target_branch}}",
  closed_by: "@{{closed_by.username}}",
  merged_by: "@{{merged_by.username}}",
  milestone: %(%"{{milestone.title}}"),
  labels: %(~"{{labels}}"),
  upvotes: "{{upvotes}}",
  downvotes: "{{downvotes}}",
  title: "{{title}}",
  web_url: "{{web_url}}",
  full_reference: "{{references.full}}",
  type: "{{type}}",
  items: "{{items}}",
  name: "{{name}}"
}.freeze
PLACEHOLDER_REGEX =
/{{([\w.]+)}}/

Instance Attribute Summary

Attributes inherited from BaseCommandBuilder

#items, #network, #resource

Instance Method Summary collapse

Methods inherited from BaseCommandBuilder

#build_command, #content_string, #slash_command_string

Constructor Details

#initialize(items, resource: nil, network: nil, redact_confidentials: true) ⇒ TextContentBuilder

Returns a new instance of TextContentBuilder.



40
41
42
43
44
# File 'lib/gitlab/triage/command_builders/text_content_builder.rb', line 40

def initialize(
  items, resource: nil, network: nil, redact_confidentials: true)
  super(items, resource: resource, network: network)
  @redact_confidentials = redact_confidentials
end

Instance Method Details

#eval_interpolation(item) ⇒ Object (private)



58
59
60
61
62
63
64
65
66
# File 'lib/gitlab/triage/command_builders/text_content_builder.rb', line 58

def eval_interpolation(item)
  quoted_comment = "%Q{#{item}}"

  Resource::Context.build(
    resource,
    network: network,
    redact_confidentials: @redact_confidentials
  ).eval(quoted_comment)
end

#extract_attributes(path) ⇒ Object (private)



98
99
100
# File 'lib/gitlab/triage/command_builders/text_content_builder.rb', line 98

def extract_attributes(path)
  redact_attributes(path, resource_dig_and_map(path.split('.')))
end

#format_item(item) ⇒ Object (private)



52
53
54
55
56
# File 'lib/gitlab/triage/command_builders/text_content_builder.rb', line 52

def format_item(item)
  return item unless resource

  replace_placeholders(eval_interpolation(item))
end

#redact_attributes(path, attributes) ⇒ Object (private)



122
123
124
125
126
127
128
129
130
131
# File 'lib/gitlab/triage/command_builders/text_content_builder.rb', line 122

def redact_attributes(path, attributes)
  return attributes unless redact_confidential_attributes?

  case path
  when 'web_url', 'items', 'type', 'references.full'
    attributes # No need to redact them
  else
    [Resource::Base::CONFIDENTIAL_TEXT]
  end
end

#redact_confidential_attributes?Boolean (private)

Returns:

  • (Boolean)


133
134
135
# File 'lib/gitlab/triage/command_builders/text_content_builder.rb', line 133

def redact_confidential_attributes?
  @redact_confidentials && resource[:confidential]
end

#replace_placeholders(item) ⇒ Object (private)



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
# File 'lib/gitlab/triage/command_builders/text_content_builder.rb', line 68

def replace_placeholders(item)
  SUPPORTED_PLACEHOLDERS.inject(item) do |comment, (placeholder, template)|
    next comment unless comment.include?("{{#{placeholder}}}")

    path = template[/.*#{PLACEHOLDER_REGEX}.*/o, 1]
    attributes = extract_attributes(path)

    formatted_text = attributes.map do |attribute|
      template.sub(PLACEHOLDER_REGEX, attribute.to_s)
    end.join(', ')

    escaped_text =
      case placeholder
      when :items
        # We don't need to escape it because it's recursive,
        # which the contents should all be escaped already.
        # Or put it another way, items isn't an attribute
        # retrieved externally. It's a generated value which
        # should be safe to begin with. At some point we
        # may want to make this more distinguishable,
        # separating values from API and values generated.
        formatted_text
      else
        CGI.escape_html(formatted_text)
      end

    comment.gsub("{{#{placeholder}}}", escaped_text)
  end
end

#resource_dig_and_map(indices) ⇒ Object (private)

If we don’t have to map arrays, we can simply do:

resource.dig(*indices)

Thus this method name. The only array here is ‘assignees`



107
108
109
110
111
112
113
114
115
116
117
118
119
120
# File 'lib/gitlab/triage/command_builders/text_content_builder.rb', line 107

def resource_dig_and_map(indices)
  attributes = indices.inject(resource) do |result, index|
    break unless result

    case result
    when Array
      result.flat_map { |sub_resource| sub_resource[index] }
    else
      result[index]
    end
  end

  Array.wrap(attributes)
end

#separatorObject (private)



48
49
50
# File 'lib/gitlab/triage/command_builders/text_content_builder.rb', line 48

def separator
  "\n\n"
end