paratrooper 1.1.3 → 1.2.0
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/Gemfile.lock +2 -2
- data/README.md +6 -1
- data/lib/paratrooper/deploy.rb +81 -14
- data/lib/paratrooper/notifier.rb +17 -0
- data/lib/paratrooper/notifiers/airbrake_notifier.rb +11 -0
- data/lib/paratrooper/notifiers/new_relic_notifier.rb.rb +32 -0
- data/lib/paratrooper/notifiers/screen_notifier.rb +67 -0
- data/lib/paratrooper/version.rb +1 -1
- data/spec/paratrooper/deploy_spec.rb +21 -41
- data/spec/paratrooper/notifier_spec.rb +12 -0
- data/spec/paratrooper/{default_formatter_spec.rb → notifiers/screen_notifier_spec.rb} +3 -2
- metadata +10 -5
- data/lib/paratrooper/default_formatter.rb +0 -19
data/Gemfile.lock
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
PATH
|
2
2
|
remote: .
|
3
3
|
specs:
|
4
|
-
paratrooper (
|
4
|
+
paratrooper (1.1.3)
|
5
5
|
heroku-api (~> 0.3)
|
6
6
|
netrc (~> 0.7)
|
7
7
|
|
@@ -11,7 +11,7 @@ GEM
|
|
11
11
|
coderay (1.0.8)
|
12
12
|
diff-lcs (1.1.3)
|
13
13
|
excon (0.16.10)
|
14
|
-
heroku-api (0.3.
|
14
|
+
heroku-api (0.3.8)
|
15
15
|
excon (~> 0.16.10)
|
16
16
|
method_source (0.8.1)
|
17
17
|
netrc (0.7.7)
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+

|
2
2
|
|
3
3
|
[](http://badge.fury.io/rb/paratrooper)
|
4
4
|
[](https://travis-ci.org/mattpolito/paratrooper)
|
@@ -175,6 +175,11 @@ end
|
|
175
175
|
4. Push to the branch (`git push origin my-new-feature`)
|
176
176
|
5. Create new Pull Request
|
177
177
|
|
178
|
+
## Thanks
|
179
|
+
|
180
|
+
* [Rye Mason][] for the fantastic heading image
|
181
|
+
|
178
182
|
[Heroku]: http://heroku.com
|
179
183
|
[Heroku Toolbelt]: http://toolbelt.heroku.com
|
180
184
|
[New Relic]: http://newrelic.com
|
185
|
+
[Rye Mason]: https://github.com/ryenotbread
|
data/lib/paratrooper/deploy.rb
CHANGED
@@ -1,62 +1,119 @@
|
|
1
1
|
require 'paratrooper/heroku_wrapper'
|
2
|
-
require 'paratrooper/default_formatter'
|
3
2
|
require 'paratrooper/system_caller'
|
3
|
+
require 'paratrooper/notifiers/screen_notifier'
|
4
4
|
|
5
5
|
module Paratrooper
|
6
|
+
|
7
|
+
# Public: Entry point into the library.
|
8
|
+
#
|
6
9
|
class Deploy
|
7
|
-
attr_reader :app_name, :
|
10
|
+
attr_reader :app_name, :notifiers, :system_caller, :heroku, :tag_name,
|
8
11
|
:match_tag
|
9
12
|
|
13
|
+
# Public: Initializes a Deploy
|
14
|
+
#
|
15
|
+
# app_name - A String naming the Heroku application to be interacted with.
|
16
|
+
# options - The Hash options is used to provide additional functionality.
|
17
|
+
# :notifiers - Array of objects responsible for handling
|
18
|
+
# notifications (optional).
|
19
|
+
# :heroku - Object wrapper around heroku-api (optional).
|
20
|
+
# :tag - String name to be used as a git reference
|
21
|
+
# point (optional).
|
22
|
+
# :match_tag_to - String name of git reference point to match
|
23
|
+
# :tag to (optional).
|
24
|
+
# :system_caller - Object responsible for calling system
|
25
|
+
# commands (optional).
|
10
26
|
def initialize(app_name, options = {})
|
11
27
|
@app_name = app_name
|
12
|
-
@
|
28
|
+
@notifiers = options[:notifiers] || [Notifiers::ScreenNotifier.new]
|
13
29
|
@heroku = options[:heroku] || HerokuWrapper.new(app_name, options)
|
14
30
|
@tag_name = options[:tag]
|
15
31
|
@match_tag = options[:match_tag_to] || 'master'
|
16
32
|
@system_caller = options[:system_caller] || SystemCaller.new
|
17
33
|
end
|
18
34
|
|
35
|
+
def setup
|
36
|
+
notify(:setup)
|
37
|
+
end
|
38
|
+
|
39
|
+
def teardown
|
40
|
+
notify(:teardown)
|
41
|
+
end
|
42
|
+
|
43
|
+
def notify(step, options={})
|
44
|
+
notifiers.each do |notifier|
|
45
|
+
notifier.notify(step, default_payload.merge(options))
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
# Public: Activates Heroku maintenance mode.
|
50
|
+
#
|
19
51
|
def activate_maintenance_mode
|
20
|
-
|
52
|
+
notify(:activate_maintenance_mode)
|
21
53
|
heroku.app_maintenance_on
|
22
54
|
end
|
23
55
|
|
56
|
+
# Public: Deactivates Heroku maintenance mode.
|
57
|
+
#
|
24
58
|
def deactivate_maintenance_mode
|
25
|
-
|
59
|
+
notify(:deactivate_maintenance_mode)
|
26
60
|
heroku.app_maintenance_off
|
27
61
|
end
|
28
62
|
|
63
|
+
# Public: Creates a git tag and pushes it to repository.
|
64
|
+
#
|
29
65
|
def update_repo_tag
|
30
66
|
unless tag_name.nil? || tag_name.empty?
|
31
|
-
|
67
|
+
notify(:update_repo_tag)
|
32
68
|
system_call "git tag #{tag_name} #{match_tag} -f"
|
33
69
|
system_call "git push -f origin #{tag_name}"
|
34
70
|
end
|
35
71
|
end
|
36
72
|
|
73
|
+
# Public: Pushes repository to Heroku.
|
74
|
+
#
|
37
75
|
def push_repo
|
38
76
|
reference_point = tag_name || 'master'
|
39
|
-
|
77
|
+
notify(:push_repo, reference_point: reference_point)
|
40
78
|
system_call "git push -f #{git_remote} #{reference_point}:master"
|
41
79
|
end
|
42
80
|
|
81
|
+
# Public: Runs rails database migrations on your application.
|
82
|
+
#
|
43
83
|
def run_migrations
|
44
|
-
|
84
|
+
notify(:run_migrations)
|
45
85
|
system_call "heroku run rake db:migrate --app #{app_name}"
|
46
86
|
end
|
47
87
|
|
88
|
+
# Public: Restarts application on Heroku.
|
89
|
+
#
|
48
90
|
def app_restart
|
49
|
-
|
91
|
+
notify(:app_restart)
|
50
92
|
heroku.app_restart
|
51
93
|
end
|
52
94
|
|
95
|
+
# Public: cURL for application URL to start your Heroku dyno.
|
96
|
+
#
|
53
97
|
def warm_instance(wait_time = 3)
|
54
98
|
sleep wait_time
|
55
|
-
|
99
|
+
notify(:warm_instance)
|
56
100
|
system_call "curl -Il http://#{app_url}"
|
57
101
|
end
|
58
102
|
|
103
|
+
# Public: Execute common deploy steps.
|
104
|
+
#
|
105
|
+
# Default deploy consists of:
|
106
|
+
# * Activating maintenance page
|
107
|
+
# * Updating repository tag
|
108
|
+
# * Pushing repository to Heroku
|
109
|
+
# * Running database migrations
|
110
|
+
# * Restarting application on Heroku
|
111
|
+
# * Deactivating maintenance page
|
112
|
+
# * cURL'ing application URL to warm Heroku dyno
|
113
|
+
#
|
114
|
+
# Alias: #deploy
|
59
115
|
def default_deploy
|
116
|
+
setup
|
60
117
|
activate_maintenance_mode
|
61
118
|
update_repo_tag
|
62
119
|
push_repo
|
@@ -64,6 +121,7 @@ module Paratrooper
|
|
64
121
|
app_restart
|
65
122
|
deactivate_maintenance_mode
|
66
123
|
warm_instance
|
124
|
+
teardown
|
67
125
|
end
|
68
126
|
alias_method :deploy, :default_deploy
|
69
127
|
|
@@ -72,14 +130,23 @@ module Paratrooper
|
|
72
130
|
heroku.app_url
|
73
131
|
end
|
74
132
|
|
75
|
-
def
|
76
|
-
|
133
|
+
def default_payload
|
134
|
+
{
|
135
|
+
app_name: app_name,
|
136
|
+
app_url: app_url,
|
137
|
+
git_remote: git_remote,
|
138
|
+
tag_name: tag_name,
|
139
|
+
match_tag: match_tag
|
140
|
+
}
|
77
141
|
end
|
78
142
|
|
79
|
-
def
|
80
|
-
|
143
|
+
def git_remote
|
144
|
+
"git@heroku.com:#{app_name}.git"
|
81
145
|
end
|
82
146
|
|
147
|
+
# Internal: Calls commands meant to go to system
|
148
|
+
#
|
149
|
+
# call - String version of system command
|
83
150
|
def system_call(call)
|
84
151
|
system_caller.execute(call)
|
85
152
|
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Paratrooper
|
2
|
+
class Notifier
|
3
|
+
def notify(step_name, options = {})
|
4
|
+
self.send(step_name, options)
|
5
|
+
end
|
6
|
+
|
7
|
+
def activate_maintenance_mode(options = {}); end
|
8
|
+
def deactivate_maintenance_mode(options = {}); end
|
9
|
+
def update_repo_tag(options = {}); end
|
10
|
+
def push_repo(options = {}); end
|
11
|
+
def run_migrations(options = {}); end
|
12
|
+
def app_restart(options = {}); end
|
13
|
+
def warm_instance(options = {}); end
|
14
|
+
def setup(options = {}); end
|
15
|
+
def teardown(options = {}); end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'paratrooper/notifier'
|
2
|
+
|
3
|
+
module Paratrooper
|
4
|
+
module Notifiers
|
5
|
+
|
6
|
+
# Public: Sends notification to NewRelic to stop monitoring while deploy is
|
7
|
+
# happening
|
8
|
+
#
|
9
|
+
class NewRelicNotifier < Notifier
|
10
|
+
attr_reader :account_id, :api_key, :application_id
|
11
|
+
|
12
|
+
# Public: Initializes NewRelicNotifier
|
13
|
+
#
|
14
|
+
# api_key - String api key from NewRelic
|
15
|
+
# account_id - String NewRelic account id
|
16
|
+
# application_id - String NewRelic id of application
|
17
|
+
def initialize(api_key, account_id, application_id)
|
18
|
+
@api_key = api_key
|
19
|
+
@account_id = account_id
|
20
|
+
@application_id = application_id
|
21
|
+
end
|
22
|
+
|
23
|
+
def setup
|
24
|
+
%x[curl https://heroku.newrelic.com/accounts/#{account_id}/applications/#{application_id}/ping_targets/disable -X POST -H "X-Api-Key: #{api_key}"]
|
25
|
+
end
|
26
|
+
|
27
|
+
def teardown
|
28
|
+
%x[curl https://heroku.newrelic.com/accounts/#{account_id}/applications/#{application_id}/ping_targets/enable -X POST -H "X-Api-Key: #{api_key}"]
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,67 @@
|
|
1
|
+
require 'paratrooper/notifier'
|
2
|
+
|
3
|
+
module Paratrooper
|
4
|
+
module Notifiers
|
5
|
+
|
6
|
+
# Public: Default notifier for outputting messages to screen.
|
7
|
+
#
|
8
|
+
class ScreenNotifier < Notifier
|
9
|
+
attr_reader :output
|
10
|
+
|
11
|
+
# Public: Initializes ScreenNotifier
|
12
|
+
#
|
13
|
+
# output - IO object (default: STDOUT)
|
14
|
+
def initialize(output = STDOUT)
|
15
|
+
@output = output
|
16
|
+
end
|
17
|
+
|
18
|
+
# Public: Displays message with decoration
|
19
|
+
#
|
20
|
+
# message - String message to be displayed
|
21
|
+
#
|
22
|
+
# Examples
|
23
|
+
#
|
24
|
+
# display("Excellent Message")
|
25
|
+
# # =>
|
26
|
+
# # => ==========================================================================
|
27
|
+
# # => >> Excellent Message
|
28
|
+
# # => ==========================================================================
|
29
|
+
# # =>
|
30
|
+
def display(message)
|
31
|
+
output.puts
|
32
|
+
output.puts "=" * 80
|
33
|
+
output.puts ">> #{message}"
|
34
|
+
output.puts "=" * 80
|
35
|
+
output.puts
|
36
|
+
end
|
37
|
+
|
38
|
+
def activate_maintenance_mode(options = {})
|
39
|
+
display("Activating Maintenance Mode")
|
40
|
+
end
|
41
|
+
|
42
|
+
def deactivate_maintenance_mode(options = {})
|
43
|
+
display("Deactivating Maintenance Mode")
|
44
|
+
end
|
45
|
+
|
46
|
+
def update_repo_tag(options = {})
|
47
|
+
display("Updating Repo Tag: #{options[:tag_name]}")
|
48
|
+
end
|
49
|
+
|
50
|
+
def push_repo(options = {})
|
51
|
+
display("Pushing #{options[:reference_point]} to Heroku")
|
52
|
+
end
|
53
|
+
|
54
|
+
def run_migrations(options = {})
|
55
|
+
display("Running database migrations")
|
56
|
+
end
|
57
|
+
|
58
|
+
def app_restart(options = {})
|
59
|
+
display("Restarting application")
|
60
|
+
end
|
61
|
+
|
62
|
+
def warm_instance(options = {})
|
63
|
+
display("Accessing #{options[:app_url]} to warm up your application")
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
data/lib/paratrooper/version.rb
CHANGED
@@ -9,7 +9,7 @@ describe Paratrooper::Deploy do
|
|
9
9
|
let(:default_options) do
|
10
10
|
{
|
11
11
|
heroku: heroku,
|
12
|
-
|
12
|
+
notifiers: [],
|
13
13
|
system_caller: system_caller
|
14
14
|
}
|
15
15
|
end
|
@@ -22,7 +22,6 @@ describe Paratrooper::Deploy do
|
|
22
22
|
app_maintenance_off: true,
|
23
23
|
)
|
24
24
|
end
|
25
|
-
let(:formatter) { double(:formatter, puts: '') }
|
26
25
|
let(:system_caller) { double(:system_caller) }
|
27
26
|
let(:domain_response) do
|
28
27
|
double(:domain_response, body: [{'domain' => 'application_url'}])
|
@@ -46,26 +45,19 @@ describe Paratrooper::Deploy do
|
|
46
45
|
end
|
47
46
|
end
|
48
47
|
|
49
|
-
context "accepts :
|
50
|
-
let(:options) { {
|
51
|
-
let(:
|
48
|
+
context "accepts :notifiers" do
|
49
|
+
let(:options) { { notifiers: [notifiers] } }
|
50
|
+
let(:notifiers) { double(:notifier) }
|
52
51
|
|
53
|
-
it "and responds to #
|
54
|
-
expect(deployer.
|
52
|
+
it "and responds to #notifiers" do
|
53
|
+
expect(deployer.notifiers).to eq([notifiers])
|
55
54
|
end
|
56
55
|
end
|
57
56
|
end
|
58
57
|
|
59
58
|
describe "#activate_maintenance_mode" do
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
before do
|
64
|
-
formatter.stub(:display)
|
65
|
-
end
|
66
|
-
|
67
|
-
it "displays message" do
|
68
|
-
formatter.should_receive(:display).with('Activating Maintenance Mode')
|
59
|
+
it 'sends notification' do
|
60
|
+
deployer.should_receive(:notify).with(:activate_maintenance_mode).once
|
69
61
|
deployer.activate_maintenance_mode
|
70
62
|
end
|
71
63
|
|
@@ -76,12 +68,8 @@ describe Paratrooper::Deploy do
|
|
76
68
|
end
|
77
69
|
|
78
70
|
describe "#deactivate_maintenance_mode" do
|
79
|
-
|
80
|
-
|
81
|
-
end
|
82
|
-
|
83
|
-
it "displays message" do
|
84
|
-
formatter.should_receive(:display).with('Deactivating Maintenance Mode')
|
71
|
+
it 'sends notification' do
|
72
|
+
deployer.should_receive(:notify).with(:deactivate_maintenance_mode).once
|
85
73
|
deployer.deactivate_maintenance_mode
|
86
74
|
end
|
87
75
|
|
@@ -97,11 +85,10 @@ describe Paratrooper::Deploy do
|
|
97
85
|
|
98
86
|
before do
|
99
87
|
system_caller.stub(:execute)
|
100
|
-
formatter.stub(:display)
|
101
88
|
end
|
102
89
|
|
103
|
-
it '
|
104
|
-
|
90
|
+
it 'sends notification' do
|
91
|
+
deployer.should_receive(:notify).with(:update_repo_tag).once
|
105
92
|
deployer.update_repo_tag
|
106
93
|
end
|
107
94
|
|
@@ -142,11 +129,11 @@ describe Paratrooper::Deploy do
|
|
142
129
|
describe "#push_repo" do
|
143
130
|
before do
|
144
131
|
system_caller.stub(:execute)
|
145
|
-
formatter.stub(:display)
|
146
132
|
end
|
147
133
|
|
148
|
-
it '
|
149
|
-
|
134
|
+
it 'sends notification' do
|
135
|
+
deployer.should_receive(:notify)
|
136
|
+
.with(:push_repo, reference_point: 'master').once
|
150
137
|
deployer.push_repo
|
151
138
|
end
|
152
139
|
|
@@ -160,11 +147,10 @@ describe Paratrooper::Deploy do
|
|
160
147
|
describe "#run_migrations" do
|
161
148
|
before do
|
162
149
|
system_caller.stub(:execute)
|
163
|
-
formatter.stub(:display)
|
164
150
|
end
|
165
151
|
|
166
|
-
it '
|
167
|
-
|
152
|
+
it 'sends notification' do
|
153
|
+
deployer.should_receive(:notify).with(:run_migrations).once
|
168
154
|
deployer.run_migrations
|
169
155
|
end
|
170
156
|
|
@@ -176,12 +162,8 @@ describe Paratrooper::Deploy do
|
|
176
162
|
end
|
177
163
|
|
178
164
|
describe "#app_restart" do
|
179
|
-
|
180
|
-
|
181
|
-
end
|
182
|
-
|
183
|
-
it 'displays message' do
|
184
|
-
formatter.should_receive(:display).with('Restarting application')
|
165
|
+
it 'sends notification' do
|
166
|
+
deployer.should_receive(:notify).with(:app_restart).once
|
185
167
|
deployer.app_restart
|
186
168
|
end
|
187
169
|
|
@@ -194,12 +176,10 @@ describe Paratrooper::Deploy do
|
|
194
176
|
describe "#warm_instance" do
|
195
177
|
before do
|
196
178
|
system_caller.stub(:execute)
|
197
|
-
formatter.stub(:display)
|
198
179
|
end
|
199
180
|
|
200
|
-
it '
|
201
|
-
|
202
|
-
formatter.should_receive(:display).with(expected_notice)
|
181
|
+
it 'sends notification' do
|
182
|
+
deployer.should_receive(:notify).with(:warm_instance).once
|
203
183
|
deployer.warm_instance(0)
|
204
184
|
end
|
205
185
|
|
@@ -0,0 +1,12 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'paratrooper/notifier'
|
3
|
+
|
4
|
+
describe Paratrooper::Notifier do
|
5
|
+
let(:notifier) { described_class.new }
|
6
|
+
describe '#notify' do
|
7
|
+
it 'sends correct method options' do
|
8
|
+
notifier.should_receive(:update_repo_tag).with(test: 'blah')
|
9
|
+
notifier.notify(:update_repo_tag, test: 'blah')
|
10
|
+
end
|
11
|
+
end
|
12
|
+
end
|
@@ -1,7 +1,8 @@
|
|
1
1
|
require 'spec_helper'
|
2
|
-
require 'paratrooper/
|
2
|
+
require 'paratrooper/notifiers/screen_notifier'
|
3
|
+
require 'stringio'
|
3
4
|
|
4
|
-
describe Paratrooper::
|
5
|
+
describe Paratrooper::Notifiers::ScreenNotifier do
|
5
6
|
let(:formatter) { described_class.new(output_stub) }
|
6
7
|
let(:output_stub) { StringIO.new }
|
7
8
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: paratrooper
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.2.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-03-14 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: rake
|
@@ -107,18 +107,22 @@ files:
|
|
107
107
|
- README.md
|
108
108
|
- Rakefile
|
109
109
|
- lib/paratrooper.rb
|
110
|
-
- lib/paratrooper/default_formatter.rb
|
111
110
|
- lib/paratrooper/deploy.rb
|
112
111
|
- lib/paratrooper/heroku_wrapper.rb
|
113
112
|
- lib/paratrooper/local_api_key_extractor.rb
|
113
|
+
- lib/paratrooper/notifier.rb
|
114
|
+
- lib/paratrooper/notifiers/airbrake_notifier.rb
|
115
|
+
- lib/paratrooper/notifiers/new_relic_notifier.rb.rb
|
116
|
+
- lib/paratrooper/notifiers/screen_notifier.rb
|
114
117
|
- lib/paratrooper/system_caller.rb
|
115
118
|
- lib/paratrooper/version.rb
|
116
119
|
- paratrooper.gemspec
|
117
120
|
- spec/fixtures/netrc
|
118
|
-
- spec/paratrooper/default_formatter_spec.rb
|
119
121
|
- spec/paratrooper/deploy_spec.rb
|
120
122
|
- spec/paratrooper/heroku_wrapper_spec.rb
|
121
123
|
- spec/paratrooper/local_api_key_extractor_spec.rb
|
124
|
+
- spec/paratrooper/notifier_spec.rb
|
125
|
+
- spec/paratrooper/notifiers/screen_notifier_spec.rb
|
122
126
|
- spec/spec_helper.rb
|
123
127
|
homepage: http://github.com/mattpolito/paratrooper
|
124
128
|
licenses: []
|
@@ -146,9 +150,10 @@ specification_version: 3
|
|
146
150
|
summary: Library to create task for deployment to Heroku
|
147
151
|
test_files:
|
148
152
|
- spec/fixtures/netrc
|
149
|
-
- spec/paratrooper/default_formatter_spec.rb
|
150
153
|
- spec/paratrooper/deploy_spec.rb
|
151
154
|
- spec/paratrooper/heroku_wrapper_spec.rb
|
152
155
|
- spec/paratrooper/local_api_key_extractor_spec.rb
|
156
|
+
- spec/paratrooper/notifier_spec.rb
|
157
|
+
- spec/paratrooper/notifiers/screen_notifier_spec.rb
|
153
158
|
- spec/spec_helper.rb
|
154
159
|
has_rdoc:
|
@@ -1,19 +0,0 @@
|
|
1
|
-
require 'stringio'
|
2
|
-
|
3
|
-
module Paratrooper
|
4
|
-
class DefaultFormatter
|
5
|
-
attr_reader :output
|
6
|
-
|
7
|
-
def initialize(output = STDOUT)
|
8
|
-
@output = output
|
9
|
-
end
|
10
|
-
|
11
|
-
def display(message)
|
12
|
-
output.puts
|
13
|
-
output.puts "=" * 80
|
14
|
-
output.puts ">> #{message}"
|
15
|
-
output.puts "=" * 80
|
16
|
-
output.puts
|
17
|
-
end
|
18
|
-
end
|
19
|
-
end
|