paratrooper 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,18 +1,36 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- paratrooper (0.0.1)
4
+ paratrooper (0.0.2)
5
5
  heroku-api
6
6
 
7
7
  GEM
8
8
  remote: http://rubygems.org/
9
9
  specs:
10
- excon (0.16.10)
11
- heroku-api (0.3.7)
12
- excon (~> 0.16.10)
10
+ coderay (1.0.8)
11
+ diff-lcs (1.1.3)
12
+ excon (0.16.7)
13
+ heroku-api (0.3.6)
14
+ excon (~> 0.16.7)
15
+ method_source (0.8.1)
16
+ pry (0.9.10)
17
+ coderay (~> 1.0.5)
18
+ method_source (~> 0.8)
19
+ slop (~> 3.3.1)
20
+ rspec (2.12.0)
21
+ rspec-core (~> 2.12.0)
22
+ rspec-expectations (~> 2.12.0)
23
+ rspec-mocks (~> 2.12.0)
24
+ rspec-core (2.12.2)
25
+ rspec-expectations (2.12.1)
26
+ diff-lcs (~> 1.1.3)
27
+ rspec-mocks (2.12.1)
28
+ slop (3.3.3)
13
29
 
14
30
  PLATFORMS
15
31
  ruby
16
32
 
17
33
  DEPENDENCIES
18
34
  paratrooper!
35
+ pry
36
+ rspec (~> 2.12)
data/README.md CHANGED
@@ -18,16 +18,18 @@ Or install it yourself as:
18
18
 
19
19
  ## Usage
20
20
 
21
+ >> Note: Before getting started, ensure that `ENV['HEROKU_API_KEY']` is set. If you do not know your api key, you can `cat ~/.netrc`. Your api key will be listed as password in that file. This is necessary until reading your crendentials out of the `.netrc` file is implemented.
22
+
21
23
  Instantiate Paratrooper with the name of your heroku application
22
24
 
23
25
  ```ruby
24
- Paratrooper.new('amazing-app')
26
+ Paratrooper::Deploy.new('amazing-app')
25
27
  ```
26
28
 
27
29
  also you can provide a tag name for repository use
28
30
 
29
31
  ```ruby
30
- Paratrooper.new('amazing-app', tag: 'staging')
32
+ Paratrooper::Deploy.new('amazing-app', tag: 'staging')
31
33
  ```
32
34
 
33
35
  Then there are methods available to perform common tasks like creating git tags, running migrations, and warming your application instance.
@@ -54,14 +56,14 @@ require 'paratrooper'
54
56
  namespace :deploy do
55
57
  desc 'Deploy app in staging environment'
56
58
  task :staging do
57
- deployment = Paratrooper.new("amazing-staging-app", tag: 'staging')
59
+ deployment = Paratrooper::Deploy.new("amazing-staging-app", tag: 'staging')
58
60
 
59
61
  deployment.deploy
60
62
  end
61
63
 
62
64
  desc 'Deploy app in production environment'
63
65
  task :production do
64
- deployment = Paratrooper.new("amazing-production-app", tag: 'production')
66
+ deployment = Paratrooper::Deploy.new("amazing-production-app", tag: 'production')
65
67
 
66
68
  deployment.deploy
67
69
  end
@@ -1,6 +1,5 @@
1
- require "paratrooper/version"
1
+ require 'paratrooper/version'
2
2
  require 'paratrooper/deploy'
3
3
 
4
4
  module Paratrooper
5
-
6
5
  end
@@ -0,0 +1,11 @@
1
+ module Paratrooper
2
+ class DefaultFormatter
3
+ def puts(message)
4
+ puts
5
+ puts "=" * 80
6
+ puts ">> #{message}"
7
+ puts "=" * 80
8
+ puts
9
+ end
10
+ end
11
+ end
@@ -1,51 +1,55 @@
1
1
  require 'heroku-api'
2
+ require 'paratrooper/default_formatter'
2
3
 
3
4
  module Paratrooper
4
5
  class Deploy
5
- attr_reader :app_name, :heroku, :tag_name
6
+ attr_reader :app_name, :formatter, :system_caller, :heroku, :tag_name
6
7
 
7
8
  def initialize(app_name, options = {})
