chaperone 0.0.1

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.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ coverage
7
+ Gemfile.lock
8
+ InstalledFiles
9
+ _yardoc
10
+ coverage
11
+ doc/
12
+ lib/bundler/man
13
+ pkg
14
+ rdoc
15
+ spec/reports
16
+ test/tmp
17
+ test/version_tmp
18
+ tmp
data/.rspec ADDED
@@ -0,0 +1,2 @@
1
+ --color
2
+ --format progress
data/Gemfile ADDED
@@ -0,0 +1,5 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in chaperone.gemspec
4
+ gem 'rake'
5
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Matthew Werner
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,119 @@
1
+ # Chaperone
2
+
3
+ Getting as close to automated as we can.
4
+
5
+ Sometimes there are processes that just can't be automated.
6
+ Chaperone is a CLI for watching over someone as they go
7
+ through a process that has human-driven components.
8
+ These are processes such as deployment or software
9
+ installation. The gem does not actually execute the
10
+ commands, but rather leaves it to the person following
11
+ the guide to do so.
12
+
13
+ ## Automation > Chaperone
14
+
15
+ Bear in mind that you should prefer automation to chaperone
16
+ whenever possible. If you find the steps you're writing for
17
+ chaperone could be safely executed within a script, chaperone
18
+ is probably not the appropriate place for that process.
19
+
20
+ ## Usage
21
+
22
+ Chaperone includes a `Guide` class which you inherit from. This
23
+ guide provides a DSL that allows you to easily produce multi-step
24
+ functionality with common informational displays as the user progresses
25
+ through a given guide.
26
+
27
+ After you have defined your guide, you simply call `MyGuide.new.start` to begin
28
+
29
+ #### Providing reference info
30
+
31
+ A defined `URL` constant is displayed at the start of the guide
32
+ which points to a more thorough explanation of what's happening.
33
+ It's rare that a chaperone guide can give all the backstory needed,
34
+ so it's handy to let the guidee know where they can get more info.
35
+
36
+ #### Defining steps
37
+
38
+ The `STEPS` constant is an array of strings that defines the names
39
+ of the step methods and their order. Each step string must correspond
40
+ to a method on the class.
41
+
42
+ #### Initialization Options
43
+
44
+ `step` will let you specify the number of the step you want to start on.
45
+ Useful when you are continuing a previously exited guide.
46
+
47
+ `steps` lets you define the array of steps your guide will use. This list
48
+ is normally defined in the `STEPS` constant, but if you have a specific case
49
+ where you only want to run through a subset of steps, this is the best way to
50
+ accomplish that.
51
+
52
+ ## Prompt
53
+
54
+ Each step is rendered using a `prompt` block. The prompt accepts a few
55
+ types of calls that vary depending on what type of information you want
56
+ to display on the screen. These calls vary the visual presentation of
57
+ the content as well as it's order
58
+
59
+ #### Options
60
+
61
+ - `padding` - Specifies if there should be any extra spaces in the prompt (Boolean, default: true)
62
+ - `question` - Specifies if there should be a blocking actions prompt (Boolean, default: true)
63
+
64
+ #### Prompt DSL
65
+
66
+ - `title` A brief message explaining this step
67
+ - `needs` The requirement to continue
68
+ - `current` What the guidee is currently using related to the needs
69
+ - `notes` A plain block of text
70
+ - `code` Highlighted block of exact syntax that they can copy and paste
71
+ - `question` The text displayed on the action prompt
72
+
73
+ #### Actions
74
+
75
+ Each prompt is blocked by a command line input:
76
+
77
+ [c]ontinue, e[x]it, [r]etry
78
+
79
+ If you passed a question into the prompt block, you'll see it before the actions:
80
+
81
+ Ready to continue? [c]ontinue, e[x]it, [r]etry
82
+
83
+ The default is to continue, retry is handy for things like git branch checks which
84
+ a user can update in another terminal and confirm the change is recognized.
85
+
86
+ ## Example
87
+
88
+ version = CommandLine.new('ruby', '-v').run.gsub("\n",'')
89
+ prompt do |p|
90
+ p.title = 'Ruby Version Check'
91
+ p.needs = 'ruby 1.9.3[Any Patch Level]'
92
+ p.notes = '1.8.7 is not supported, sorry.'
93
+ p.current = version
94
+ p.code = 'rvm use 1.9.3'
95
+ p.question = 'Using the right version?'
96
+ end
97
+
98
+ To see a full guide example, see the [`deploy.rb`](https://github.com/mwerner/chaperone/blob/master/examples/deploy.rb) file in the repository's `examples` dir
99
+
100
+ ## Libraries
101
+
102
+ The `Guide` class includes the [cocaine](https://github.com/thoughtbot/cocaine)
103
+ and [highline](https://github.com/JEG2/highline) libraries. Go nuts.
104
+
105
+ ## Future
106
+
107
+ There are a few things I'm hoping to include as a part of this gem
108
+
109
+ - Delivering guide execution reports to a remote server
110
+ - Error reporting to catch failed guide execution in disparate locations
111
+ - A central source for guide distribution
112
+
113
+ ## Contributing
114
+
115
+ 1. Fork it
116
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
117
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
118
+ 4. Push to the branch (`git push origin my-new-feature`)
119
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/chaperone.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # -*- encoding: utf-8 -*-
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'chaperone/version'
5
+
6
+ Gem::Specification.new do |gem|
7
+ gem.name = "chaperone"
8
+ gem.version = Chaperone::VERSION
9
+ gem.authors = ["Matthew Werner"]
10
+ gem.email = ["mwerner@zendesk.com"]
11
+ gem.description = %q{Guides you step by step through the things you can mess up}
12
+ gem.summary = %q{Guides you step by step through the things you can mess up}
13
+ gem.license = 'MIT'
14
+ gem.homepage = "https://github.com/mwerner/chaperone"
15
+
16
+ gem.files = `git ls-files`.split($/)
17
+ gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
18
+ gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
19
+ gem.require_paths = ["lib"]
20
+
21
+ gem.add_development_dependency 'rspec'
22
+ gem.add_development_dependency 'simplecov'
23
+ gem.add_development_dependency 'mocha'
24
+
25
+ gem.add_runtime_dependency 'thor'
26
+ gem.add_runtime_dependency 'cocaine'
27
+ gem.add_runtime_dependency 'activesupport'
28
+ gem.add_runtime_dependency 'highline'
29
+
30
+ end
@@ -0,0 +1,66 @@
1
+ require 'rubygems'
2
+ require 'chaperone'
3
+
4
+ class Deploy < Chaperone::Guide
5
+
6
+ URL = 'https://github.com/mwerner/chaperone'
7
+ STEPS = %w[
8
+ check_ruby_version
9
+ execute_capistrano
10
+ tag_release_version
11
+ notify_flowdock
12
+ ]
13
+
14
+ protected
15
+
16
+ def check_ruby_version
17
+ version = CommandLine.new('ruby', '-v').run.gsub("\n",'')
18
+
19
+ prompt do |p|
20
+ p.title = 'Ruby Version Check'
21
+ p.needs = 'ruby 1.9.3[Any Patch Level]'
22
+ p.current = version
23
+ p.code = 'rvm use 1.9.3'
24
+ end
25
+ end
26
+
27
+ def execute_capistrano
28
+ prompt do |p|
29
+ p.title = 'Run capistrano task'
30
+ p.code = 'bundle exec cap production deploy'
31
+ p.notes = %{
32
+ The script can be found in config/deploy/production.rb
33
+ }
34
+ end
35
+ end
36
+
37
+ def tag_release_version
38
+ latest = CommandLine.new('git describe --abbrev=0 --tags').run.gsub("\n",'') rescue 'Unable to determine'
39
+
40
+ prompt(question: false) do |p|
41
+ p.title = 'Tagging the release'
42
+ p.notes = %{
43
+ - This should be the next unreleased tag in the current Changelog.md
44
+ Latest Deployed Version: #{status(latest)}
45
+ }
46
+ end
47
+
48
+ version = ask(strong('The version youre deploying:')).to_s
49
+ prompt do |p|
50
+ p.code = %{
51
+ git tag -a #{version}
52
+ git push origin #{version}
53
+ }
54
+ end
55
+ end
56
+
57
+ def notify_flowdock
58
+ prompt do |p|
59
+ p.title = 'Notify flowdock chat'
60
+ p.code = '@all just deployed master to production'
61
+ end
62
+ end
63
+
64
+ end
65
+
66
+ Deploy.new.start
@@ -0,0 +1,88 @@
1
+ module Chaperone
2
+ class Guide
3
+ include Cocaine
4
+ include Output
5
+ include HighlineConfig
6
+
7
+ attr_accessor :steps, :current_step, :iteration, :url
8
+
9
+ STEPS = ['no_steps_defined']
10
+ URL = 'https://github.com/mwerner/chaperone'
11
+
12
+ def initialize(opts={})
13
+ @steps = opts[:steps] || self.class::STEPS
14
+ @url = self.class::URL
15
+ @iteration = 0
16
+ @current_step = opts[:step].to_i || 0
17
+ end
18
+
19
+ def start
20
+ welcome!
21
+
22
+ (0..steps.length-1).each do |step|
23
+ @iteration = step
24
+
25
+ if current_step > iteration
26
+ skip_step!
27
+ next
28
+ end
29
+
30
+ break unless execute_step(steps[iteration].to_sym)
31
+ complete_step!
32
+ end
33
+
34
+ complete!
35
+ end
36
+
37
+ protected
38
+
39
+ def no_steps_defined
40
+ prompt(question: false) do |p|
41
+ p.title = "No Steps are defined for #{self.class.to_s}"
42
+ end
43
+ end
44
+
45
+ def execute_step(step, proceed=true)
46
+ unless self.respond_to?(step)
47
+ output "WARNING: #{step} is not defined"
48
+ return
49
+ end
50
+
51
+ loop do
52
+ case send(step)
53
+ when 'r'; next
54
+ when 'x'; proceed = false
55
+ end
56
+
57
+ break
58
+ end
59
+
60
+ proceed
61
+ end
62
+
63
+ private
64
+
65
+ def prompt(opts={}, &config)
66
+ Prompt.new(opts, &config).render
67
+ end
68
+
69
+ def welcome!
70
+ output '==> Begin'
71
+ output "==> Reference: #{url}" if url
72
+ end
73
+
74
+ def complete_step!
75
+ @current_step += 1
76
+ output notice("==> [#{iteration}] Completed Step")
77
+ end
78
+
79
+ def skip_step!
80
+ output notice("==> Skipping [#{iteration}] #{steps[iteration].gsub('_',' ')}")
81
+ end
82
+
83
+ def complete!
84
+ output "==> Finished"
85
+ end
86
+
87
+ end
88
+ end
@@ -0,0 +1,44 @@
1
+ module Chaperone
2
+ class Prompt
3
+ include Output
4
+ include HighlineConfig
5
+
6
+ attr_accessor :title, :notes, :needs, :current, :code, :question, :config
7
+
8
+ def initialize(config={})
9
+ @config = {padding: true, question: true}.merge(config)
10
+ yield(self) if block_given?
11
+ end
12
+
13
+ def render
14
+ output body
15
+ return unless has_question?
16
+ ask strong("#{question} [c]ontinue, [r]etry, e[x]it".squeeze(' '))
17
+ end
18
+
19
+ def lines
20
+ sections = []
21
+ sections << action( title ) if title
22
+ sections << notes if notes
23
+ sections << "#{requirement('Required:')} #{needs}" if needs
24
+ sections << "#{status('Current:')} #{current}" if current
25
+ sections << direction("\n #{code}") if code
26
+ sections
27
+ end
28
+
29
+ def body
30
+ text = lines.join("\n ")
31
+ text = "\n#{text}\n\n" if has_padding?
32
+ text.squeeze(' ')
33
+ end
34
+
35
+ def has_padding?
36
+ !!config[:padding]
37
+ end
38
+
39
+ def has_question?
40
+ !!config[:question]
41
+ end
42
+
43
+ end
44
+ end
@@ -0,0 +1,3 @@
1
+ module Chaperone
2
+ VERSION = "0.0.1"
3
+ end
data/lib/chaperone.rb ADDED
@@ -0,0 +1,38 @@
1
+ require 'cocaine'
2
+ require 'chaperone/version'
3
+ require 'highline/import'
4
+
5
+ module HighlineConfig
6
+ COLORS = [:status, :notice, :action, :error, :requirement, :strong, :direction]
7
+
8
+ HighLine.color_scheme = HighLine::ColorScheme.new do |scheme|
9
+ scheme[:action] = [ :bold, :yellow, :on_black ]
10
+ scheme[:notice] = [ :green ]
11
+ scheme[:status] = [ :bold, :blue ]
12
+ scheme[:error] = [ :red ]
13
+ scheme[:direction] = [ :bold, :black, :on_gray ]
14
+ scheme[:strong] = [ :gray, :bold ]
15
+ scheme[:requirement] = [ :bold, :cyan ]
16
+ end
17
+
18
+ COLORS.each do |hue|
19
+ define_method(hue.to_sym) do |message|
20
+ "<%= color('#{message}', :#{hue})%>"
21
+ end
22
+ end
23
+ end
24
+
25
+ module Output
26
+ def output(message)
27
+ say(message) unless ENV['env'] == 'test'
28
+ end
29
+ end
30
+
31
+ module Chaperone
32
+ autoload :Prompt, 'chaperone/prompt'
33
+ autoload :Guide, 'chaperone/guide'
34
+
35
+ module Guides
36
+ autoload :Brew, 'chaperone/guides/brew'
37
+ end
38
+ end
@@ -0,0 +1,54 @@
1
+ require 'spec_helper'
2
+
3
+ describe Guide do
4
+
5
+ context '#initialize' do
6
+ it 'defaults step to 0' do
7
+ Guide.new.current_step.should eq(0)
8
+ end
9
+
10
+ it 'accepts step param' do
11
+ guide = Guide.new(step: 2)
12
+ guide.current_step.should eq(2)
13
+ guide.start
14
+ end
15
+ end
16
+
17
+ context '#start' do
18
+ let(:guide){Guide.new}
19
+
20
+ it 'calls welcome and complete' do
21
+ Guide.any_instance.expects(:welcome!).once
22
+ Guide.any_instance.expects(:complete!).once
23
+ guide.start
24
+ end
25
+
26
+ it 'runs no_steps_defined when no steps are defined' do
27
+ Guide.any_instance.expects(:no_steps_defined).once
28
+ guide.start
29
+ end
30
+
31
+ it 'provides the chaperone url if none is defined' do
32
+ guide.url.should eq(Guide::URL)
33
+ end
34
+
35
+ context 'with steps' do
36
+ let(:guide){Guide.new(steps: ['a','b'])}
37
+ let(:stubbed_guide){
38
+ guide.stubs(:a)
39
+ guide.stubs(:b)
40
+ }
41
+
42
+ it 'warns on an undefined step' do
43
+ expect{ guide.start }.to_not raise_error
44
+ end
45
+
46
+ it 'runs each step' do
47
+ stubbed_guide.expects(:a).once
48
+ stubbed_guide.expects(:b).once
49
+ guide.start
50
+ end
51
+ end
52
+
53
+ end
54
+ end
@@ -0,0 +1,46 @@
1
+ require 'spec_helper'
2
+
3
+ describe Guide do
4
+ let(:attrs){%w(title notes needs current code)}
5
+ context '#initialize' do
6
+ it 'defaults config' do
7
+ Prompt.new.config.should eq({padding: true, question: true})
8
+ end
9
+
10
+ it 'allows config' do
11
+ params = {padding: false, question: false}
12
+ Prompt.new(params).config.should eq(params)
13
+ end
14
+
15
+ it 'executes a block' do
16
+ prompt = Prompt.new do |p|
17
+ attrs.each do |attr|
18
+ p.send("#{attr.to_sym}=", "My #{attr}")
19
+ end
20
+ end
21
+ attrs.each do |attr|
22
+ prompt.send(attr.to_sym).should eq("My #{attr}")
23
+ end
24
+ end
25
+ end
26
+
27
+ context '#lines' do
28
+ it 'returns an array' do
29
+ prompt = Prompt.new{|p| p.title = 'My title'}
30
+ prompt.lines.should be_a_kind_of(Array)
31
+ end
32
+
33
+ it 'accepts a dsl' do
34
+ prompt = Prompt.new do |p|
35
+ attrs.each do |attr|
36
+ p.send("#{attr.to_sym}=", "My #{attr}")
37
+ end
38
+ end
39
+
40
+ prompt.lines.each_with_index do |line, i|
41
+ line.should include("My #{attrs[i]}")
42
+ end
43
+ end
44
+ end
45
+
46
+ end
@@ -0,0 +1,17 @@
1
+ ENV['env'] = 'test'
2
+
3
+ require 'simplecov'
4
+ SimpleCov.start
5
+
6
+ require 'chaperone'
7
+ require 'mocha/api'
8
+
9
+ RSpec.configure do |config|
10
+ include Mocha::API
11
+ include Chaperone
12
+
13
+ config.treat_symbols_as_metadata_keys_with_true_values = true
14
+ config.run_all_when_everything_filtered = true
15
+ config.filter_run :focus
16
+ config.order = 'random'
17
+ end
metadata ADDED
@@ -0,0 +1,182 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: chaperone
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Matthew Werner
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-04-02 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rspec
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: simplecov
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :development
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: mocha
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :development
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: thor
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: cocaine
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ! '>='
84
+ - !ruby/object:Gem::Version
85
+ version: '0'
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ! '>='
92
+ - !ruby/object:Gem::Version
93
+ version: '0'
94
+ - !ruby/object:Gem::Dependency
95
+ name: activesupport
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ! '>='
100
+ - !ruby/object:Gem::Version
101
+ version: '0'
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ! '>='
108
+ - !ruby/object:Gem::Version
109
+ version: '0'
110
+ - !ruby/object:Gem::Dependency
111
+ name: highline
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :runtime
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ description: Guides you step by step through the things you can mess up
127
+ email:
128
+ - mwerner@zendesk.com
129
+ executables: []
130
+ extensions: []
131
+ extra_rdoc_files: []
132
+ files:
133
+ - .gitignore
134
+ - .rspec
135
+ - Gemfile
136
+ - LICENSE.txt
137
+ - README.md
138
+ - Rakefile
139
+ - chaperone.gemspec
140
+ - examples/deploy.rb
141
+ - lib/chaperone.rb
142
+ - lib/chaperone/guide.rb
143
+ - lib/chaperone/prompt.rb
144
+ - lib/chaperone/version.rb
145
+ - spec/models/guide_spec.rb
146
+ - spec/models/prompt_spec.rb
147
+ - spec/spec_helper.rb
148
+ homepage: https://github.com/mwerner/chaperone
149
+ licenses:
150
+ - MIT
151
+ post_install_message:
152
+ rdoc_options: []
153
+ require_paths:
154
+ - lib
155
+ required_ruby_version: !ruby/object:Gem::Requirement
156
+ none: false
157
+ requirements:
158
+ - - ! '>='
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ segments:
162
+ - 0
163
+ hash: -1260887828363319748
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ none: false
166
+ requirements:
167
+ - - ! '>='
168
+ - !ruby/object:Gem::Version
169
+ version: '0'
170
+ segments:
171
+ - 0
172
+ hash: -1260887828363319748
173
+ requirements: []
174
+ rubyforge_project:
175
+ rubygems_version: 1.8.24
176
+ signing_key:
177
+ specification_version: 3
178
+ summary: Guides you step by step through the things you can mess up
179
+ test_files:
180
+ - spec/models/guide_spec.rb
181
+ - spec/models/prompt_spec.rb
182
+ - spec/spec_helper.rb