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
|
# frozen_string_literal: true
module Gitlab
module EndpointAttributes
class Config
RequestUrgency = Struct.new(:name, :duration)
REQUEST_URGENCIES = [
RequestUrgency.new(:high, 0.25),
RequestUrgency.new(:medium, 0.5),
RequestUrgency.new(:default, 1),
RequestUrgency.new(:low, 5)
].index_by(&:name).freeze
SUPPORTED_ATTRIBUTES = %i[feature_category urgency].freeze
def initialize
@default_attributes = {}
@action_attributes = {}
end
def defined_actions
@action_attributes.keys
end
def set(actions, attributes)
sanitize_attributes!(attributes)
if actions.empty?
conflicted = conflicted_attributes(attributes, @default_attributes)
raise ArgumentError, "Attributes already defined: #{conflicted.join(", ")}" if conflicted.present?
@default_attributes.merge!(attributes)
else
set_attributes_for_actions(actions, attributes)
end
nil
end
def attribute_for_action(action, attribute_name)
value = @action_attributes.dig(action.to_s, attribute_name) || @default_attributes[attribute_name]
# Translate urgency to a representative struct
value = REQUEST_URGENCIES[value] if attribute_name == :urgency
value
end
private
def sanitize_attributes!(attributes)
unsupported_attributes = (attributes.keys - SUPPORTED_ATTRIBUTES).present?
raise ArgumentError, "Attributes not supported: #{unsupported_attributes.join(", ")}" if unsupported_attributes
if attributes[:urgency].present? && !REQUEST_URGENCIES.key?(attributes[:urgency])
raise ArgumentError, "Urgency not supported: #{attributes[:urgency]}"
end
end
def set_attributes_for_actions(actions, attributes)
conflicted = conflicted_attributes(attributes, @default_attributes)
if conflicted.present?
raise ArgumentError, "#{conflicted.join(", ")} are already defined for all actions, but re-defined for #{actions.join(", ")}"
end
actions.each do |action|
action = action.to_s
if @action_attributes[action].blank?
@action_attributes[action] = attributes.dup
else
conflicted = conflicted_attributes(attributes, @action_attributes[action])
raise ArgumentError, "Attributes re-defined for action #{action}: #{conflicted.join(", ")}" if conflicted.present?
@action_attributes[action].merge!(attributes)
end
end
end
def conflicted_attributes(attributes, existing_attributes)
attributes.keys.filter { |attr| existing_attributes[attr].present? && existing_attributes[attr] != attributes[attr] }
end
end
end
end
|