summaryrefslogtreecommitdiff
path: root/app/controllers/concerns/controller_with_feature_category.rb
diff options
context:
space:
mode:
Diffstat (limited to 'app/controllers/concerns/controller_with_feature_category.rb')
-rw-r--r--app/controllers/concerns/controller_with_feature_category.rb45
1 files changed, 45 insertions, 0 deletions
diff --git a/app/controllers/concerns/controller_with_feature_category.rb b/app/controllers/concerns/controller_with_feature_category.rb
new file mode 100644
index 00000000000..f8985cf0950
--- /dev/null
+++ b/app/controllers/concerns/controller_with_feature_category.rb
@@ -0,0 +1,45 @@
+# frozen_string_literal: true
+
+module ControllerWithFeatureCategory
+ extend ActiveSupport::Concern
+ include Gitlab::ClassAttributes
+
+ class_methods do
+ def feature_category(category, config = {})
+ validate_config!(config)
+
+ category_config = Config.new(category, config[:only], config[:except], config[:if], config[:unless])
+ # Add the config to the beginning. That way, the last defined one takes precedence.
+ feature_category_configuration.unshift(category_config)
+ end
+
+ def feature_category_for_action(action)
+ category_config = feature_category_configuration.find { |config| config.matches?(action) }
+
+ category_config&.category || superclass_feature_category_for_action(action)
+ end
+
+ private
+
+ def validate_config!(config)
+ invalid_keys = config.keys - [:only, :except, :if, :unless]
+ if invalid_keys.any?
+ raise ArgumentError, "unknown arguments: #{invalid_keys} "
+ end
+
+ if config.key?(:only) && config.key?(:except)
+ raise ArgumentError, "cannot configure both `only` and `except`"
+ end
+ end
+
+ def feature_category_configuration
+ class_attributes[:feature_category_config] ||= []
+ end
+
+ def superclass_feature_category_for_action(action)
+ return unless superclass.respond_to?(:feature_category_for_action)
+
+ superclass.feature_category_for_action(action)
+ end
+ end
+end