paratrooper 1.3.2 → 1.4.0

Sign up to get free protection for your applications and to get access to all the features.
data/.bundle/config ADDED
@@ -0,0 +1,2 @@
1
+ ---
2
+ BUNDLE_BIN: bin
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- paratrooper (1.3.2)
4
+ paratrooper (1.4.0)
5
5
  heroku-api (~> 0.3)
6
6
  netrc (~> 0.7)
7
7
  rendezvous (~> 0.0.1)
@@ -11,9 +11,9 @@ GEM
11
11
  specs:
12
12
  coderay (1.0.8)
13
13
  diff-lcs (1.1.3)
14
- excon (0.20.1)
15
- heroku-api (0.3.9)
16
- excon (~> 0.20.1)
14
+ excon (0.21.0)
15
+ heroku-api (0.3.10)
16
+ excon (~> 0.21.0)
17
17
  method_source (0.8.1)
18
18
  netrc (0.7.7)
19
19
  pry (0.9.10)
@@ -1,6 +1,7 @@
1
1
  require 'paratrooper/heroku_wrapper'
2
2
  require 'paratrooper/system_caller'
3
3
  require 'paratrooper/notifiers/screen_notifier'
4
+ require 'paratrooper/pending_migration_check'
4
5
 
5
6
  module Paratrooper
6
7
 
@@ -8,7 +9,7 @@ module Paratrooper
8
9
  #
9
10
  class Deploy
10
11
  attr_reader :app_name, :notifiers, :system_caller, :heroku, :tag_name,
11
- :match_tag, :protocol, :deployment_host
12
+ :match_tag, :protocol, :deployment_host, :migration_check, :debug
12
13
 
13
14
  # Public: Initializes a Deploy
14
15
  #
@@ -28,15 +29,19 @@ module Paratrooper
28
29
  # application (optional, default: 'http').
29
30
  # :deployment_host - String host name to be used in git URL
30
31
  # (optional, default: 'heroku.com').
32
+ # :migration_check - Object responsible for checking pending
33
+ # migrations (optional).
31
34
  def initialize(app_name, options = {})
32
35
  @app_name = app_name
33
36
  @notifiers = options[:notifiers] || [Notifiers::ScreenNotifier.new]
34
37
  @heroku = options[:heroku] || HerokuWrapper.new(app_name, options)
35
38
  @tag_name = options[:tag]
36
39
  @match_tag = options[:match_tag_to] || 'master'
37
- @system_caller = options[:system_caller] || SystemCaller.new
40
+ @system_caller = options[:system_caller] || SystemCaller.new(debug)
38
41
  @protocol = options[:protocol] || 'http'
39
42
  @deployment_host = options[:deployment_host] || 'heroku.com'
43
+ @debug = options[:debug] || false
44
+ self.migration_check = options[:migration_check]
40
45
  end
41
46
 
42
47
  def setup
@@ -88,6 +93,7 @@ module Paratrooper
88
93
  # Public: Runs rails database migrations on your application.
89
94
  #
90
95
  def run_migrations
96
+ return unless pending_migrations?
91
97
  notify(:run_migrations)
92
98
  heroku.run_migrations
93
99
  end
@@ -155,6 +161,14 @@ module Paratrooper
155
161
  git_remote(deployment_host, app_name)
156
162
  end
157
163
 
164
+ def pending_migrations?
165
+ migration_check.migrations_waiting?
166
+ end
167
+
168
+ def migration_check=(obj)
169
+ @migration_check = obj || PendingMigrationCheck.new(match_tag, heroku, system_caller)
170
+ end
171
+
158
172
  # Internal: Calls commands meant to go to system
159
173
  #
160
174
  # call - String version of system command
@@ -35,6 +35,12 @@ module Paratrooper
35
35
  rendezvous.start(:url => data['rendezvous_url'])
36
36
  end
37
37
 
38
+ def last_deploy_commit
39
+ data = heroku_api.get_releases(app_name).body
40
+ return nil if data.empty?
41
+ data.last['commit']
42
+ end
43
+
38
44
  private
39
45
  def app_domain_name
40
46
  if custom_domain_response