8
- @app_name = app_name
9
- @heroku = options[:heroku_auth] || Heroku::API.new(api_key: ENV['HEROKU_API_KEY'])
10
- @tag_name = options[:tag]
9
+ @app_name = app_name
10
+ @formatter = options[:formatter] || DefaultFormatter.new
11
+ @heroku = options[:heroku_auth] || Heroku::API.new(api_key: ENV['HEROKU_API_KEY'])
12
+ @tag_name = options[:tag]
13
+ @system_caller = options[:system_caller] || SystemCaller.new
11
14
  end
12
15
 
13
16
  def activate_maintenance_mode
14
17
  notify_screen("Activating Maintenance Mode")
15
- heroku.post_app_maintenance(app_name, '1')
18
+ app_maintenance_on
16
19
  end
17
20
 
18
21
  def deactivate_maintenance_mode
19
22
  notify_screen("Deactivating Maintenance Mode")
20
- heroku.post_app_maintenance(app_name, '0')
23
+ app_maintenance_off
21
24
  end
22
25
 
23
26
  def update_repo_tag
24
- unless tag_name.empty?
27
+ unless tag_name.nil? || tag_name.empty?
25
28
  notify_screen("Updating Repo Tag: #{tag_name}")
26
- system "git tag #{tag_name} -f"
27
- system "git push origin #{tag_name}"
29
+ system_call "git tag #{tag_name} -f"
30
+ system_call "git push origin #{tag_name}"
28
31
  end
29
32
  end
30
33
 
31
34
  def push_repo(branch = 'master')
32
35
  notify_screen("Pushing #{branch} to Heroku")
33
- system "git push -f #{git_remote} #{branch}"
36
+ system_call "git push -f #{git_remote} #{branch}"
34
37
  end
35
38
 
36
39
  def run_migrations
37
40
  notify_screen("Running database migrations")
38
- system "heroku run rake db:migrate --app #{app_name}"
41
+ system_call "heroku run rake db:migrate --app #{app_name}"
39
42
  end
40
43
 
41
44
  def app_restart
42
- heroku.post_ps_restart(app_name)
45
+ notify_screen("Restarting application")
46
+ _app_restart
43
47
  end
44
48
 
45
- def warm_instance(wait_time = 5)
49
+ def warm_instance(wait_time = 3)
46
50
  sleep wait_time
47
51
  notify_screen("Accessing #{app_url} to warm up your application")
48
- system "curl -Il http://#{app_url}"
52
+ system_call "curl -Il http://#{app_url}"
49
53
  end
50
54
 
51
55
  def default_deploy
@@ -60,20 +64,46 @@ module Paratrooper
60
64
  alias_method :deploy, :default_deploy
61
65
 
62
66
  private
63
- def git_remote
64
- "git@heroku.com:#{app_name}.git"
67
+ def _app_maintenance(flag)
68
+ heroku.post_app_maintenance(app_name, flag)
65
69
  end
66
70
 
67
- def app_url
71
+ def _app_restart
72
+ heroku.post_ps_restart(app_name)
73
+ end
74
+
75
+ def _app_domain_name
68
76
  heroku.get_domains(app_name).body.last['domain']
69
77
  end
70
78
 
79
+ def app_maintenance_off
80
+ _app_maintenance('0')
81
+ end
82
+
83
+ def app_maintenance_on
84
+ _app_maintenance('1')
85
+ end
86
+
87
+ def app_url
88
+ _app_domain_name
89
+ end
90
+
91
+ def git_remote
92
+ "git@heroku.com:#{app_name}.git"
93
+ end
94
+
71
95
  def notify_screen(message)
72
- puts
73
- puts "=" * 80
74
- puts ">> #{message}"
75
- puts "=" * 80
76
- puts
96
+ formatter.puts(message)
97
+ end
98
+
99
+ def system_call(call)
100
+ system_caller.execute(call)
101
+ end
102
+ end
103
+
104
+ SystemCaller = Struct.new(:call) do
105
+ def execute
106
+ system(call)
77
107
  end
78
108
  end
79
109
  end
@@ -0,0 +1,5 @@
1
+ SystemCaller = Struct.new(:call) do
2
+ def execute
3
+ system(call)
4
+ end
5
+ end
@@ -1,3 +1,3 @@
1
1
  module Paratrooper
2
- VERSION = "0.0.2"
2
+ VERSION = "0.0.3"
3
3
  end
@@ -17,5 +17,7 @@ Gem::Specification.new do |gem|
17
17
  gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
18
18
  gem.require_paths = ["lib"]
19
19
 
20
+ gem.add_development_dependency 'rspec', '~> 2.12'
21
+ gem.add_development_dependency 'pry'
20
22
  gem.add_dependency 'heroku-api'
