lita 1.1.2 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 6481f1efae6591656a5568118250b016f996895b
4
- data.tar.gz: dcbb5b21902747c0d9e15f3295b1b1a6faab3ea1
3
+ metadata.gz: 08671280114ef4f96291a7b7f296e7b616f40647
4
+ data.tar.gz: dc0372bef9351ea61ae833568d07302f586896fa
5
5
  SHA512:
6
- metadata.gz: 7a97fbc70295e6b060f058eb7ed16bdef50e8878c53a430c13df4bdccf7511c4f6547dd576d722aab3f14b730721c70c9911219c72c470a6cfd4b47095a14cbe
7
- data.tar.gz: 08a9eee29bcffa5c6f0b870eaac12f470287bf7bcab2e35e662221884e180a32f86b0090a02cbdf449ebd2220bacc7d8dc00976b6ce05aacd863c7d7d272c30f
6
+ metadata.gz: e6c6c3f23fa4657320607973ef740765863539a1b5fe4fb281c92b8bddd8c6f6285be942b691b04ab9f0a0f1ea54a8aafbb81615bf88bfc79df4d02c4fa4bf4e
7
+ data.tar.gz: b655f0ff87524fb958f83398ffa5adae67b955eca3b281c3eab915dbda71517e034d2016fb05ed3f3685dc68f5497ce02c2a97fbd9c29ba6e09793154d0863e8
data/README.md CHANGED
@@ -4,10 +4,23 @@
4
4
  [![Code Climate](https://codeclimate.com/github/jimmycuadra/lita.png)](https://codeclimate.com/github/jimmycuadra/lita)
5
5
  [![Coverage Status](https://coveralls.io/repos/jimmycuadra/lita/badge.png)](https://coveralls.io/r/jimmycuadra/lita)
6
6
 
7
+ ![Lita](http://f.cl.ly/items/0c271a2P3k2V180B1R0X/lita.jpg)
8
+
7
9
  **Lita** is a chat bot written in Ruby with persistent storage provided by [Redis](http://redis.io/). It can connect to any chat service (given that there is an [adapter](#adapters) available for it) and can have new behavior added via [handlers](#handlers). The plugin system is managed with regular RubyGems and [Bundler](http://gembundler.com/).
8
10
 
9
11
  Automate your business and have fun with your very own robot companion.
10
12
 
13
+ ## Features
14
+
15
+ * Can work with any chat service
16
+ * Simple installation and setup
17
+ * Easily extendable with plugins
18
+ * Data persistence with Redis
19
+ * Built-in web server and routing
20
+ * Support for outgoing HTTP requests
21
+ * Group-based authorization
22
+ * Configurable logging
23
+
11
24
  ## Why?
12
25
 
13
26
  Lita draws much inspiration from GitHub's fantastic [Hubot](http://hubot.github.com/), but has a few key differences and strengths:
@@ -15,9 +28,13 @@ Lita draws much inspiration from GitHub's fantastic [Hubot](http://hubot.github.
15
28
  * It's written in Ruby.
16
29
  * It exposes the full power of Redis rather than using it to serialize JSON.
17
30
  * Is easy to develop and test plugins for with the provied [RSpec](https://github.com/rspec/rspec) extras. Lita strongly encourages thorough testing of plugins.
18
- * It uses uses the Ruby ecosystem's standard tools (RubyGems and Bundler) for plugins.
31
+ * It uses uses the Ruby ecosystem's standard tools (RubyGems and Bundler) for plugin installation and loading.
19
32
  * It's thoroughly documented.
20
33
 
34
+ ## Is it any good?
35
+
36
+ Yes.
37
+
21
38
  ## Dependencies
22
39
 
23
40
  * Ruby 2.0
@@ -31,7 +48,7 @@ Generate a new Lita instance by running `lita new NAME`. This will create a new
31
48
 
32
49
  ## Usage
33
50
 
34
- To start your Lita instance, simply run `bundle exec lita`. This will load up all the plugins (adapters and handlers) declared in your Gemfile, load any configuration you've defined (more on that later) and start the bot.
51
+ To start your Lita instance, simply run `lita`. This will load up all the plugins (adapters and handlers) declared in your Gemfile, load any configuration you've defined (more on that later) and start the bot.
35
52
 
36
53
  ## Adapters
37
54
 
@@ -66,19 +83,22 @@ Lita.configure do |config|
66
83
  config.adapter.password = "secret"
67
84
  config.redis.host = "redis.example.com"
68
85
  config.handlers.karma.cooldown = 300
69
- config.handlers.google_images.safe_search = false
86
+ config.handlers.google_images.safe_search = :off
70
87
  end
71
88
  ```
72
89
 
73
90
  The main config objects are:
74
91
 
75
92
  * `robot` - General settings for Lita.
76
- * `name` - The display name the bot will use on the chat service.
77
- * `mention_name` - The name the bot will look for in messages to determine if the message is being addressed to it. Usually this is the same as the display name, but in some cases it may not be. For example, on HipChat, display names are required to be a first and last name, such as "Lita Bot", whereas the mention system would use a name like "LitaBot". This value defaults to whatever the name is if it's not set.
78
- * `adapter` - A symbol or string indicating the adapter to load.
79
- * `log_level` - A symbol or string indicating the severity level of log messages to output. Valid options are, in order of severity - `:debug`, `:info`, `:warn`, `:error`, and `:fatal`. For whichever level you choose, log messages of that severity and greater will be output. The default level is `:info`.
80
- * `admins` - An array of string user IDs which tell Lita which users are considered administrators. Only these users will have access to Lita's `auth` command.
93
+ * `name` (String) - The display name the bot will use on the chat service. Default: `"Lita"`.
94
+ * `mention_name` (String) - The name the bot will look for in messages to determine if the message is being addressed to it. Usually this is the same as the display name, but in some cases it may not be. For example, in HipChat, display names are required to be a first and last name, such as "Lita Bot", whereas the mention system would use a name like "LitaBot". Default: `Lita.config.robot.name`.
95
+ * `adapter` (Symbol, String) - The adapter to load. Default: `:shell`.
96
+ * `log_level` (Symbol, String) - The severity level of log messages to output. Valid options are, in order of severity: `:debug`, `:info`, `:warn`, `:error`, and `:fatal`. For whichever level you choose, log messages of that severity and greater will be output. Default: `:info`.
97
+ * `admins` (Array<String>) - An array of string user IDs which tell Lita which users are considered administrators. Only these users will have access to Lita's `auth` command. Default: `nil`.
81
98
  * `redis` - Options for the Redis connection. See the [Redis gem](https://github.com/redis/redis-rb) documentation.
99
+ * `http` - Settings related to Lita's built-in web server.
100
+ * `port` (Integer) - The port the server should run on. Default: `8080`.
101
+ * `debug` (Boolean) - Set to true to display the web server's logs mixed in with Lita's own logs. Default: `false`.
82
102
  * `adapter` - Options for the chosen adapter. See the adapter's documentation.
83
103
  * `handlers` - Handlers may choose to expose a config object here with their own options. See the handler's documentation.
84
104
 
@@ -99,6 +119,12 @@ The first command adds a user whose ID or name is "joe" to the authorization gro
99
119
 
100
120
  Message Lita `help` for a list of commands it knows about. You can also message it `help FOO` to list only commands beginning with FOO.
101
121
 
122
+ ## Shell adapter
123
+
124
+ Lita ships with one adapter for use directly in the shell. Simply type text at the input to send messages, and Lita will respond with any registered handlers. The shell adapter has one configuration attribute:
125
+
126
+ * `private_chat` (Boolean) - If true, all messages will be treated as though they were sent in a private chat, so they will be considered commands even when not prefixed with the bot's name. Default: `false`.
127
+
102
128
  ## Writing an adapter
103
129
 
104
130
  An adapter is a packaged as a RubyGem. The adapter is a class that inherits from `Lita::Adapter`, implements a few required methods, and is registered by calling `Lita.register_adapter(:symbol_that_identifies_the_adapter, TheAdapterClass)`.
@@ -140,56 +166,90 @@ end
140
166
 
141
167
  It's important to note that each adapter should employ its own thread or event mechanism so that incoming messages can still be processed even while a handler is processing a previous message.
142
168
 
143
- For more detailed examples, check out the built in shell adapter or [lita-hipchat](https://github.com/jimmycuadra/lita-hipchat). Also check out the API documentation.
169
+ For more detailed examples, check out the built in shell adapter, [lita-hipchat](https://github.com/jimmycuadra/lita-hipchat), or [lita-irc](https://github.com/jimmycuadra/lita-irc). See the API documentation for the exact methods and signatures adapters must implement.
144
170
 
145
171
  ## Writing a handler
146
172
 
147
- A handler is packaged as a RubyGem. A handler is a class that inherits from `Lita::Handler` and is registered by calling `Lita.register_handler(TheHandlerClass)`. There are two components to a handler: route definitions, and the methods that implement those routes.
173
+ A handler is packaged as a RubyGem. A handler is a class that inherits from `Lita::Handler` and is registered by calling `Lita.register_handler(TheHandlerClass)`. There are two components to a handler: route definitions, and the methods that implement those routes. There are both chat routes and HTTP routes available to handlers.
174
+
175
+ ### Chat routes
148
176
 
149
177
  To define a route, use the class method `route`:
150
178
 
151
179
  ``` ruby
152
- route /^echo\s+(.+)/, to: :echo
180
+ route /^echo\s+(.+)/, :echo
153
181
  ```
154
182
 
155
- `route` takes a regular expression that will be used to determine whether or not an incoming message should trigger the route. The keyword argument `:to` is supplied the name of the method that should be called when this route is triggered. `route` takes two additional options:
183
+ `route` takes a regular expression that will be used to determine whether or not an incoming message should trigger the route, and the name of the method that should be called when this route is triggered. `route` takes a few additional options:
156
184
 
157
- * `:command` - A boolean which, if set to true, means that the route will only trigger when "directed" at the robot. Directed means that it's sent via a private message, or the message is prefixed with the bot's name in some form (optionally prefixed with an @, and optionally followed by a colon or comma and white space). This prefix is stripped from the message body itself, but the `command?` method available to handlers can be used if you need to determine whether or not a message was a command after it's been routed.
158
- * `:required_groups` - A string, symbol, or array of strings/symbols, specifying authorization groups necessary to trigger the route. The user sending the message must be a member of at least one of the supplied groups. See the section on authorization for more information.
185
+ * `:command` (Boolean) - If set to true, the route will only trigger when "directed" at the robot. Directed means that it's sent via a private message, or the message is prefixed with the bot's name in some form (optionally prefixed with an @, and optionally followed by a colon or comma and white space). This prefix is stripped from the message body itself, but `Lita::Message#command?` available in handlers can be used if you need to determine whether or not a message was a command after it's been routed. Default: `false`.
186
+ * `:restrict_to` (Symbol, String, Array<String, Symbol>) - Authorization groups necessary to trigger the route. The user sending the message must be a member of at least one of the supplied groups. See the section on authorization for more information. Default: `nil`.
187
+ * `:help` (Hash<String>) - A map of example invocations of the route and descriptions of what they do. These values will be used to generate the listing for the built-in "help" handler. The robot's mention name will automatically be added to the front of the example if the route is a command. Default: `{}`.
159
188
 
160
189
  Here is an example of a route declaration with all the options:
161
190
 
162
191
  ``` ruby
163
- route /^echo\s+(.+)/, to :echo, command: true, required_groups: [:testers, :committers]
192
+ route /^echo\s+(.+)/, to: :echo, command: true, restrict_to: [:testers, :committers], help => {
193
+ "echo FOO" => "Replies back with FOO."
194
+ }
164
195
  ```
165
196
 
166
- Each method that is called by a route takes one argument, an array of matches extracted by calling `message.scan(route_pattern)`. Handler methods have several other methods available to them to assist in performing other tasks and in most cases responding to the user who sent the message:
197
+ Each method that is called by a route takes one argument, a `Lita::Response` object. This object has the following useful methods:
167
198
 
168
199
  * `reply` - Sends one or more string messages back to the source of the original message, either a private message or a chat room.
169
- * `redis` - A `Redis::Namespace` object which provides each handler with its own isolated Redis store, suitable for many data persistence and manipulation tasks.
170
- * `args` - The user's message as an array of strings, as it would be parsed by `Shellwords.split`. For example, if the message was "Lita: auth add joe committers", calling `args` would return `["auth", "add", "joe", "committers"]`. This is very handy for commands that take arguments in a way similar to how a UNIX shell would work.
200
+ * `matches` - An array of regular expression matches obtained by calling `body_of_message.scan(route_regex)`.
201
+ * `args` - The user's message as an array of strings, as it would be parsed by `Shellwords.split`. For example, if the message was "Lita: auth add joe committers", calling `args` would return `["add", "joe", "committers"]`. ("auth" is considered the command and so is not included in the arguments.) This is very handy for commands that take arguments in a way similar to how a UNIX shell would work.
202
+ * `message` - A `Lita::Message` object for the incoming message.
171
203
  * `user` - A `Lita::User` object for the user who sent the message.
172
- * `command?` - A boolean indicating whether or not the current message was directed at the robot.
173
- * `message_body` - The full body of the user's message, as a string.
174
204
 
175
- To add entries to Lita's built-in `help` command for your handler's commands, add a class method called `help` that returns a hash, where the keys are the format of the command, and the values are a description of what it does.
205
+ Additionally, handlers have access to these top-level methods:
176
206
 
177
- ### Example
207
+ * `robot` - Direct access to the currently running `Lita::Robot` object.
208
+ * `redis` - A `Redis::Namespace` object which provides each handler with its own isolated Redis store, suitable for many data persistence and manipulation tasks.
209
+ * `http` - A `Faraday::Connection` object for making HTTP requests. Takes an optional hash of options and optional block which are passed on to [Faraday](https://github.com/lostisland/faraday).
178
210
 
179
- Here is a basic handler which simply echoes back whatever the user says.
211
+ ### HTTP routes
212
+
213
+ In addition to chat routes, handlers can also define HTTP routes for the built-in web server. This is done with the class-level `http` method. `http` returns a `Lita::HTTPRoute` object, which has methods for the most common HTTP methods. These methods take two arguments: the path for the route, and the name of the method that it will invoke as a symbol. The callback method takes two arguments: a `Rack::Request` and a `Rack::Response`. For example:
214
+
215
+ ``` ruby
216
+ http.get "/foo/bar", :baz
217
+
218
+ def baz(request, response)
219
+ response.body = "Hello, world!"
220
+ end
221
+ ```
222
+
223
+ ### Handler-specific configuration
224
+
225
+ If you want your handler to expose config settings to the user, use the class-level `default_config` method. This method accepts a single config object as an argument, which will be exposed to the user as `Lita.config.handlers.your_handler_namespace`.
180
226
 
181
227
  ``` ruby
182
228
  module Lita
183
229
  module Handlers
184
- class Echo < Handler
185
- def self.help
186
- { "#{Lita.config.robot.name}: echo FOO" => "Echoes back FOO." }
230
+ class HandlerWithConfig < Handler
231
+ def self.default_config(config)
232
+ config.enabled = true
187
233
  end
234
+ end
235
+ end
236
+ end
237
+
238
+ Lita.config.handlers.handler_with_config.enabled # => true
239
+ ```
188
240
 
189
- route /^echo\s+(.+)/, to: :echo
241
+ ### Examples
242
+
243
+ Here is a basic handler which simply echoes back whatever the user says.
244
+
245
+ ``` ruby
246
+ module Lita
247
+ module Handlers
248
+ class Echo < Handler
249
+ route /^echo\s+(.+)/, :echo, help: { "echo FOO" => "Echoes back FOO." }
190
250
 
191
251
  def echo(matches)
192
- reply matches
252
+ response.reply(response.matches)
193
253
  end
194
254
  end
195
255
 
@@ -197,51 +257,148 @@ module Lita
197
257
  end
198
258
  end
199
259
  ```
200
- For more detailed examples, check out the built in authorization and help handlers or [lita-karma](https://github.com/jimmycuadra/lita-karma). Also check out the API documentation.
260
+
261
+ Here is a handler that tells a user who their United States congressional representative is based on zip code with data from a fictional HTTP API. The results are saved in the handler's namespaced Redis store to save HTTP calls on future requests.
262
+
263
+ ``` ruby
264
+ module Lita
265
+ module Handlers
266
+ class Representative < Handler
267
+ route /representative\s+(\d{5})/, :lookup, command: true, help: {
268
+ "representative ZIP_CODE" => "Looks up the United States congressional representative for your zip code."
269
+ }
270
+
271
+ def lookup(response)
272
+ zip = response.matches[0][0]
273
+ rep = redis.get(zip)
274
+ rep = get_rep(zip) unless rep
275
+ response.reply "The representative for #{zip} is #{rep}."
276
+ end
277
+
278
+ private
279
+
280
+ def get_rep(zip)
281
+ http_response = http.get(
282
+ "http://www.example.com/api/represenative",
283
+ zip_code: zip
284
+ )
285
+
286
+ data = MultiJson.load(http_response.body)
287
+ rep = data["representative"]["name"]
288
+ redis.set(zip, data["representative"]["name"])
289
+ rep
290
+ end
291
+ end
292
+
293
+ Lita.register_handler(Representative)
294
+ end
295
+ end
296
+ ```
297
+
298
+ For more detailed examples, check out the built in authorization, help, and web handlers, or external handlers [lita-karma](https://github.com/jimmycuadra/lita-karma) and [lita-google-images](https://github.com/jimmycuadra/lita-google-images). See the API documentation for exact specifications for handlers' methods.
201
299
 
202
300
  ## Testing
203
301
 
204
- It's a core philosophy of Lita that any handlers you write for your robot should be as thoroughly tested as any other program you would write. To make this easier, Lita ships with some handy extras for [RSpec](https://github.com/rspec/rspec) that make testing a handler dead simple.
302
+ It's a core philosophy of Lita that any plugins you write for your robot should be as thoroughly tested as any other program you would write. To make this easier, Lita ships with some handy extras for [RSpec](https://github.com/rspec/rspec) that make testing a handler dead simple. They require the full RSpec suite (rspec-core, rspec-expectations, and rspec-mocks) version 2.14 or higher, as they use the newer `expect(obj).to receive(:message)` syntax.
303
+
304
+ ### Testing handlers
205
305
 
206
- To include Lita's RSpec extras, require "lita/rspec" and add `lita: true` to any `describe` block where you want the extras:
306
+ To include Lita's RSpec extras for testing a handler, require "lita/rspec", then add `lita_handler: true` to the metadata for the example group.
207
307
 
208
308
  ``` ruby
209
309
  require "lita/rspec"
210
310
 
211
- describe Lita::Handlers::MyHandler, lita: true do
311
+ describe Lita::Handlers::MyHandler, lita_handler: true do
212
312
  # ...
213
313
  end
214
314
  ```
215
315
 
216
- `Lita::RSpec` makes the following changes to make testing easier:
316
+ This provides the following:
217
317
 
218
- * `Lita.handlers` will return an array with only the class you're testing (`described_class`).
219
318
  * All Redis interaction will be namespaced to a test environment and automatically cleared out before each example.
220
- * `Lita::Robot#send_messages` will be stubbed out so the shell adapter doesn't actually spit messages out into your terminal.
221
- * You have access to the following cached objects set with `let`: `robot`, `source`, and `user`.
319
+ * Lita's logger is stubbed to prevent log messages from cluttering up your test output.
320
+ * Lita's configuration is cleared out before each example, so that the first call to `Lita.config` will start from the default configuration.
321
+ * `Lita.handlers` will return an array with only the class you're testing (`described_class`).
322
+ * Strings sent with `Lita::Robot#send_messages` will be pushed to an array accessible as `replies` so you can make expectations about output from the robot.
323
+ * You have access to the following cached objects set with `let`: `robot`, `source`, and `user`. Note that these objects are instances of the real classes and not test doubles.
222
324
 
223
- The custom helper methods are where `Lita::RSpec` really shines. You can test routes very easily using this syntax:
325
+ The custom helper methods are where `Lita::RSpec` really shines. You can test routes (both chat and HTTP routes) very easily using this syntax:
224
326
 
225
327
  ``` ruby
226
328
  it { routes("some message").to(:some_method) }
227
- it { routes("#{robot.name} directed message").to(:some_command_method) }
329
+ it { routes_command("directed message").to(:some_command_method) }
228
330
  it { doesnt_route("message").to(:some_command_method) }
331
+ it { routes_http(:get, "/foo/bar").to(:baz) }
332
+ it { doesnt_route_http(:post, "/foo/bar").to(:baz) }
229
333
  ```
230
334
 
231
- You can also use the alias `does_not_route` if you prefer that to `doesnt_route`. These methods allow you to test your routing in a terse, expressive way.
335
+ * `routes` - Sets an expectation that the given string will trigger the given method when overheard by the robot.
336
+ * `routes_command` - Sets an expectation that the given string will trigger the given method when directed at the robot, either in a private message, or by prefixing a message in a chat room with the robot's mention name.
337
+ * `doesnt_route` - Sets an expectation that is the inverse of the one set by `routes`. Also aliased to `does_not_route`.
338
+ * `doesnt_route_command` - Sets an expectation that is the inverse of the one set by `routes_command`. Also aliased to `does_not_route_command`.
339
+ * `routes_http` - Sets an expectation that an HTTP request with the given HTTP method and path will route to the given handler method.
340
+ * `doesnt_route_http` - Sets an expectation that is the inverse of `routes_http`. Also aliased to `does_not_route_http`.
232
341
 
233
- To test the functionality of your methods, two additional methods are provided:
342
+ **Note: These routing helpers bypass authorization for routes restricted to authorization groups.**
343
+
344
+ To send a message to the robot, use `send_message` and `send_command`. Then set expectations about the contents of the `replies` array.
234
345
 
235
346
  ``` ruby
236
- expect_reply("Hello, #{user.name}.")
237
- send_test_message("#{robot.name}: hi")
347
+ it "lets everyone know when someone is happy" do
348
+ send_message("I'm happy!")
349
+ expect(replies.last).to eq("Hey, everyone! #{user.name} is happy! Isn't that nice?")
350
+ end
351
+
352
+ it "greets anyone that says hi to it" do
353
+ send_command("hi")
354
+ expect(repliest.last).to eq("Hello, #{user.name}!")
355
+ end
238
356
  ```
239
357
 
240
- `expect_reply` takes one or more argument matchers that it expects your handler to reply with. The arguments can be strings, regular expressions, or any other RSpec argument matcher. You can also use the alias `expect_replies` if you're passing multiple arguments.
358
+ If you want to send a message or command from a user other than the default test user (set up for you with `let(:user)` by `Lita::RSpec`), you can invoke either method with the `:as` option, supplying a `Lita::User` object.
359
+
360
+ ``` ruby
361
+ it "lets everyone know that Carl is happy" do
362
+ carl = Lita::User.create(123, name: "Carl")
363
+ send_message("I'm happy!", as: carl)
364
+ expect(replies.last).to eq("Hey, everyone! Carl is happy! Isn't that nice?")
365
+ end
366
+ ```
367
+
368
+ * `send_message(string, as: user)` - Sends the given string to the robot.
369
+ * `send_command(string, as: user)` - Sends the given string to the robot, prefixing it with the robot's mention name.
370
+
371
+ ### Testing adapters or other code
372
+
373
+ If you use `lita: true` instead of `lita_handler: true` in the metadata for your example group, only a small subset of Lita's RSpec extras will be enabled:
374
+
375
+ * All Redis interaction will be namespaced to a test environment and automatically cleared out before each example.
376
+ * Lita's logger is stubbed to prevent log messages from cluttering up your test output.
377
+ * Lita's configuration is cleared out before each example, so that the first call to `Lita.config` will start from the default configuration.
378
+
379
+ ## Deploying to Heroku
380
+
381
+ There are a few things worth mentioning when deploying an instance of Lita to Heroku:
382
+
383
+ 1. Your Procfile should contain one process: `web: bundle exec lita`.
384
+
385
+ 1. To use the Redis To Go add-on, configure Lita's redis connection like this:
386
+
387
+ ``` ruby
388
+ Lita.configure do |config|
389
+ config.redis.url = ENV["REDISTOGO_URL"]
390
+ end
391
+ ```
392
+
393
+ 1. Consider using a service like [Uptime Robot](http://www.uptimerobot.com/) to monitor your Lita instance and keep it from [sleeping](https://blog.heroku.com/archives/2013/6/20/app_sleeping_on_heroku) when running on a free dyno. `/lita/info` is a reliable path to hit from the web to keep it running.
394
+
395
+ ## API documentation
396
+
397
+ Complete documentation for all of Lita's classes and methods can be found at [rdoc.info](http://rdoc.info/gems/lita/frames).
241
398
 
242
- `send_test_message` does what you would expect: It sends the given message to your handler, using the `user` and `source` provided by the cached `let` objects.
399
+ ## History
243
400
 
244
- For negative message expectations, you can use `expect_no_reply` and its alias `expect_no_replies`, which also take any number of argument matchers.
401
+ For a history of releases, see the [Releases](https://github.com/jimmycuadra/lita/releases) page.
245
402
 
246
403
  ## License
247
404
 
@@ -3,50 +3,78 @@ require "logger"
3
3
  require "set"
4
4
  require "shellwords"
5
5
 
6
+ require "faraday"
7
+ require "multi_json"
8
+ require "rack"
6
9
  require "redis-namespace"
10
+ require "thin"
7
11
 
8
12
  require "lita/version"
9
13
  require "lita/config"
10
14
 
15
+ # The main namespace for Lita. Provides a global registry of adapters and
16
+ # handlers, as well as global configuration, logger, and Redis store.
11
17
  module Lita
18
+ # The base Redis namespace for all Lita data.
12
19
  REDIS_NAMESPACE = "lita"
13
20
 
14
21
  class << self
22
+ # The global registry of adapters.
23
+ # @return [Hash] A map of adapter keys to adapter classes.
15
24
  def adapters
16
25
  @adapters ||= {}
17
26
  end
18
27
 
28
+ # Adds an adapter to the global registry under the provided key.
29
+ # @param key [String, Symbol] The key that identifies the adapter.
30
+ # @param adapter [Lita::Adapter] The adapter class.
31
+ # @return [void]
19
32
  def register_adapter(key, adapter)
20
33
  adapters[key.to_sym] = adapter
21
34
  end
22
35
 
36
+ # The global registry of handlers.
37
+ # @return [Set] The set of handlers.
23
38
  def handlers
24
39
  @handlers ||= Set.new
25
40
  end
26
41
 
42
+ # Adds a handler to the global registry.
43
+ # @param handler [Lita::Handler] The handler class.
44
+ # @return [void]
27
45
  def register_handler(handler)
28
46
  handlers << handler
29
47
  end
30
48
 
49
+ # The global configuration object. Provides user settings for the robot.
50
+ # @return [Lita::Config] The Lita configuration object.
31
51
  def config
32
52
  @config ||= Config.default_config
33
53
  end
34
54
 
55
+ # Yields the global configuration object. Called by the user in a
56
+ # lita_config.rb file.
57
+ # @yieldparam [Lita::Configuration] config The global configuration object.
58
+ # @return [void]
35
59
  def configure
36
60
  yield config
37
61
  end
38
62
 
63
+ # Clears the global configuration object. The next call to {Lita.config}
64
+ # will create a fresh config object.
65
+ # @return [void]
66
+ def clear_config
67
+ @config = nil
68
+ end
69
+
70
+ # The global Logger object.
71
+ # @return [::Logger] The global Logger object.
39
72
  def logger
40
- @logger ||= begin
41
- logger = Logger.new(STDERR)
42
- logger.level = log_level
43
- logger.formatter = proc do |severity, datetime, progname, msg|
44
- "[#{datetime.utc}] #{severity}: #{msg}\n"
45
- end
46
- logger
47
- end
73
+ @logger ||= Logger.get_logger(Lita.config.robot.log_level)
48
74
  end
49
75
 
76
+ # The root Redis object.
77
+ # @return [Redis::Namespace] The root Redis object.
50
78
  def redis
51
79
  @redis ||= begin
52
80
  redis = Redis.new(config.redis)
@@ -54,36 +82,29 @@ module Lita
54
82
  end
55
83
  end
56
84
 
85
+ # Loads user configuration and starts the robot.
86
+ # @param config_path [String] The path to the user configuration file.
87
+ # @return [void]
57
88
  def run(config_path = nil)
58
89
  Config.load_user_config(config_path)
59
90
  Robot.new.run
60
91
  end
61
-
62
- private
63
-
64
- def log_level
65
- level = config.robot.log_level
66
-
67
- if level
68
- begin
69
- Logger.const_get(level.to_s.upcase)
70
- rescue NameError
71
- return Logger::INFO
72
- end
73
- else
74
- Logger::INFO
75
- end
76
- end
77
92
  end
78
93
  end
79
94
 
95
+ require "lita/util"
96
+ require "lita/logger"
80
97
  require "lita/user"
81
98
  require "lita/source"
82
99
  require "lita/authorization"
83
100
  require "lita/message"
101
+ require "lita/response"
102
+ require "lita/http_route"
103
+ require "lita/rack_app_builder"
84
104
  require "lita/robot"
85
105
  require "lita/adapter"
86
106
  require "lita/adapters/shell"
87
107
  require "lita/handler"
88
108
  require "lita/handlers/authorization"
89
109
  require "lita/handlers/help"
110
+ require "lita/handlers/web"