@@ -0,0 +1,23 @@
1
+ require 'paratrooper/system_caller'
2
+
3
+ module Paratrooper
4
+ class PendingMigrationCheck
5
+ attr_accessor :diff, :heroku, :match_tag_name, :system_caller
6
+
7
+ def initialize(match_tag_name, heroku_wrapper, system_caller)
8
+ self.heroku = heroku_wrapper
9
+ self.match_tag_name = match_tag_name
10
+ self.system_caller = system_caller
11
+ end
12
+
13
+ def migrations_waiting?
14
+ call = %Q[git diff --shortstat #{last_deployed_commit} #{match_tag_name} -- db/migrate]
15
+ self.diff = system_caller.execute(call)
16
+ !diff.strip.empty?
17
+ end
18
+
19
+ def last_deployed_commit
20
+ heroku.last_deploy_commit
21
+ end
22
+ end
23
+ end
@@ -1,7 +1,19 @@
1
1
  module Paratrooper
2
2
  class SystemCaller
3
+ attr_accessor :debug
4
+
5
+ def initialize(debug = false)
6
+ self.debug = debug
7
+ end
8
+
3
9
  def execute(call)
4
- system(call)
10
+ debug_message_for(call)
11
+ `#{call}`
12
+ end
13
+
14
+ private
15
+ def debug_message_for(call)
16
+ p "DEBUG: #{call}" if debug
5
17
  end
6
18
  end
7
19
  end
@@ -1,3 +1,3 @@
1
1
  module Paratrooper
2
- VERSION = "1.3.2"
2
+ VERSION = "1.4.0"
3
3
  end
@@ -10,7 +10,8 @@ describe Paratrooper::Deploy do
10
10
  {
11
11
  heroku: heroku,
12
12
  notifiers: [],
13
- system_caller: system_caller
13
+ system_caller: system_caller,
14
+ migration_check: migration_check
14
15
  }
15
16
  end
16
17
  let(:options) { Hash.new }
@@ -24,6 +25,7 @@ describe Paratrooper::Deploy do
24
25
  )
25
26
  end
26
27
  let(:system_caller) { double(:system_caller) }
28
+ let(:migration_check) { double(:migration_check) }
27
29
  let(:domain_response) do
28
30
  double(:domain_response, body: [{'domain' => 'application_url'}])
29
31
  end
@@ -175,14 +177,31 @@ describe Paratrooper::Deploy do
175
177
  system_caller.stub(:execute)
176
178
  end
177
179
 
178
- it 'sends notification' do
179
- deployer.should_receive(:notify).with(:run_migrations).once
180
- deployer.run_migrations
180
+ context "when new migrations are waiting to be run" do
181
+ before do
182
+ migration_check.stub(:migrations_waiting?).and_return(true)
183
+ end
184
+
185
+ it 'sends notification' do
186
+ deployer.should_receive(:notify).with(:run_migrations).once
187
+ deployer.run_migrations
188
+ end
189
+
190
+ it 'pushes repo to heroku' do
191
+ heroku.should_receive(:run_migrations)
192
+ deployer.run_migrations
193
+ end
181
194
  end
182
195
 
183
- it 'pushes repo to heroku' do
184
- heroku.should_receive(:run_migrations)
185
- deployer.run_migrations
196
+ context "when no migrations are available to be run" do
197
+ before do
198
+ migration_check.stub(:migrations_waiting?).and_return(false)
199
+ end
200
+
201
+ specify "heroku is not notified to run migrations" do
202
+ heroku.should_not_receive(:run_migrations)
203
+ deployer.run_migrations
204
+ end
186
205
  end
187
206
  end
188
207
 
@@ -107,4 +107,29 @@ describe Paratrooper::HerokuWrapper do
107
107
  end
108
108
  end
109
109
  end
110
+
111
+ describe "#last_deploy_commit" do
112
+ context "when deploy data is returned" do
113
+ let(:response) do
114
+ double(:response, body: [{ 'commit' => 'SHA' }])
115
+ end
116
+ it "returns string of last deployed commit" do
117
+ heroku_api.should_receive(:get_releases).with(app_name)
118
+ .and_return(response)
119
+ expect(wrapper.last_deploy_commit).to eq('SHA')
120
+ end
121
+ end
122
+
123
+ context "when no deploys have happened yet" do
124
+ let(:response) do
125
+ double(:response, body: [])
126
+ end
127
+
128
+ it "returns nil" do
129
+ heroku_api.should_receive(:get_releases).with(app_name)
130
+ .and_return(response)
131
+ expect(wrapper.last_deploy_commit).to eq(nil)
132
+ end
133
+ end
134
+ end
110
135
  end