21
23
  end
@@ -0,0 +1,182 @@
1
+ require 'spec_helper'
2
+ require 'paratrooper/deploy'
3
+
4
+ describe Paratrooper::Deploy do
5
+ let(:deployer) do
6
+ described_class.new(app_name, default_options.merge(options))
7
+ end
8
+ let(:app_name) { 'app' }
9
+ let(:default_options) do
10
+ {
11
+ heroku_auth: heroku,
12
+ formatter: formatter,
13
+ system_caller: system_caller
14
+ }
15
+ end
16
+ let(:options) { Hash.new }
17
+ let(:heroku) do
18
+ double(:heroku,
19
+ post_app_maintenance: true,
20
+ post_ps_restart: true,
21
+ get_domains: domain_response
22
+ )
23
+ end
24
+ let(:formatter) { double(:formatter, puts: '') }
25
+ let(:system_caller) { double(:system_caller) }
26
+ let(:domain_response) do
27
+ double(:domain_response, body: [{'domain' => 'application_url'}])
28
+ end
29
+
30
+ describe "options" do
31
+ context "accepts :tag" do
32
+ let(:options) { { tag: 'tag_name' } }
33
+
34
+ it "and responds to #tag_name" do
35
+ expect(deployer.tag_name).to eq('tag_name')
36
+ end
37
+ end
38
+
39
+ context "accepts :heroku_auth" do
40
+ let(:options) { { heroku_auth: heroku } }
41
+ let(:heroku) { double(:heroku) }
42
+
43
+ it "and responds to #heroku" do
44
+ expect(deployer.heroku).to eq(heroku)
45
+ end
46
+ end
47
+
48
+ context "accepts :formatter" do
49
+ let(:options) { { formatter: formatter } }
50
+ let(:formatter) { double(:formatter) }
51
+
52
+ it "and responds to #formatter" do
53
+ expect(deployer.formatter).to eq(formatter)
54
+ end
55
+ end
56
+ end
57
+
58
+ describe "#activate_maintenance_mode" do
59
+ let(:options) { { formatter: formatter } }
60
+ let(:formatter) { double(:formatter, puts: true) }
61
+
62
+ it "displays message" do
63
+ formatter.should_receive(:puts).with('Activating Maintenance Mode')
64
+ deployer.activate_maintenance_mode
65
+ end
66
+
67
+ it "makes call to heroku to turn on maintenance mode" do
68
+ heroku.should_receive(:post_app_maintenance).with(app_name, '1')
69
+ deployer.activate_maintenance_mode
70
+ end
71
+ end
72
+
73
+ describe "#deactivate_maintenance_mode" do
74
+ it "displays message" do
75
+ formatter.should_receive(:puts).with('Deactivating Maintenance Mode')
76
+ deployer.deactivate_maintenance_mode
77
+ end
78
+
79
+ it "makes call to heroku to turn on maintenance mode" do
80
+ heroku.should_receive(:post_app_maintenance).with(app_name, '0')
81
+ deployer.deactivate_maintenance_mode
82
+ end
83
+ end
84
+
85
+ describe "#update_repo_tag" do
86
+ context "when a tag_name is available" do
87
+ let(:options) { { tag: 'awesome' } }
88
+
89
+ before do
90
+ system_caller.stub(:execute)
91
+ end
92
+
93
+ it 'displays message' do
94
+ formatter.should_receive(:puts).with('Updating Repo Tag: awesome')
95
+ deployer.update_repo_tag
96
+ end
97
+
98
+ it 'creates a git tag' do
99
+ system_caller.should_receive(:execute).with('git tag awesome -f')
100
+ deployer.update_repo_tag
101
+ end
102
+
103
+ it 'pushes git tag' do
104
+ system_caller.should_receive(:execute).with('git push origin awesome')
105
+ deployer.update_repo_tag
106
+ end
107
+ end
108
+
109
+ context "when a tag_name is unavailable" do
110
+ let(:options) { Hash.new }
111
+
112
+ it 'no repo tags are created' do
113
+ system_caller.should_not_receive(:execute)
114
+ deployer.update_repo_tag
115
+ end
116
+ end
117
+ end
118
+
119
+ describe "#push_repo" do
120
+ before do
121
+ system_caller.stub(:execute)
122
+ end
123
+
124
+ it 'displays message' do
125
+ formatter.should_receive(:puts).with('Pushing master to Heroku')
126
+ deployer.push_repo
127
+ end
128
+
129
+ it 'pushes repo to heroku' do
130
+ expected_call = 'git push -f git@heroku.com:app.git master'
131
+ system_caller.should_receive(:execute).with(expected_call)
132
+ deployer.push_repo
133
+ end
134
+ end
135
+
136
+ describe "#run_migrations" do
137
+ before do
138
+ system_caller.stub(:execute)
139
+ end
140
+
141
+ it 'displays message' do
142
+ formatter.should_receive(:puts).with('Running database migrations')
143
+ deployer.run_migrations
144
+ end
145
+
146
+ it 'pushes repo to heroku' do
147
+ expected_call = 'heroku run rake db:migrate --app app'
148
+ system_caller.should_receive(:execute).with(expected_call)
149
+ deployer.run_migrations
150
+ end
151
+ end
152
+
153
+ describe "#app_restart" do
154
+ it 'displays message' do
155
+ formatter.should_receive(:puts).with('Restarting application')
156
+ deployer.app_restart
157
+ end
158
+
159
+ it 'restarts your heroku instance' do
160
+ heroku.should_receive(:post_ps_restart).with(app_name)
161
+ deployer.app_restart
162
+ end
163
+ end
164
+
165
+ describe "#warm_instance" do
166
+ before do
167
+ system_caller.stub(:execute)
168
+ end
169
+
170
+ it 'displays message' do
171
+ expected_notice = 'Accessing application_url to warm up your application'
172
+ formatter.should_receive(:puts).with(expected_notice)
173
+ deployer.warm_instance(0)
174
+ end
175
+
176
+ it 'pings application url' do
177
+ expected_call = 'curl -Il http://application_url'
178
+ system_caller.should_receive(:execute).with(expected_call)
179
+ deployer.warm_instance(0)
180
+ end
181
+ end
182
+ end
@@ -0,0 +1 @@
1
+ require 'rspec'
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: 0.0.2
4
+ version: 0.0.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -10,8 +10,40 @@ authors:
10
10
  autorequire:
