lita 3.3.1 → 4.0.0.rc1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.rubocop.yml +1 -1
- data/.travis.yml +3 -0
- data/lib/lita.rb +45 -97
- data/lib/lita/adapter.rb +38 -17
- data/lib/lita/adapters/shell.rb +5 -3
- data/lib/lita/authorization.rb +109 -60
- data/lib/lita/builder.rb +38 -0
- data/lib/lita/callback.rb +37 -0
- data/lib/lita/cli.rb +2 -0
- data/lib/lita/config.rb +1 -18
- data/lib/lita/configurable.rb +29 -0
- data/lib/lita/configuration.rb +179 -0
- data/lib/lita/configuration_validator.rb +66 -0
- data/lib/lita/daemon.rb +4 -11
- data/lib/lita/default_configuration.rb +146 -0
- data/lib/lita/errors.rb +9 -0
- data/lib/lita/handler.rb +5 -264
- data/lib/lita/handler/chat_router.rb +130 -0
- data/lib/lita/handler/common.rb +114 -0
- data/lib/lita/handler/event_router.rb +77 -0
- data/lib/lita/handler/http_router.rb +26 -0
- data/lib/lita/handlers/authorization.rb +13 -18
- data/lib/lita/handlers/deprecation_check.rb +24 -0
- data/lib/lita/handlers/help.rb +5 -3
- data/lib/lita/handlers/info.rb +2 -2
- data/lib/lita/http_callback.rb +29 -0
- data/lib/lita/http_route.rb +41 -26
- data/lib/lita/namespace.rb +23 -0
- data/lib/lita/rack_app.rb +29 -2
- data/lib/lita/registry.rb +133 -0
- data/lib/lita/robot.rb +58 -20
- data/lib/lita/route_validator.rb +12 -4
- data/lib/lita/rspec.rb +23 -14
- data/lib/lita/rspec/handler.rb +93 -23
- data/lib/lita/rspec/matchers/chat_route_matcher.rb +48 -0
- data/lib/lita/rspec/matchers/deprecated.rb +36 -0
- data/lib/lita/rspec/matchers/event_route_matcher.rb +27 -0
- data/lib/lita/rspec/matchers/http_route_matcher.rb +18 -60
- data/lib/lita/user.rb +0 -6
- data/lib/lita/util.rb +1 -8
- data/lib/lita/version.rb +1 -1
- data/lita.gemspec +1 -0
- data/spec/lita/adapter_spec.rb +25 -7
- data/spec/lita/adapters/shell_spec.rb +24 -4
- data/spec/lita/authorization_spec.rb +57 -38
- data/spec/lita/builder_spec.rb +39 -0
- data/spec/lita/config_spec.rb +0 -24
- data/spec/lita/configuration_spec.rb +222 -0
- data/spec/lita/configuration_validator_spec.rb +112 -0
- data/spec/lita/daemon_spec.rb +2 -2
- data/spec/lita/default_configuration_spec.rb +254 -0
- data/spec/lita/handler/chat_router_spec.rb +192 -0
- data/spec/lita/handler/common_spec.rb +272 -0
- data/spec/lita/handler/event_router_spec.rb +54 -0
- data/spec/lita/handler/http_router_spec.rb +106 -0
- data/spec/lita/handler_spec.rb +20 -291
- data/spec/lita/handlers/authorization_spec.rb +9 -11
- data/spec/lita/handlers/deprecation_check_spec.rb +21 -0
- data/spec/lita/handlers/help_spec.rb +31 -9
- data/spec/lita/handlers/info_spec.rb +2 -2
- data/spec/lita/handlers/room_spec.rb +5 -3
- data/spec/lita/robot_spec.rb +30 -11
- data/spec/lita/rspec_spec.rb +71 -31
- data/spec/lita/user_spec.rb +2 -2
- data/spec/lita_spec.rb +62 -4
- data/spec/spec_helper.rb +7 -0
- data/templates/locales/en.yml +56 -4
- data/templates/plugin/gemspec.tt +1 -0
- data/templates/plugin/spec/spec_helper.tt +4 -0
- metadata +54 -8
- data/lib/lita/rspec/matchers/event_subscription_matcher.rb +0 -67
- data/lib/lita/rspec/matchers/route_matcher.rb +0 -69
- data/spec/lita/rack_app_spec.rb +0 -92
@@ -0,0 +1,77 @@
|
|
1
|
+
module Lita
|
2
|
+
class Handler
|
3
|
+
# A handler mixin that provides the methods necessary for handling events.
|
4
|
+
# @since 4.0.0
|
5
|
+
module EventRouter
|
6
|
+
# Includes common handler methods in any class that includes {EventRouter}.
|
7
|
+
def self.extended(klass)
|
8
|
+
klass.send(:include, Common)
|
9
|
+
end
|
10
|
+
|
11
|
+
# @overload on(event_name, method_name)
|
12
|
+
# Registers an event subscription. When an event is triggered with
|
13
|
+
# {#trigger}, a new instance of the handler will be created and the
|
14
|
+
# instance method name supplied to {#on} will be invoked with a payload
|
15
|
+
# (a hash of arbitrary keys and values).
|
16
|
+
# @param event_name [String, Symbol] The name of the event to subscribe to.
|
17
|
+
# @param method_name [String, Symbol] The name of the instance method on
|
18
|
+
# the handler that should be invoked when the event is triggered.
|
19
|
+
# @return [void]
|
20
|
+
# @overload on(event_name, callable)
|
21
|
+
# Registers an event subscription. When an event is triggered with
|
22
|
+
# {#trigger}, a new instance of the handler will be created and the
|
23
|
+
# callable object supplied to {#on} will be evaluated within the context of the new
|
24
|
+
# handler instance, and passed a payload (a hash of arbitrary keys and values).
|
25
|
+
# @param event_name [String, Symbol] The name of the event to subscribe to.
|
26
|
+
# @param callable [#call] A callable object to serve as the event callback.
|
27
|
+
# @return [void]
|
28
|
+
# @since 4.0.0
|
29
|
+
# @overload on(event_name)
|
30
|
+
# Registers an event subscription. When an event is triggered with
|
31
|
+
# {#trigger}, a new instance of the handler will be created and the
|
32
|
+
# block supplied to {#on} will be evaluated within the context of the new
|
33
|
+
# handler instance, and passed a payload (a hash of arbitrary keys and values).
|
34
|
+
# @param event_name [String, Symbol] The name of the event to subscribe to.
|
35
|
+
# @yield The body of the event callback.
|
36
|
+
# @return [void]
|
37
|
+
# @since 4.0.0
|
38
|
+
def on(event_name, method_name_or_callable = nil)
|
39
|
+
event_subscriptions[normalize_event(event_name)] << Callback.new(
|
40
|
+
method_name_or_callable || (proc if block_given?)
|
41
|
+
)
|
42
|
+
end
|
43
|
+
|
44
|
+
# Returns an array of all callbacks registered for the named event.
|
45
|
+
# @param event_name [String, Symbol] The name of the event to return callbacks for.
|
46
|
+
# @return [Array] The array of callbacks.
|
47
|
+
# @since 4.0.0
|
48
|
+
def event_subscriptions_for(event_name)
|
49
|
+
event_subscriptions[normalize_event(event_name)]
|
50
|
+
end
|
51
|
+
|
52
|
+
# Triggers an event, invoking methods previously registered with {#on} and
|
53
|
+
# passing them a payload hash with any arbitrary data.
|
54
|
+
# @param robot [Lita::Robot] The currently running robot instance.
|
55
|
+
# @param event_name [String, Symbol], The name of the event to trigger.
|
56
|
+
# @param payload [Hash] An optional hash of arbitrary data.
|
57
|
+
# @return [Boolean] Whether or not the event triggered any callbacks.
|
58
|
+
def trigger(robot, event_name, payload = {})
|
59
|
+
event_subscriptions_for(event_name).any? do |callback|
|
60
|
+
callback.call(new(robot), payload)
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
private
|
65
|
+
|
66
|
+
# A hash of arrays used to store event subscriptions registered with {#on}.
|
67
|
+
def event_subscriptions
|
68
|
+
@event_subscriptions ||= Hash.new { |h, k| h[k] = [] }
|
69
|
+
end
|
70
|
+
|
71
|
+
# Normalize the event name, ignoring casing and spaces.
|
72
|
+
def normalize_event(event_name)
|
73
|
+
event_name.to_s.downcase.strip.to_sym
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module Lita
|
2
|
+
class Handler
|
3
|
+
# A handler mixin that provides the methods necessary for handling incoming HTTP requests.
|
4
|
+
# @since 4.0.0
|
5
|
+
module HTTPRouter
|
6
|
+
# Includes common handler methods in any class that includes {HTTPRouter}.
|
7
|
+
def self.extended(klass)
|
8
|
+
klass.send(:include, Common)
|
9
|
+
end
|
10
|
+
|
11
|
+
# Creates a new {Lita::HTTPRoute} which is used to define an HTTP route
|
12
|
+
# for the built-in web server.
|
13
|
+
# @see Lita::HTTPRoute
|
14
|
+
# @return [Lita::HTTPRoute] The new {Lita::HTTPRoute}.
|
15
|
+
def http
|
16
|
+
HTTPRoute.new(self)
|
17
|
+
end
|
18
|
+
|
19
|
+
# An array of all HTTP routes defined for the handler.
|
20
|
+
# @return [Array<Lita::HTTPRoute>] The array of routes.
|
21
|
+
def http_routes
|
22
|
+
@http_routes ||= []
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
@@ -25,29 +25,14 @@ module Lita
|
|
25
25
|
# @param response [Lita::Response] The response object.
|
26
26
|
# @return [void]
|
27
27
|
def add(response)
|
28
|
-
|
29
|
-
|
30
|
-
if Lita::Authorization.add_user_to_group(response.user, @user, @group)
|
31
|
-
response.reply t("user_added", user: @user.name, group: @group)
|
32
|
-
else
|
33
|
-
response.reply t("user_already_in", user: @user.name, group: @group)
|
34
|
-
end
|
28
|
+
toggle_membership(response, :add_user_to_group, "user_added", "user_already_in")
|
35
29
|
end
|
36
30
|
|
37
31
|
# Removes a user from an authorization group.
|
38
32
|
# @param response [Lita::Response] The response object.
|
39
33
|
# @return [void]
|
40
34
|
def remove(response)
|
41
|
-
|
42
|
-
|
43
|
-
if Lita::Authorization.remove_user_from_group(response.user, @user, @group)
|
44
|
-
response.reply t("user_removed",
|
45
|
-
user: @user.name,
|
46
|
-
group: @group
|
47
|
-
)
|
48
|
-
else
|
49
|
-
response.reply t("user_not_in", user: @user.name, group: @group)
|
50
|
-
end
|
35
|
+
toggle_membership(response, :remove_user_from_group, "user_removed", "user_not_in")
|
51
36
|
end
|
52
37
|
|
53
38
|
# Lists all authorization groups (or only the specified group) and the
|
@@ -75,7 +60,7 @@ module Lita
|
|
75
60
|
end
|
76
61
|
|
77
62
|
def get_groups_list(requested_group)
|
78
|
-
groups_with_users =
|
63
|
+
groups_with_users = robot.auth.groups_with_users
|
79
64
|
if requested_group
|
80
65
|
requested_group = requested_group.downcase.strip.to_sym
|
81
66
|
groups_with_users.select! { |group, _| group == requested_group }
|
@@ -86,6 +71,16 @@ module Lita
|
|
86
71
|
end
|
87
72
|
end
|
88
73
|
|
74
|
+
def toggle_membership(response, method_name, success_key, failure_key)
|
75
|
+
return unless valid_message?(response)
|
76
|
+
|
77
|
+
if robot.auth.public_send(method_name, response.user, @user, @group)
|
78
|
+
response.reply t(success_key, user: @user.name, group: @group)
|
79
|
+
else
|
80
|
+
response.reply t(failure_key, user: @user.name, group: @group)
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
89
84
|
def valid_group?(response, identifier)
|
90
85
|
unless identifier && @group
|
91
86
|
response.reply "#{t("format")}: #{robot.name} auth add USER GROUP"
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module Lita
|
2
|
+
module Handlers
|
3
|
+
# Warns about any handlers using deprecated features.
|
4
|
+
# @since 4.0.0
|
5
|
+
class DeprecationCheck
|
6
|
+
extend Lita::Handler::EventRouter
|
7
|
+
|
8
|
+
on :loaded, :check_handlers_for_default_config
|
9
|
+
|
10
|
+
# Warns about handlers using the old +default_config+ method.
|
11
|
+
def check_handlers_for_default_config(_payload)
|
12
|
+
robot.registry.handlers.each do |handler|
|
13
|
+
if handler.respond_to?(:default_config)
|
14
|
+
Lita.logger.warn(
|
15
|
+
I18n.t("lita.config.handler_default_config_deprecated", name: handler.namespace)
|
16
|
+
)
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
22
|
+
Lita.register_handler(DeprecationCheck)
|
23
|
+
end
|
24
|
+
end
|
data/lib/lita/handlers/help.rb
CHANGED
@@ -22,13 +22,15 @@ module Lita
|
|
22
22
|
# Checks if the user is authorized to at least one of the given groups.
|
23
23
|
def authorized?(user, required_groups)
|
24
24
|
required_groups.nil? || required_groups.any? do |group|
|
25
|
-
|
25
|
+
robot.auth.user_in_group?(user, group)
|
26
26
|
end
|
27
27
|
end
|
28
28
|
|
29
29
|
# Creates an array of help info for all registered routes.
|
30
30
|
def build_help(response)
|
31
|
-
|
31
|
+
robot.handlers.map do |handler|
|
32
|
+
next unless handler.respond_to?(:routes)
|
33
|
+
|
32
34
|
handler.routes.map do |route|
|
33
35
|
route.help.map do |command, description|
|
34
36
|
if authorized?(response.user, route.required_groups)
|
@@ -58,7 +60,7 @@ module Lita
|
|
58
60
|
|
59
61
|
# The way the bot should be addressed in order to trigger a command.
|
60
62
|
def name
|
61
|
-
|
63
|
+
robot.config.robot.mention_name || robot.config.robot.name
|
62
64
|
end
|
63
65
|
end
|
64
66
|
|
data/lib/lita/handlers/info.rb
CHANGED
@@ -22,13 +22,13 @@ module Lita
|
|
22
22
|
end
|
23
23
|
|
24
24
|
# Returns JSON with basic information about the robot.
|
25
|
-
# @param
|
25
|
+
# @param _request [Rack::Request] The HTTP request.
|
26
26
|
# @param response [Rack::Response] The HTTP response.
|
27
27
|
# @return [void]
|
28
28
|
def web(_request, response)
|
29
29
|
response.headers["Content-Type"] = "application/json"
|
30
30
|
json = MultiJson.dump(
|
31
|
-
adapter:
|
31
|
+
adapter: robot.config.robot.adapter,
|
32
32
|
lita_version: Lita::VERSION,
|
33
33
|
redis_memory_usage: redis_memory_usage,
|
34
34
|
redis_version: redis_version,
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Lita
|
2
|
+
# A wrapper around a handler's HTTP route callbacks that sets up the request and response.
|
3
|
+
# @api private
|
4
|
+
# @since 4.0.0
|
5
|
+
class HTTPCallback
|
6
|
+
# @param handler_class [Lita::Handler] The handler defining the callback.
|
7
|
+
# @param callback [Proc] The callback.
|
8
|
+
def initialize(handler_class, callback)
|
9
|
+
@handler_class = handler_class
|
10
|
+
@callback = callback
|
11
|
+
end
|
12
|
+
|
13
|
+
# Call the Rack endpoint with a standard environment hash.
|
14
|
+
def call(env)
|
15
|
+
request = Rack::Request.new(env)
|
16
|
+
response = Rack::Response.new
|
17
|
+
|
18
|
+
if request.head?
|
19
|
+
response.status = 204
|
20
|
+
else
|
21
|
+
handler = @handler_class.new(env["lita.robot"])
|
22
|
+
|
23
|
+
@callback.call(handler, request, response)
|
24
|
+
end
|
25
|
+
|
26
|
+
response.finish
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
data/lib/lita/http_route.rb
CHANGED
@@ -1,3 +1,17 @@
|
|
1
|
+
# Primary class from the +http_router+ gem.
|
2
|
+
# @todo Remove this monkey patch as soon as a gem is released with this pull request merged:
|
3
|
+
# https://github.com/joshbuddy/http_router/pull/40
|
4
|
+
class HttpRouter
|
5
|
+
# An individual HTTP route.
|
6
|
+
class Route
|
7
|
+
# Sets a name for the route. Monkey patched due to a bug.
|
8
|
+
def name=(name)
|
9
|
+
@name = name
|
10
|
+
router.named_routes[name] << self if router
|
11
|
+
end
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
1
15
|
module Lita
|
2
16
|
# Handlers use this class to define HTTP routes for the built-in web
|
3
17
|
# server.
|
@@ -22,16 +36,23 @@ module Lita
|
|
22
36
|
private
|
23
37
|
|
24
38
|
# @!macro define_http_method
|
25
|
-
# @
|
26
|
-
#
|
27
|
-
#
|
28
|
-
#
|
29
|
-
#
|
30
|
-
#
|
31
|
-
#
|
39
|
+
# @overload $1(path, method_name, options = {})
|
40
|
+
# Defines a new route with the "$1" HTTP method.
|
41
|
+
# @param path [String] The URL path component that will trigger the route.
|
42
|
+
# @param method_name [Symbol, String] The name of the instance method in
|
43
|
+
# the handler to call for the route.
|
44
|
+
# @param options [Hash] Various options for controlling the behavior of the route.
|
45
|
+
# @return [void]
|
46
|
+
# @overload $1(path, options = {})
|
47
|
+
# Defines a new route with the "$1" HTTP method.
|
48
|
+
# @param path [String] The URL path component that will trigger the route.
|
49
|
+
# @param options [Hash] Various options for controlling the behavior of the route.
|
50
|
+
# @yield The body of the route's callback.
|
51
|
+
# @return [void]
|
52
|
+
# @since 4.0.0
|
32
53
|
def define_http_method(http_method)
|
33
|
-
define_method(http_method) do |path, method_name, options = {}|
|
34
|
-
|
54
|
+
define_method(http_method) do |path, method_name = nil, options = {}, &block|
|
55
|
+
register_route(http_method.to_s.upcase, path, Callback.new(method_name || block), options)
|
35
56
|
end
|
36
57
|
end
|
37
58
|
end
|
@@ -48,28 +69,22 @@ module Lita
|
|
48
69
|
|
49
70
|
private
|
50
71
|
|
51
|
-
#
|
52
|
-
def
|
72
|
+
# Adds a new HTTP route for the handler.
|
73
|
+
def register_route(http_method, path, callback, options)
|
74
|
+
route = new_route(http_method, path, callback, options)
|
75
|
+
route.to(HTTPCallback.new(handler_class, callback))
|
76
|
+
handler_class.http_routes << route
|
77
|
+
end
|
78
|
+
|
79
|
+
# Creates and configures a new HTTP route.
|
80
|
+
def new_route(http_method, path, callback, options)
|
53
81
|
route = ExtendedRoute.new
|
54
82
|
route.path = path
|
83
|
+
route.name = callback.method_name
|
55
84
|
route.add_match_with(options)
|
56
85
|
route.add_request_method(http_method)
|
57
86
|
route.add_request_method("HEAD") if http_method == "GET"
|
58
|
-
|
59
|
-
route.to do |env|
|
60
|
-
request = Rack::Request.new(env)
|
61
|
-
response = Rack::Response.new
|
62
|
-
|
63
|
-
if request.head?
|
64
|
-
response.status = 204
|
65
|
-
else
|
66
|
-
handler_class.new(env["lita.robot"]).public_send(method_name, request, response)
|
67
|
-
end
|
68
|
-
|
69
|
-
response.finish
|
70
|
-
end
|
71
|
-
|
72
|
-
handler_class.http_routes << route
|
87
|
+
route
|
73
88
|
end
|
74
89
|
end
|
75
90
|
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
module Lita
|
2
|
+
# A mixin for setting and getting a plugin's namespace.
|
3
|
+
# @since 4.0.0
|
4
|
+
module Namespace
|
5
|
+
# Gets (and optionally sets) the namespace for a plugin. The namespace is generated from the
|
6
|
+
# class's name by default.
|
7
|
+
# @param value [String] If provided, sets the namespace of the plugin to the value.
|
8
|
+
# @return [String] The namespace.
|
9
|
+
# @raise [RuntimeError] If the plugin is an anonymous class, does not define +self.name+, and
|
10
|
+
# has not set a namespace manually.
|
11
|
+
def namespace(value = nil)
|
12
|
+
@namespace = value.to_s if value
|
13
|
+
|
14
|
+
string_name = defined?(@namespace) ? @namespace : name
|
15
|
+
|
16
|
+
if string_name
|
17
|
+
Util.underscore(string_name.split("::").last)
|
18
|
+
else
|
19
|
+
raise I18n.t("lita.plugin.name_required")
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
data/lib/lita/rack_app.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Lita
|
2
|
-
# A +Rack+ application to serve routes registered by handlers.
|
2
|
+
# A +Rack+ application to serve HTTP routes registered by handlers.
|
3
3
|
class RackApp
|
4
4
|
# The currently running robot.
|
5
5
|
# @return [Lita::Robot] The robot.
|
@@ -9,6 +9,16 @@ module Lita
|
|
9
9
|
# @return [HttpRouter] The router.
|
10
10
|
attr_reader :router
|
11
11
|
|
12
|
+
# Constructs a {RackApp} inside a +Rack::Builder+, including any configured middleware.
|
13
|
+
# @param robot [Lita::Robot] The currently running robot.
|
14
|
+
# @return [Lita::RackApp, Class] The Rack application.
|
15
|
+
def self.build(robot)
|
16
|
+
builder = Rack::Builder.new
|
17
|
+
builder.run(new(robot))
|
18
|
+
robot.config.http.middleware.each { |middleware| builder.use(middleware) }
|
19
|
+
builder.to_app
|
20
|
+
end
|
21
|
+
|
12
22
|
# @param robot [Lita::Robot] The currently running robot.
|
13
23
|
def initialize(robot)
|
14
24
|
@robot = robot
|
@@ -24,13 +34,30 @@ module Lita
|
|
24
34
|
router.call(env)
|
25
35
|
end
|
26
36
|
|
37
|
+
# Finds the first route that matches the request environment, if any. Does not trigger the
|
38
|
+
# route.
|
39
|
+
# @param env [Hash] A Rack environment.
|
40
|
+
# @return [Array] An array of the name of the first matching route.
|
41
|
+
# @since 4.0.0
|
42
|
+
def recognize(env)
|
43
|
+
env["lita.robot"] = robot
|
44
|
+
recognized_routes_for(env).map { |match| match.route.name }
|
45
|
+
end
|
46
|
+
|
27
47
|
private
|
28
48
|
|
29
49
|
# Registers routes in the router for each handler's defined routes.
|
30
50
|
def compile
|
31
|
-
|
51
|
+
robot.handlers.each do |handler|
|
52
|
+
next unless handler.respond_to?(:http_routes)
|
53
|
+
|
32
54
|
handler.http_routes.each { |route| router.add_route(route) }
|
33
55
|
end
|
34
56
|
end
|
57
|
+
|
58
|
+
# Returns an array containing the first recongnized route, if any.
|
59
|
+
def recognized_routes_for(env)
|
60
|
+
Array(router.recognize(env).first)
|
61
|
+
end
|
35
62
|
end
|
36
63
|
end
|
@@ -0,0 +1,133 @@
|
|
1
|
+
module Lita
|
2
|
+
# An object to hold various types of data including configuration and plugins.
|
3
|
+
# @since 4.0.0
|
4
|
+
class Registry
|
5
|
+
# Allows a registry to be added to another object.
|
6
|
+
module Mixins
|
7
|
+
# The primary configuration object. Provides user settings for the robot.
|
8
|
+
# @return [Object] The configuration object.
|
9
|
+
def config
|
10
|
+
@config ||= DefaultConfiguration.new(self).finalize
|
11
|
+
end
|
12
|
+
|
13
|
+
# Yields the configuration object. Called by the user in a +lita_config.rb+ file.
|
14
|
+
# @yieldparam [Object] config The configuration object.
|
15
|
+
# @return [void]
|
16
|
+
def configure
|
17
|
+
yield config
|
18
|
+
end
|
19
|
+
|
20
|
+
# A registry of adapters.
|
21
|
+
# @return [Hash] A map of adapter keys to adapter classes.
|
22
|
+
def adapters
|
23
|
+
@adapters ||= {}
|
24
|
+
end
|
25
|
+
|
26
|
+
# A registry of handlers.
|
27
|
+
# @return [Set] The set of handlers.
|
28
|
+
def handlers
|
29
|
+
@handlers ||= Set.new
|
30
|
+
end
|
31
|
+
|
32
|
+
# A registry of hook handler objects.
|
33
|
+
# @return [Hash] A hash mapping hook names to sets of objects that handle them.
|
34
|
+
# @since 3.2.0
|
35
|
+
def hooks
|
36
|
+
@hooks ||= Hash.new { |h, k| h[k] = Set.new }
|
37
|
+
end
|
38
|
+
|
39
|
+
# @overload register_adapter(key, adapter)
|
40
|
+
# Adds an adapter to the registry under the provided key.
|
41
|
+
# @param key [String, Symbol] The key that identifies the adapter.
|
42
|
+
# @param adapter [Class] The adapter class.
|
43
|
+
# @return [void]
|
44
|
+
# @overload register_adapter(key)
|
45
|
+
# Adds an adapter to the registry under the provided key.
|
46
|
+
# @param key [String, Symbol] The key that identifies the adapter.
|
47
|
+
# @yield The body of the adapter class.
|
48
|
+
# @return [void]
|
49
|
+
# @since 4.0.0
|
50
|
+
def register_adapter(key, adapter = nil)
|
51
|
+
adapter = Builder.new(key, &proc).build_adapter if block_given?
|
52
|
+
|
53
|
+
unless adapter.is_a?(Class)
|
54
|
+
raise ArgumentError, I18n.t("lita.core.register_adapter.block_or_class_required")
|
55
|
+
end
|
56
|
+
|
57
|
+
adapters[key.to_sym] = adapter
|
58
|
+
end
|
59
|
+
|
60
|
+
# @overload register_handler(handler)
|
61
|
+
# Adds a handler to the registry.
|
62
|
+
# @param handler [Lita::Handler] The handler class.
|
63
|
+
# @return [void]
|
64
|
+
# @overload register_handler(key)
|
65
|
+
# Adds a handler to the registry.
|
66
|
+
# @param key [String] The namespace of the handler.
|
67
|
+
# @yield The body of the handler class.
|
68
|
+
# @return [void]
|
69
|
+
# @since 4.0.0
|
70
|
+
def register_handler(handler_or_key)
|
71
|
+
if block_given?
|
72
|
+
handler = Builder.new(handler_or_key, &proc).build_handler
|
73
|
+
else
|
74
|
+
handler = handler_or_key
|
75
|
+
|
76
|
+
unless handler.is_a?(Class)
|
77
|
+
raise ArgumentError, I18n.t("lita.core.register_handler.block_or_class_required")
|
78
|
+
end
|
79
|
+
end
|
80
|
+
|
81
|
+
handlers << handler
|
82
|
+
end
|
83
|
+
|
84
|
+
# Adds a hook handler object to the registry for the given hook.
|
85
|
+
# @return [void]
|
86
|
+
# @since 3.2.0
|
87
|
+
def register_hook(name, hook)
|
88
|
+
hooks[name.to_s.downcase.strip.to_sym] << hook
|
89
|
+
end
|
90
|
+
|
91
|
+
# Clears the configuration object and the adapter, handler, and hook registries.
|
92
|
+
# @return [void]
|
93
|
+
# @since 3.2.0
|
94
|
+
def reset
|
95
|
+
reset_adapters
|
96
|
+
reset_config
|
97
|
+
reset_handlers
|
98
|
+
reset_hooks
|
99
|
+
end
|
100
|
+
|
101
|
+
# Resets the adapter registry, removing all registered adapters.
|
102
|
+
# @return [void]
|
103
|
+
# @since 3.2.0
|
104
|
+
def reset_adapters
|
105
|
+
@adapters = nil
|
106
|
+
end
|
107
|
+
|
108
|
+
# Resets the configuration object. The next call to {#config}
|
109
|
+
# will create a fresh config object.
|
110
|
+
# @return [void]
|
111
|
+
def reset_config
|
112
|
+
@config = nil
|
113
|
+
end
|
114
|
+
alias_method :clear_config, :reset_config
|
115
|
+
|
116
|
+
# Resets the handler registry, removing all registered handlers.
|
117
|
+
# @return [void]
|
118
|
+
# @since 3.2.0
|
119
|
+
def reset_handlers
|
120
|
+
@handlers = nil
|
121
|
+
end
|
122
|
+
|
123
|
+
# Resets the hooks registry, removing all registered hook handlers.
|
124
|
+
# @return [void]
|
125
|
+
# @since 3.2.0
|
126
|
+
def reset_hooks
|
127
|
+
@hooks = nil
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
include Mixins
|
132
|
+
end
|
133
|
+
end
|