-
-
Notifications
You must be signed in to change notification settings - Fork 419
/
Copy pathflipper.rb
207 lines (180 loc) · 5.65 KB
/
flipper.rb
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
require "forwardable"
module Flipper
extend self
extend Forwardable
# Private: The namespace for all instrumented events.
InstrumentationNamespace = :flipper
# Public: Start here. Given an adapter returns a handy DSL to all the flipper
# goodness. To see supported options, check out dsl.rb.
def new(adapter, options = {})
DSL.new(adapter, options)
end
# Public: Configure flipper.
#
# Flipper.configure do |config|
# config.adapter { ... }
# end
#
# Yields Flipper::Configuration instance.
def configure
yield configuration if block_given?
end
# Public: Returns Flipper::Configuration instance.
def configuration
@configuration ||= Configuration.new
end
# Public: Sets Flipper::Configuration instance.
def configuration=(configuration)
# need to reset flipper instance if configuration changes
self.instance = nil
@configuration = configuration
end
# Public: Default per thread flipper instance if configured. You should not
# need to use this directly as most of the Flipper::DSL methods are delegated
# from Flipper module itself. Instead of doing Flipper.instance.enabled?(:search),
# you can use Flipper.enabled?(:search) for the same result.
#
# Returns Flipper::DSL instance.
def instance
Thread.current[:flipper_instance] ||= configuration.default
end
# Public: Set the flipper instance. It is most common to use the
# Configuration#default to set this instance, but for things like the test
# environment, this writer is actually useful.
def instance=(flipper)
Thread.current[:flipper_instance] = flipper
end
# Public: All the methods delegated to instance. These should match the
# interface of Flipper::DSL.
def_delegators :instance,
:enabled?, :enable, :disable,
:enable_expression, :disable_expression,
:expression, :add_expression, :remove_expression,
:enable_actor, :disable_actor,
:enable_group, :disable_group,
:enable_percentage_of_actors, :disable_percentage_of_actors,
:enable_percentage_of_time, :disable_percentage_of_time,
:features, :feature, :[], :preload, :preload_all,
:adapter, :add, :exist?, :remove, :import, :export,
:memoize=, :memoizing?, :read_only?,
:sync, :sync_secret # For Flipper::Cloud. Will error for OSS Flipper.
def any(*args)
Expression.build({ Any: args.flatten })
end
def all(*args)
Expression.build({ All: args.flatten })
end
def constant(value)
Expression.build(value)
end
def property(name)
Expression.build({ Property: name })
end
def string(value)
Expression.build({ String: value })
end
def number(value)
Expression.build({ Number: value })
end
def boolean(value)
Expression.build({ Boolean: value })
end
def random(max)
Expression.build({ Random: max })
end
# Public: Use this to register a group by name.
#
# name - The Symbol name of the group.
# block - The block that should be used to determine if the group matches a
# given actor.
#
# Examples
#
# Flipper.register(:admins) { |actor|
# actor.respond_to?(:admin?) && actor.admin?
# }
#
# Returns a Flipper::Group.
# Raises Flipper::DuplicateGroup if the group is already registered.
def register(name, &block)
group = Types::Group.new(name, &block)
groups_registry.add(group.name, group)
group
rescue Registry::DuplicateKey
raise DuplicateGroup, "Group #{name.inspect} has already been registered"
end
# Public: Returns a Set of registered Types::Group instances.
def groups
groups_registry.values.to_set
end
# Public: Returns a Set of symbols where each symbol is a registered
# group name. If you just want the names, this is more efficient than doing
# `Flipper.groups.map(&:name)`.
def group_names
groups_registry.keys.to_set
end
# Public: Clears the group registry.
#
# Returns nothing.
def unregister_groups
groups_registry.clear
end
# Public: Check if a group exists
#
# Returns boolean
def group_exists?(name)
groups_registry.key?(name)
end
# Public: Fetches a group by name.
#
# name - The Symbol name of the group.
#
# Examples
#
# Flipper.group(:admins)
#
# Returns Flipper::Group.
def group(name)
groups_registry.get(name) || Types::Group.new(name)
end
# Internal: Registry of all groups_registry.
def groups_registry
@groups_registry ||= Registry.new
end
# Internal: Change the groups_registry registry.
def groups_registry=(registry)
@groups_registry = registry
end
end
require 'flipper/actor'
require 'flipper/adapter'
require 'flipper/adapters/wrapper'
require 'flipper/adapters/actor_limit'
require 'flipper/adapters/instrumented'
require 'flipper/adapters/memoizable'
require 'flipper/adapters/memory'
require 'flipper/adapters/strict'
require 'flipper/adapter_builder'
require 'flipper/configuration'
require 'flipper/dsl'
require 'flipper/errors'
require 'flipper/feature'
require 'flipper/gate'
require 'flipper/instrumenters/memory'
require 'flipper/instrumenters/noop'
require 'flipper/identifier'
require 'flipper/middleware/memoizer'
require 'flipper/middleware/setup_env'
require 'flipper/poller'
require 'flipper/registry'
require 'flipper/expression'
require 'flipper/type'
require 'flipper/types/actor'
require 'flipper/types/boolean'
require 'flipper/types/group'
require 'flipper/types/percentage'
require 'flipper/types/percentage_of_actors'
require 'flipper/types/percentage_of_time'
require 'flipper/typecast'
require 'flipper/version'
require "flipper/engine" if defined?(Rails)