11
11
  bindir: bin
12
12
  cert_chain: []
13
- date: 2013-01-15 00:00:00.000000000 Z
13
+ date: 2013-01-23 00:00:00.000000000 Z
14
14
  dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rspec
17
+ requirement: !ruby/object:Gem::Requirement
18
+ none: false
19
+ requirements:
20
+ - - ~>
21
+ - !ruby/object:Gem::Version
22
+ version: '2.12'
23
+ type: :development
24
+ prerelease: false
25
+ version_requirements: !ruby/object:Gem::Requirement
26
+ none: false
27
+ requirements:
28
+ - - ~>
29
+ - !ruby/object:Gem::Version
30
+ version: '2.12'
31
+ - !ruby/object:Gem::Dependency
32
+ name: pry
33
+ requirement: !ruby/object:Gem::Requirement
34
+ none: false
35
+ requirements:
36
+ - - ! '>='
37
+ - !ruby/object:Gem::Version
38
+ version: '0'
39
+ type: :development
40
+ prerelease: false
41
+ version_requirements: !ruby/object:Gem::Requirement
42
+ none: false
43
+ requirements:
44
+ - - ! '>='
45
+ - !ruby/object:Gem::Version
46
+ version: '0'
15
47
  - !ruby/object:Gem::Dependency
16
48
  name: heroku-api
17
49
  requirement: !ruby/object:Gem::Requirement
@@ -43,9 +75,13 @@ files:
43
75
  - README.md
44
76
  - Rakefile
45
77
  - lib/paratrooper.rb
78
+ - lib/paratrooper/default_formatter.rb
46
79
  - lib/paratrooper/deploy.rb
80
+ - lib/paratrooper/system_caller.rb
47
81
  - lib/paratrooper/version.rb
48
82
  - paratrooper.gemspec
83
+ - spec/paratrooper/deploy_spec.rb
84
+ - spec/spec_helper.rb
49
85
  homepage: http://github.com/hashrocket/paratrooper
50
86
  licenses: []
51
87
  post_install_message:
@@ -70,4 +106,6 @@ rubygems_version: 1.8.24
70
106
  signing_key:
71
107
  specification_version: 3
72
108
  summary: Library to create task for deployment to Heroku
73
- test_files: []
109
+ test_files:
110
+ - spec/paratrooper/deploy_spec.rb
111
+ - spec/spec_helper.rb