@@ -0,0 +1,45 @@
1
+ require 'spec_helper'
2
+ require 'paratrooper/pending_migration_check'
3
+
4
+ describe Paratrooper::PendingMigrationCheck do
5
+ let(:migration_check) do
6
+ described_class.new(match_tag_name, heroku_wrapper, system_caller)
7
+ end
8
+ let(:system_caller) { double(:system_caller) }
9
+ let(:heroku_wrapper) do
10
+ double(:heroku_wrapper, last_deploy_commit: last_deployed_commit)
11
+ end
12
+ let(:last_deployed_commit) { nil }
13
+
14
+ describe "#migrations_waiting?" do
15
+ let(:match_tag_name) { "MATCH" }
16
+ let(:last_deployed_commit) { "LAST_DEPLOYED_COMMIT" }
17
+
18
+ it "calls out to heroku for latest deploy's commit" do
19
+ system_caller.stub(:execute).and_return("")
20
+ heroku_wrapper.should_receive(:last_deploy_commit)
21
+ migration_check.migrations_waiting?
22
+ end
23
+
24
+ context "and migrations are in diff" do
25
+ it "returns true" do
26
+ expected_call = %Q[git diff --shortstat LAST_DEPLOYED_COMMIT MATCH -- db/migrate]
27
+ system_caller.should_receive(:execute).with(expected_call)
28
+ .and_return("DIFF")
29
+ expect(migration_check.migrations_waiting?).to be_true
30
+ end
31
+ end
32
+
33
+ context "and migrations are not in diff" do
34
+ let(:match_tag_name) { 'master' }
35
+ let(:last_deployed_commit) { "LAST_DEPLOYED_COMMIT" }
36
+
37
+ it "returns false" do
38
+ expected_call = %Q[git diff --shortstat LAST_DEPLOYED_COMMIT master -- db/migrate]
39
+ system_caller.should_receive(:execute).with(expected_call)
40
+ .and_return("")
41
+ expect(migration_check.migrations_waiting?).to be_false
42
+ end
43
+ end
44
+ end
45
+ end
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.3.2
4
+ version: 1.4.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-04-15 00:00:00.000000000 Z
13
+ date: 2013-05-21 00:00:00.000000000 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: rake
@@ -116,6 +116,7 @@ executables: []
116
116
  extensions: []
117
117
  extra_rdoc_files: []
118
118
  files:
119
+ - .bundle/config
119
120
  - .gitignore
120
121
  - .ruby-version
121
122
  - Gemfile
@@ -129,6 +130,7 @@ files:
129
130
  - lib/paratrooper/local_api_key_extractor.rb
130
131
  - lib/paratrooper/notifier.rb
131
132
  - lib/paratrooper/notifiers/screen_notifier.rb
133
+ - lib/paratrooper/pending_migration_check.rb
132
134
  - lib/paratrooper/system_caller.rb
133
135
  - lib/paratrooper/version.rb
134
136
  - paratrooper.gemspec
@@ -138,6 +140,7 @@ files:
138
140
  - spec/paratrooper/local_api_key_extractor_spec.rb
139
141
  - spec/paratrooper/notifier_spec.rb
140
142
  - spec/paratrooper/notifiers/screen_notifier_spec.rb
143
+ - spec/paratrooper/pending_migration_check_spec.rb
141
144
  - spec/spec_helper.rb
142
145
  homepage: http://github.com/mattpolito/paratrooper
143
146
  licenses: []
@@ -170,4 +173,5 @@ test_files:
170
173
  - spec/paratrooper/local_api_key_extractor_spec.rb
171
174
  - spec/paratrooper/notifier_spec.rb
172
175
  - spec/paratrooper/notifiers/screen_notifier_spec.rb
176
+ - spec/paratrooper/pending_migration_check_spec.rb
173
177
  - spec/spec_helper.rb