README.md in cogy-0.0.3 vs README.md in cogy-0.1.0
- old
+ new
@@ -1,77 +1,146 @@
# Cogy
+[![Build Status](https://api.travis-ci.org/skroutz/cogy.svg?branch=master)](https://travis-ci.org/skroutz/cogy)
+[![Gem Version](https://badge.fury.io/rb/cogy.svg)](https://badge.fury.io/rb/cogy)
+[![Inline docs](http://inch-ci.org/github/skroutz/cogy.svg)](http://inch-ci.org/github/skroutz/cogy)
+
Cogy integrates [Cog](https://operable.io/) with Rails
-in a way that managing commands becomes a breeze.
+in a way that writing & deploying commands from your application is a breeze.
+See the API documentation [here](http://www.rubydoc.info/github/skroutz/cogy).
+
## Status
-*DISCLAIMER*: While we use Cogy in production, it's still in public alpha and
-is under heavy development.
+Cogy is still in public alpha.
-This means that a few critical bits are missing (the Relay executable and
-RSpec helpers to name a few) and the API is not stable yet.
+While we use it in production, it's still under heavy development.
+This means that there are a few rough edges and some important bits are missing.
-However, feel free to test it and gives us your feedback!
+However we'd love any [feedback, suggestions or ideas](https://github.com/skroutz/cogy/issues/new).
## Why
-Creating a Cog command that talks with a Rails app typically involves writing
+Creating a ChatOps command that talks with a Rails app typically involves writing
a route, maybe a controller, an action and code to handle the command arguments
and options.
-This is a tedious and repetitive task and involves writing a lot of boilerplate
+This is a tedious and repetitive task and involves a lot of boilerplate
code each time someone wants to add a new command.
Cogy is an opinionated library that provides a way to get rid of all the
-repetitive work and makes writing commands a breeze!
+repetitive work.
-Making a new command available for use is as simple as adding the following line
-to a file in your application:
+Writing a new command and deploying it is as simple as:
```ruby
# in cogy/my_commands.rb
-on "foo", desc: "Echo a foo bar back at you!" do |_args, _opts, user|
- "@#{user}: foo bar"
+on "foo", desc: "Echo a foo bar back at you!" do
+ "@#{handle}: foo bar"
end
```
-...and deploying!
+...and deploying! After a second or so, the command is ready to be used.
## How it works
Cogy is essentially three things:
1. An opinionated way to write, manage & ship commands: All Cogy commands are
- defined in your Rails app and end up invoking a single executable within the
- Relay (see below). Cogy provides versioning and dynamically generates the
- bundle config, which is also served by your Rails app (via a Rails Engine).
- This, accompanied with the command [TODO: INSERT LINK HERE] that
- can install bundles from other bundles, makes it possible to automatically
- install the newly-written commands by invoking a trigger when you deploy
- your app.
-2. A Rails Engine that is mounted in your application and routes the incoming
- requests to their user-defined handlers. It also creates the `/inventory`
+ defined in your Rails app and end up invoking a [single executable](https://github.com/skroutz/cogy-bundle/blob/master/commands/cogy) within the
+ Relay. Cogy also provides bundle versioning and dynamically generates the
+ installable bundle config, which is also served by your Rails application
+ and consumed by the [`cogy:install`](https://github.com/skroutz/cogy-bundle)
+ command that installs the new Cogy-generated bundle when you deploy your
+ application.
+2. A library that provides the API for defining the commands. This library
+ is integrated in your application via a Rails Engine that routes the incoming
+ requests to their respective handlers. It also creates the `/inventory`
endpoint, which serves the installable bundle configuration in YAML and can be
- consumed directly by the `cogutils:install` command [TODO: INSERT LINK].
-3. An executable [TODO: INSERT LINK HERE] which all commands point to.
- This is placed inside the Relays and performs the requests to your application
+ consumed directly by the [`cogy:install`](https://github.com/skroutz/cogy-bundle) command.
+3. A [Cog bundle](https://github.com/skroutz/cogy-bundle) that contains the
+ [executable](https://github.com/skroutz/cogy-bundle/blob/master/commands/cogy)
+ that all the commands end up invoking.
+ It is placed inside the Relays and performs the requests to your application
when a user invokes a command in the chat. It then posts the result back
- to the user.
+ to the user. It also contains the `cogy:install` command for automating
+ the task of installing the new bundle when a command is added/modified.
-## Installation
+Take a look at the relevant [diagrams](diagrams/) for an illustration of how
+Cogy works.
-Add the following to your Gemfile:
+## Requirements
+* [cogy bundle](https://github.com/skroutz/cogy-bundle)
+* Ruby 2.1+
+* Tested with Rails 4.2
+
+## Install
+
+Add it to your Gemfile:
+
```ruby
gem "cogy"
```
+Then run `bundle install`
+
+Next, run the generator:
+
+```shell
+$ bin/rails g cogy:install
+```
+
+This will create a sample command, mount the engine and add a sample
+configuration initializer in your application.
+
+## Usage
+
+Defining a new command:
+
+```ruby
+# in cogy/commands.rb
+
+on "foo", desc: "Echo a bar" do
+ "bar"
+end
+```
+
+This will print "bar" back to the user who calls `!foo` in Slack, for example.
+
+Inside the block there are the following pre-defined helpers available:
+
+* `#args`: an array containing the arguments passed to the command
+* `#opts`: a hash containing the options passed to the command
+* `#handle`: the chat handle of the user who called the command
+* `#env`: a hash containing the Cogy environment, that is, every environment variable
+ starting with 'COGY_' and set in the Relay
+
+For instructions on defining your own helpers, see [Helpers](#helpers).
+
+A more complete example:
+
+```ruby
+# in cogy/commands.rb
+on "calc",
+ args: [:a, :b],
+ opts: { op: { type: "string" } },
+ desc: "Performs a calculation between numbers <a> and <b>",
+ examples: "myapp:calc sum 1 2" do
+ op = opts[:op].to_sym
+ result = args.map(&:to_i).inject(&op)
+ "Hello @#{user}, the result is: #{result}"
+end
+```
+
+For more examples see the [test commands](https://github.com/skroutz/cogy/tree/master/test/dummy/cogy).
+
+
## Configuration
-The options provided are the following:
+The configuration options provided are the following:
```ruby
# in config/initializers/cogy.rb
Cogy.configure do |config|
@@ -84,14 +153,14 @@
#
# Default: "Cogy-generated commands"
config.bundle_description = "myapp-generated commands from Cogy"
# Can be either a string or an object that responds to `#call` and returns
- # a string. Must be set explicitly.
+ # a string.
config.bundle_version = "0.0.1"
- # If you used a callable object, it will be evaluated each time the inventory
+ # if you used a callable object, it will be evaluated each time the inventory
# is called. This can be useful if you want the version to change dynamically
# when it's needed.
#
# For example, this will change the version only when a command is
# added or is modified (uses the 'grit' gem).
@@ -99,11 +168,10 @@
repo = Grit::Repo.new(Rails.root.to_s)
repo.log("HEAD", "cogy/", max_count: 1).first.date.strftime("%y%m%d.%H%M%S")
}
# The path in the Relay where the cogy command executable is located at.
- # Must be set explicitly.
config.executable_path = "/cogcmd/cogy"
# Paths in your application where the files that define the commands live in.
# For example the default value will search for all `*.rb` files in the `cogy/`
# directory relative to the root of your application.
@@ -112,57 +180,77 @@
config.command_load_paths = "cogy"
end
```
-## Usage
+You can use the generator to quickly create a config initializer in your app:
-Commands are defined like so:
+```shell
+$ bin/rails g cogy:config
+```
+### Helpers
+
+It is possible to define helpers that can be used throughout commands. They
+can be defined during configuration and can accept a variable number of
+arguments, or no arguments at all.
+
+Let's define a helper that fetches a `Shops` address of the user who called the
+command:
+
```ruby
-# in cogy/commands.rb
+Cogy.configure do |c|
+ c.helper(:shop_address) { Shop.find_by(owner: handle).address }
+end
+```
-on "foo", desc: "Echo a bar" do
- "bar"
+*(Note that custom helpers also have access to the default helpers like
+`handle`, `args` etc.)*
+
+Then we could have a command like this:
+
+```ruby
+on "shop_address", desc: "Returns the user's Shop address" do
+ "@#{handle}: Your shop's address is #{shop_address}"
end
```
-The last line evaluated is the result of the command.
+We can also define helpers that accept arguments:
-A more complete example:
+```ruby
+Cogy.configure do |c|
+ c.helper(:format) { |answer| answer.titleize }
+end
+```
+Then in our command we could call it like so:
+
```ruby
-# in cogy/commands.rb
-on "calc",
- args: [:a, :b],
- opts: { op: { type: "string", required: true, short_flag: "o" } },
- desc: "Performs a calculation between numbers <a> and <b>",
- examples: "!myapp:calc sum 1 2" do |req_args, req_opts, user|
- op = req_opts[:op].to_sym
- result = req_args.map(&:to_i).inject(&op)
- "Hello @#{user}, the result is: #{result}"
+on "foo", desc: "Nothing special" do
+ format "hello there, how are you today?"
end
```
+Rails' URL helpers are also available inside the commands.
+
## Error template
-When a command throws an error, the default error template is rendered, which
+When a command throws an error the [default error template](https://github.com/skroutz/cogy/blob/master/app/views/cogy/error.text.erb) is rendered, which
is the following:
@<%= @user %>: Command '<%= @cmd %>' returned an error.
```
<%= @exception.class %>:<%= @exception.message %>
```
-However it can be overriden in the application by creating a view in
+It can be overriden in the application by creating a view in
`app/views/cogy/error.text.erb`.
## Authors
* [Agis Anastasopoulos](https://github.com/agis-)
* [Mpampis Kostas](https://github.com/charkost)
## License
Cogy is licensed under MIT. See [LICENSE](LICENSE).
-