README.md
# Stairs
It's a pain to set up new developers on your codebase. Stairs makes it easy.
### The Problem
Apps these days come with dependencies—S3, Facebook, Twitter, Zencoder, etc. We
can stub certain things in development, but we also want to make sure we're
developing in a realistic setting. Satisfying all of these requirements can
really slow down onboarding time when adding new developers to your existing
codebase.
### The Solution
Every codebase should come with a script to set itself up. An interactive
README, if you will. __Stairs__ aims to provide the tools to make writing these
scripts fast and easy. Scripts try to automate as much as possible and provide
interactive prompts for everything else.
[![Build Status](https://travis-ci.org/patbenatar/stairs.png?branch=master)](https://travis-ci.org/patbenatar/stairs)
[![Code Climate](https://codeclimate.com/github/patbenatar/stairs.png)](https://codeclimate.com/github/patbenatar/stairs)
## Table of Contents
* [Setup](#setup)
* [Running Scripts](#running-scripts)
* [Command Line Utility](#advanced)
* [Defining Scripts](#defining-scripts)
* [Collecting Input](#collecting-values)
* [Asking Questions](#asking-questions)
* [Setting ENV vars](#setting-env-vars)
* [Writing to Files](#writing-files)
* [Miscellaneous](#misc-helpers)
* [Steps](#steps)
* [Groups](#groups)
* [Plugins](#plugins)
## Setup
### Rails
Add Stairs to your `Gemfile`:
```ruby
gem "stairs"
```
[Define your script](#defining-scripts) in `setup.rb` at the root of your
project.
### Not Rails
Same as above, but you'll have to manually add the Stairs Rake tasks to your
`Rakefile`.
```ruby
require "stairs/tasks"
```
## Running Scripts
### Basic
In an app with a `setup.rb`, just run the rake task:
```
$ rake newb
```
### Advanced
If you want more control, use the `stairs` command line utility:
```
$ stairs --help
Usage: stairs [options]
--use-defaults Use defaults when available
-g, --groups GROUPS Specify groups to run. e.g. init,reset
```
## Defining scripts
A script composes many steps that setup a project.
```ruby
setup :secret_key_base
setup :s3
setup :zencoder, required: false
setup :misc do
env "CHECK_IT", provide("Cool check it value")
end
rake "db:setup db:test:prepare"
finish "Just run rails s and sidekiq to get rolling!"
```
[See Example CLI](#example-cli)
### Collecting values
```ruby
value = provide "Something"
value = provide "Another", required: false
provide "More", default: "a-default"
```
### Asking questions
```ruby
i_should = choice "Should I?"
choice "Should I?" do |yes|
do_something if yes
end
dinner = choice "Meat or vegetables?", ["Meat", "Vegetables"]
```
### Setting ENV vars
Stairs currently supports writing environment variables for rbenv-vars, RVM, and
dotenv.
```ruby
env "NAME", value
```
### Writing files
```ruby
write "awesome: true", "config/settings.yml"
write_line "more: false", "config/settings.yml"
```
### Misc helpers
Run rake tasks
```ruby
rake "task_name"
```
Display a message when setup completes
```ruby
finish "Now that you're done, go have a drink!"
```
### Steps
Group related setup procedures into named steps using `setup`:
```ruby
setup :a_cool_service do
# ...
end
```
#### Using predefined steps (aka plugins)
```ruby
setup :s3
setup :facebook, required: false
```
[Available Plugins](#plugins)
### Groups
Stairs supports organizing your script into groups in a way similar to what you
may be used to with Bundler. With groups you can target specific steps to run
for different use cases (see `-g` option in the [command line utility](#advanced)).
Anything outside of a group will always be executed. Anything within a group
will only be executed when its group is run. By default, Stairs runs the `newb`
group with `$ rake newb`.
For example, you may want to run different steps on a brand new setup than you
would when resetting an existing setup:
```ruby
group :newb do
setup :s3
end
group :newb, :reset do
setup :balanced
rake "db:setup"
end
```
And then run your reset like so:
```bash
$ stairs -g reset
```
## Plugins
Many projects share dependencies. Plugins are predefined setup steps for common
use cases.
Some steps support options. Options are specified as a hash like so:
```ruby
setup :step_name, option_1: "value", option_2: "value"
```
### Built-in
#### `:secret_key_base`
Sets a secure random secret token. This will write the following ENV vars:
`SECRET_KEY_BASE`
#### `:postgresql`
Quickly setup database.yml for use with PostgreSQL, including sensible defaults.
#### `:facebook`
Tnteractive prompt for setting Facebook app credentials. This will write the
following ENV vars: `FACEBOOK_ID`, `FACEBOOK_SECRET`
##### Options
* `app_id`: ENV var name for Facebook App ID
* `app_secret`: ENV var name for Facebook App Secret
### Available as independent gems
Any plugin that has specific dependencies on third party gems is shipped
independently to avoid maintaining those dependencies within Stairs.
* `:s3` interactive prompt for setting AWS + S3 bucket access credentials:
[patbenatar/stairs-steps-s3][s3]
* `:balanced` automatically creates a test Marketplace on Balanced:
[patbenatar/stairs-steps-balanced][balanced]
### Defining custom plugins
Steps inherit from `Stairs::Step` and live in `Stairs::Steps`, have a title,
description, and implement the `run` method. See those included and in the
various extension gems for examples.
## Example CLI
Given the [example script above](#defining-scripts), the CLI would look like
this:
```
$ rake newb
Looks like you're using rbenv to manage environment variables. Is this correct? (Y/N): Y
= Running script setup.rb
== Running S3
AWS access key: 39u39d9u291
AWS secret: 19jd920i10is0i01i0s01ks0kfknkje
Do you have an existing bucket? (Y/N): Y
Bucket name (leave blank for app-dev): my-cool-bucket
== Completed S3
== Starting Zencoder
This step is optional, would you like to perform it? (Y/N): N
== Completed Zencoder
== Starting Misc
Cool check it value: w00t
== Completed Misc
== Running db:setup
...
== Completed db:setup
== All done!
Run rails s and sidekiq to get rolling!
```
## Contributing
1. Fork it
2. Create your feature branch (`git checkout -b my-new-feature`)
3. Commit your changes (`git commit -am 'Add some feature'`)
4. Push to the branch (`git push origin my-new-feature`)
5. Create new Pull Request
[s3]: http://github.com/patbenatar/stairs-steps-s3
[balanced]: http://github.com/patbenatar/stairs-steps-balanced
## Credits
### Contributors
* [Nick Giancola](https://github.com/patbenatar)
* [Brendan Loudermilk](https://github.com/bloudermilk)
### Sponsor
[![philosophie](http://patbenatar.github.io/showoff/images/philosophie.png)](http://gophilosophie.com)
This gem is maintained partially during my open source time at [philosophie](http://gophilosophie.com).