Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitlab-foss.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'lib/feature')
-rw-r--r--lib/feature/definition.rb35
-rw-r--r--lib/feature/logger.rb9
-rw-r--r--lib/feature/shared.rb16
3 files changed, 49 insertions, 11 deletions
diff --git a/lib/feature/definition.rb b/lib/feature/definition.rb
index 0ba1bdc4799..8d9b2fa5234 100644
--- a/lib/feature/definition.rb
+++ b/lib/feature/definition.rb
@@ -13,6 +13,12 @@ class Feature
end
end
+ TYPES.each do |type, _|
+ define_method("#{type}?") do
+ attributes[:type].to_sym == type
+ end
+ end
+
def initialize(path, opts = {})
@path = path
@attributes = {}
@@ -65,9 +71,7 @@ class Feature
"a valid syntax: #{TYPES.dig(type, :example)}"
end
- # We accept an array of defaults as some features are undefined
- # and have `default_enabled: true/false`
- unless Array(default_enabled).include?(default_enabled_in_code)
+ unless default_enabled_in_code == :yaml || default_enabled == default_enabled_in_code
# Raise exception in test and dev
raise Feature::InvalidFeatureFlagError, "The `default_enabled:` of `#{key}` is not equal to config: " \
"#{default_enabled_in_code} vs #{default_enabled}. Ensure to update #{path}"
@@ -90,12 +94,20 @@ class Feature
@definitions ||= load_all!
end
+ def get(key)
+ definitions[key.to_sym]
+ end
+
def reload!
@definitions = load_all!
end
+ def has_definition?(key)
+ definitions.has_key?(key.to_sym)
+ end
+
def valid_usage!(key, type:, default_enabled:)
- if definition = definitions[key.to_sym]
+ if definition = get(key)
definition.valid_usage!(type_in_code: type, default_enabled_in_code: default_enabled)
elsif type_definition = self::TYPES[type]
raise InvalidFeatureFlagError, "Missing feature definition for `#{key}`" unless type_definition[:optional]
@@ -104,6 +116,17 @@ class Feature
end
end
+ def default_enabled?(key)
+ if definition = get(key)
+ definition.default_enabled
+ else
+ Gitlab::ErrorTracking.track_and_raise_for_dev_exception(
+ InvalidFeatureFlagError.new("The feature flag YAML definition for '#{key}' does not exist"))
+
+ false
+ end
+ end
+
def register_hot_reloader!
# Reload feature flags on change of this file or any `.yml`
file_watcher = Rails.configuration.file_watcher.new(reload_files, reload_directories) do
@@ -119,10 +142,6 @@ class Feature
private
def load_all!
- # We currently do not load feature flag definitions
- # in production environments
- return [] unless Gitlab.dev_or_test_env?
-
paths.each_with_object({}) do |glob_path, definitions|
load_all_from_path!(definitions, glob_path)
end
diff --git a/lib/feature/logger.rb b/lib/feature/logger.rb
new file mode 100644
index 00000000000..784a619e182
--- /dev/null
+++ b/lib/feature/logger.rb
@@ -0,0 +1,9 @@
+# frozen_string_literal: true
+
+class Feature
+ class Logger < ::Gitlab::JsonLogger
+ def self.file_name_noext
+ 'features_json'
+ end
+ end
+end
diff --git a/lib/feature/shared.rb b/lib/feature/shared.rb
index 1fcbc8fa173..17dfe26bd82 100644
--- a/lib/feature/shared.rb
+++ b/lib/feature/shared.rb
@@ -23,7 +23,7 @@ class Feature
example: <<-EOS
Feature.enabled?(:my_feature_flag, project)
Feature.enabled?(:my_feature_flag, project, type: :development)
- push_frontend_feature_flag?(:my_feature_flag, project)
+ push_frontend_feature_flag(:my_feature_flag, project)
EOS
},
ops: {
@@ -33,8 +33,8 @@ class Feature
ee_only: false,
default_enabled: false,
example: <<-EOS
- Feature.enabled?(:my_ops_flag, type: ops)
- push_frontend_feature_flag?(:my_ops_flag, project, type: :ops)
+ Feature.enabled?(:my_ops_flag, type: :ops)
+ push_frontend_feature_flag(:my_ops_flag, project, type: :ops)
EOS
},
licensed: {
@@ -48,6 +48,16 @@ class Feature
project.feature_available?(:my_licensed_feature)
namespace.feature_available?(:my_licensed_feature)
EOS
+ },
+ experiment: {
+ description: 'Short lived, used specifically to run A/B/n experiments.',
+ optional: true,
+ rollout_issue: true,
+ ee_only: true,
+ default_enabled: false,
+ example: <<-EOS
+ experiment(:my_experiment, project: project, actor: current_user) { ...variant code... }
+ EOS
}
}.freeze