whiskey_disk 0.6.17 → 0.6.20
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGELOG +34 -0
- data/README.markdown +33 -3
- data/VERSION +1 -1
- data/bin/wd +3 -3
- data/lib/whiskey_disk.rb +52 -15
- data/lib/whiskey_disk/helpers.rb +42 -0
- data/lib/whiskey_disk/rake.rb +1 -0
- data/spec/spec_helper.rb +19 -2
- data/spec/wd_command_spec.rb +126 -22
- data/spec/whiskey_disk/helpers_spec.rb +399 -1
- data/spec/whiskey_disk/rake_spec.rb +6 -0
- data/spec/whiskey_disk_spec.rb +75 -8
- data/whiskey_disk.gemspec +2 -2
- metadata +4 -4
data/CHANGELOG
CHANGED
@@ -1,4 +1,38 @@
|
|
1
1
|
|
2
|
+
0.6.20 / 2011-04-06
|
3
|
+
==================
|
4
|
+
|
5
|
+
* Output the entire command before running it when debugging.
|
6
|
+
* more anal git checkouts on clones to support older gits
|
7
|
+
* abort instead of raising in wd
|
8
|
+
* Neuter commandline output in wd command spec
|
9
|
+
* Make #changes work on setup
|
10
|
+
* Allow enabling debugger in specs w/ non-empty ENV['debug']
|
11
|
+
* Fix setup #changed? integration specs
|
12
|
+
* Improve example text for deployment #changed? integration specs
|
13
|
+
* Factor out snapshotting of git revision from WD.initialize_git_changes
|
14
|
+
* Fix the direction of the setup #changed? integration spec test
|
15
|
+
* Fixing jump_to_initial_commit spec helper
|
16
|
+
* Helper integration spec should use the correct branch when setting up.
|
17
|
+
* adjust env testing in integration specs
|
18
|
+
* update some specs to work with updated checkout/setup helpers
|
19
|
+
* use branches in integration checks so full checkouts will work
|
20
|
+
* when initializing git changes data, work from deployment path
|
21
|
+
* allow integration spec checkouts to switch to a specific branch
|
22
|
+
* record git changes for later use by #changed?
|
23
|
+
* capture rsync changes for later #changed? analysis
|
24
|
+
* capture initial git HEAD ref for later #changes comparisons
|
25
|
+
* clean out any prior git/rsync changes data before refreshing repos
|
26
|
+
* Add specs for version command-line argument
|
27
|
+
* Change spec helper run_command method set pwd to bin/
|
28
|
+
* integration spec for #changed? in post_setup tasks
|
29
|
+
* adding #changed? helper (and friends) to whiskey_disk/helpers
|
30
|
+
* spec_helper method to rewind a git repo to the beginning
|
31
|
+
* git project scenario changes to support integration testing of #changes helper
|
32
|
+
* refactor: splitting up WD.summarize method
|
33
|
+
* README updates for #changed? helper functionality
|
34
|
+
|
35
|
+
|
2
36
|
0.6.17 / 2011-03-25
|
3
37
|
==================
|
4
38
|
|
data/README.markdown
CHANGED
@@ -86,12 +86,14 @@ current local checkout.
|
|
86
86
|
|
87
87
|
- You can deploy to multiple remote targets at once. Currently this is limited
|
88
88
|
to one-after-the-other synchronous deployments, but we're thinking about
|
89
|
-
doing them in parallel once we're happy with the stability of this
|
90
|
-
feature.
|
89
|
+
doing them in parallel once we're happy with the stability of this feature.
|
91
90
|
|
92
91
|
- Assign hosts to roles (e.g., "web", "db", "app") and vary the shell or rake
|
93
92
|
post-setup/post-deploy actions you run based on those roles.
|
94
93
|
|
94
|
+
- Limit the actions you run after deployment based on whether files of interest
|
95
|
+
*actually changed*.
|
96
|
+
|
95
97
|
### Assumptions ###
|
96
98
|
|
97
99
|
- your project is managed via git
|
@@ -486,9 +488,37 @@ You can also define these tasks yourself if you want to eliminate the dependency
|
|
486
488
|
deployment target system.
|
487
489
|
|
488
490
|
|
491
|
+
### Doing things when files of interest change ###
|
492
|
+
|
493
|
+
Do you want to run database migrations when no migrations have been added? Why bother compressing front-end assets when none of them have changed? Why restart your application server if only the project README changed? Whiskey\_disk provides a `changed?` ruby helper method to allow you to decide whether to run expensive post deployment tasks, based on what files changed in the deployment. Typically this would happen in your rake tasks, but it could happen from regular ruby code as well.
|
494
|
+
|
495
|
+
|
496
|
+
require 'whiskey_disk/helpers'
|
497
|
+
|
498
|
+
namespace :deploy do
|
499
|
+
|
500
|
+
task :run_migrations do
|
501
|
+
if role?(:db) and changed?('db/migrate')
|
502
|
+
puts "Running database migrations..."
|
503
|
+
Rake::Task['db:migrate'].invoke
|
504
|
+
end
|
505
|
+
end
|
506
|
+
|
507
|
+
task :compress_assets do
|
508
|
+
if changed?('public/stylesheets') or changed?('public/javascripts')
|
509
|
+
puts "Getting my asset munge on..."
|
510
|
+
# do some expensive asset compression stuff
|
511
|
+
end
|
512
|
+
end
|
513
|
+
|
514
|
+
task :post_deploy => [ :run_migrations, :compress_assets ]
|
515
|
+
end
|
516
|
+
|
517
|
+
|
518
|
+
|
489
519
|
### Running via rake ###
|
490
520
|
|
491
|
-
In your Rakefile:
|
521
|
+
You can use rake tasks to do everything possible with whiskey\_disk (the `wd` command is just a front-end to the whiskey\_disk rake tasks). In your Rakefile:
|
492
522
|
|
493
523
|
require 'whiskey_disk/rake'
|
494
524
|
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.6.
|
1
|
+
0.6.20
|
data/bin/wd
CHANGED
@@ -43,10 +43,10 @@ rescue
|
|
43
43
|
abort op.to_s
|
44
44
|
end
|
45
45
|
|
46
|
-
|
47
|
-
|
46
|
+
abort op.to_s unless options[:target]
|
47
|
+
abort op.to_s unless rest and rest.size == 1
|
48
48
|
command = rest.first
|
49
|
-
|
49
|
+
abort op.to_s unless ['deploy', 'setup'].include?(command)
|
50
50
|
|
51
51
|
ENV['to'] = options[:target]
|
52
52
|
ENV['path'] = options[:path]
|
data/lib/whiskey_disk.rb
CHANGED
@@ -137,12 +137,14 @@ class WhiskeyDisk
|
|
137
137
|
end
|
138
138
|
|
139
139
|
def ssh(domain, cmd)
|
140
|
+
puts "Running command on [#{domain}]: [#{cmd}]" if Config.debug?
|
140
141
|
args = [domain[:name], build_command(domain, cmd)]
|
141
142
|
args.unshift '-v' if Config.debug?
|
142
143
|
system('ssh', *args)
|
143
144
|
end
|
144
145
|
|
145
146
|
def shell(domain, cmd)
|
147
|
+
puts "Running command locally: [#{cmd}]" if Config.debug?
|
146
148
|
system('bash', '-c', build_command(domain, cmd))
|
147
149
|
end
|
148
150
|
|
@@ -160,22 +162,24 @@ class WhiskeyDisk
|
|
160
162
|
@results ||= []
|
161
163
|
@results << { :domain => domain, :status => status }
|
162
164
|
end
|
165
|
+
|
166
|
+
def summarize_results(results)
|
167
|
+
successes = failures = 0
|
168
|
+
results.each do |result|
|
169
|
+
puts "#{result[:domain]} => #{result[:status] ? 'succeeded' : 'failed'}."
|
170
|
+
if result[:status]
|
171
|
+
successes += 1
|
172
|
+
else
|
173
|
+
failures += 1
|
174
|
+
end
|
175
|
+
end
|
176
|
+
[successes + failures, successes, failures]
|
177
|
+
end
|
163
178
|
|
164
179
|
def summarize
|
165
|
-
puts
|
166
|
-
puts "Results:"
|
180
|
+
puts "\nResults:"
|
167
181
|
if results and not results.empty?
|
168
|
-
successes
|
169
|
-
results.each do |result|
|
170
|
-
total += 1
|
171
|
-
if result[:status]
|
172
|
-
successes += 1
|
173
|
-
else
|
174
|
-
failures += 1
|
175
|
-
end
|
176
|
-
|
177
|
-
puts "#{result[:domain]} => #{result[:status] ? 'succeeded' : 'failed'}."
|
178
|
-
end
|
182
|
+
total, successes, failures = summarize_results(results)
|
179
183
|
puts "Total: #{total} deployment#{total == 1 ? '' : 's'}, " +
|
180
184
|
"#{successes} success#{successes == 1 ? '' : 'es'}, " +
|
181
185
|
"#{failures} failure#{failures == 1 ? '' : 's'}."
|
@@ -198,7 +202,7 @@ class WhiskeyDisk
|
|
198
202
|
end
|
199
203
|
|
200
204
|
def safe_branch_checkout(path, my_branch)
|
201
|
-
%Q(cd #{path} && git checkout -b #{my_branch} origin/#{my_branch} || git checkout #{my_branch})
|
205
|
+
%Q(cd #{path} && git checkout -b #{my_branch} origin/#{my_branch} || git checkout #{my_branch} origin/#{my_branch} || git checkout #{my_branch})
|
202
206
|
end
|
203
207
|
|
204
208
|
def clone_repository(repo, path, my_branch)
|
@@ -251,13 +255,44 @@ class WhiskeyDisk
|
|
251
255
|
clone_repository(self[:config_repository], self[:deploy_config_to], config_branch)
|
252
256
|
end
|
253
257
|
|
258
|
+
def snapshot_git_revision
|
259
|
+
needs(:deploy_to)
|
260
|
+
enqueue "cd #{self[:deploy_to]}"
|
261
|
+
enqueue %Q{ml=\`cat .git/refs/heads/#{branch}\`}
|
262
|
+
end
|
263
|
+
|
264
|
+
def initialize_git_changes
|
265
|
+
needs(:deploy_to)
|
266
|
+
enqueue "rm -f #{self[:deploy_to]}/.whiskey_disk_git_changes"
|
267
|
+
snapshot_git_revision
|
268
|
+
end
|
269
|
+
|
270
|
+
def initialize_rsync_changes
|
271
|
+
needs(:deploy_to)
|
272
|
+
enqueue "rm -f #{self[:deploy_to]}/.whiskey_disk_rsync_changes"
|
273
|
+
end
|
274
|
+
|
275
|
+
def initialize_all_changes
|
276
|
+
needs(:deploy_to)
|
277
|
+
initialize_git_changes
|
278
|
+
initialize_rsync_changes
|
279
|
+
end
|
280
|
+
|
281
|
+
def capture_git_changes
|
282
|
+
needs(:deploy_to)
|
283
|
+
enqueue "git diff --name-only ${ml}..HEAD > #{self[:deploy_to]}/.whiskey_disk_git_changes"
|
284
|
+
end
|
285
|
+
|
254
286
|
def update_main_repository_checkout
|
255
287
|
needs(:deploy_to)
|
288
|
+
initialize_git_changes
|
256
289
|
refresh_checkout(self[:deploy_to], branch)
|
290
|
+
capture_git_changes
|
257
291
|
end
|
258
292
|
|
259
293
|
def update_configuration_repository_checkout
|
260
294
|
needs(:deploy_config_to)
|
295
|
+
initialize_rsync_changes
|
261
296
|
refresh_checkout(self[:deploy_config_to], config_branch)
|
262
297
|
end
|
263
298
|
|
@@ -265,7 +300,9 @@ class WhiskeyDisk
|
|
265
300
|
needs(:deploy_to, :deploy_config_to)
|
266
301
|
raise "Must specify project name when using a configuration repository." unless project_name_specified?
|
267
302
|
enqueue "echo Rsyncing configuration..."
|
268
|
-
enqueue("rsync -a#{'v --progress' if Config.debug?}
|
303
|
+
enqueue("rsync -a#{'v --progress' if Config.debug?} " +
|
304
|
+
"--log-file=#{self[:deploy_to]}/.whiskey_disk_rsync_changes " +
|
305
|
+
"#{self[:deploy_config_to]}/#{self[:project]}/#{self[:config_target]}/ #{self[:deploy_to]}/")
|
269
306
|
end
|
270
307
|
|
271
308
|
def run_post_setup_hooks
|
data/lib/whiskey_disk/helpers.rb
CHANGED
@@ -3,4 +3,46 @@
|
|
3
3
|
def role?(role)
|
4
4
|
return false unless ENV['WD_ROLES'] and ENV['WD_ROLES'] != ''
|
5
5
|
ENV['WD_ROLES'].split(':').include?(role.to_s)
|
6
|
+
end
|
7
|
+
|
8
|
+
# have files of interest changed on this deployment?
|
9
|
+
def changed?(path)
|
10
|
+
return true unless gc = git_changes
|
11
|
+
cleaned = Regexp.escape(path.sub(%r{/+$}, ''))
|
12
|
+
[ gc, rsync_changes ].flatten.compact.any? { |p| p =~ %r<^#{cleaned}(?:$|/)> }
|
13
|
+
end
|
14
|
+
|
15
|
+
# list of changed paths, according to git
|
16
|
+
def git_changes
|
17
|
+
changes = read_git_changes_file.split("\n").uniq
|
18
|
+
rescue Exception
|
19
|
+
nil
|
20
|
+
end
|
21
|
+
|
22
|
+
def rsync_changes
|
23
|
+
changes = read_rsync_changes_file.split("\n")
|
24
|
+
changes.map {|c| c.sub(/^[^ ]* [^ ]* [^ ]* [^ ]* /, '') }.grep(%r{/}).map {|s| s.sub(%r{/$}, '') } - ['.']
|
25
|
+
rescue Exception
|
26
|
+
nil
|
27
|
+
end
|
28
|
+
|
29
|
+
def read_git_changes_file
|
30
|
+
File.read(git_changes_path)
|
31
|
+
end
|
32
|
+
|
33
|
+
def read_rsync_changes_file
|
34
|
+
File.read(rsync_changes_path)
|
35
|
+
end
|
36
|
+
|
37
|
+
def changes_file_root
|
38
|
+
path = IO.popen("git rev-parse --show-toplevel").read
|
39
|
+
path == '' ? Dir.pwd : path.chomp
|
40
|
+
end
|
41
|
+
|
42
|
+
def git_changes_path
|
43
|
+
File.join(changes_file_root, '.whiskey_disk_git_changes')
|
44
|
+
end
|
45
|
+
|
46
|
+
def rsync_changes_path
|
47
|
+
File.join(changes_file_root, '.whiskey_disk_rsync_changes')
|
6
48
|
end
|
data/lib/whiskey_disk/rake.rb
CHANGED
@@ -11,6 +11,7 @@ namespace :deploy do
|
|
11
11
|
WhiskeyDisk.update_main_repository_checkout
|
12
12
|
WhiskeyDisk.update_configuration_repository_checkout if WhiskeyDisk.has_config_repo?
|
13
13
|
WhiskeyDisk.refresh_configuration if WhiskeyDisk.has_config_repo?
|
14
|
+
WhiskeyDisk.initialize_all_changes
|
14
15
|
WhiskeyDisk.run_post_setup_hooks
|
15
16
|
WhiskeyDisk.flush
|
16
17
|
WhiskeyDisk.summarize
|
data/spec/spec_helper.rb
CHANGED
@@ -3,6 +3,13 @@ require 'bacon'
|
|
3
3
|
require 'facon'
|
4
4
|
require 'fileutils'
|
5
5
|
|
6
|
+
if ENV['DEBUG'] and ENV['DEBUG'] != ''
|
7
|
+
STDERR.puts "Enabling debugger for spec runs..."
|
8
|
+
require 'rubygems'
|
9
|
+
require 'ruby-debug'
|
10
|
+
Debugger.start
|
11
|
+
end
|
12
|
+
|
6
13
|
$:.unshift(File.expand_path(File.join(File.dirname(__FILE__), '..', 'lib')))
|
7
14
|
|
8
15
|
# local target directory, integration spec workspace
|
@@ -50,9 +57,19 @@ def scenario_config(path)
|
|
50
57
|
end
|
51
58
|
|
52
59
|
# clone a git repository locally (as if a "wd setup" had been deployed)
|
53
|
-
def checkout_repo(repo_name,
|
60
|
+
def checkout_repo(repo_name, branch = nil)
|
54
61
|
repo_path = File.expand_path(File.join(File.dirname(__FILE__), '..', 'scenarios', 'git_repositories', "#{repo_name}.git"))
|
55
|
-
system("cd #{deployment_root} && git clone #{repo_path}
|
62
|
+
system("cd #{deployment_root} && git clone #{repo_path} >/dev/null 2>/dev/null")
|
63
|
+
checkout_branch(repo_name, branch)
|
64
|
+
end
|
65
|
+
|
66
|
+
def checkout_branch(repo_name, branch = nil)
|
67
|
+
return unless branch
|
68
|
+
system("cd #{deployment_root}/#{repo_name} && git checkout #{branch} >/dev/null 2>/dev/null")
|
69
|
+
end
|
70
|
+
|
71
|
+
def jump_to_initial_commit(path)
|
72
|
+
system(%Q(cd #{File.join(deployment_root, path)} && git reset --hard `git log --oneline | tail -1 | awk '{print $1}'` >/dev/null 2>/dev/null))
|
56
73
|
end
|
57
74
|
|
58
75
|
def run_log
|
data/spec/wd_command_spec.rb
CHANGED
@@ -2,13 +2,24 @@ require File.dirname(__FILE__) + '/spec_helper.rb'
|
|
2
2
|
require 'rake'
|
3
3
|
|
4
4
|
def run_command
|
5
|
-
|
5
|
+
cmd_path = File.expand_path(File.join(File.dirname(__FILE__), *%w[.. bin wd]))
|
6
|
+
path = File.expand_path(File.dirname(cmd_path))
|
7
|
+
file = File.read(cmd_path)
|
8
|
+
|
9
|
+
Dir.chdir(path) do |path|
|
10
|
+
eval(file)
|
11
|
+
end
|
6
12
|
end
|
7
13
|
|
8
14
|
describe 'wd command' do
|
9
15
|
before do
|
16
|
+
@stderr, @stdout, $stderr, $stdout = $stderr, $stdout, StringIO.new, StringIO.new
|
10
17
|
ENV['to'] = ENV['path'] = nil
|
11
18
|
end
|
19
|
+
|
20
|
+
after do
|
21
|
+
@stderr, @stdout, $stderr, $stdout = $stderr, $stdout, @stderr, @stdout
|
22
|
+
end
|
12
23
|
|
13
24
|
describe 'when no command-line arguments are specified' do
|
14
25
|
before do
|
@@ -21,25 +32,56 @@ describe 'wd command' do
|
|
21
32
|
lambda { run_command }
|
22
33
|
end
|
23
34
|
|
24
|
-
it 'should
|
25
|
-
lambda { run_command }.should.raise
|
35
|
+
it 'should exit' do
|
36
|
+
lambda { run_command }.should.raise(SystemExit)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'should exit with a failure status' do
|
40
|
+
begin
|
41
|
+
run_command
|
42
|
+
rescue Exception => e
|
43
|
+
e.success?.should == false
|
44
|
+
end
|
26
45
|
end
|
27
46
|
end
|
28
47
|
|
29
48
|
it 'should output usage without a backtrace when --help is specified' do
|
30
49
|
Object.send(:remove_const, :ARGV)
|
31
50
|
ARGV = ['--help']
|
32
|
-
self.stub!(:abort).and_raise(SystemExit) # primarily to drop extraneous output
|
33
51
|
lambda { run_command }.should.raise(SystemExit)
|
34
52
|
end
|
35
53
|
|
36
54
|
it 'should output usage without a backtrace when garbage options are specified' do
|
37
55
|
Object.send(:remove_const, :ARGV)
|
38
56
|
ARGV = ['--slkjfsdflkj']
|
39
|
-
self.stub!(:abort).and_raise(SystemExit) # primarily to drop extraneous output
|
40
57
|
lambda { run_command }.should.raise(SystemExit)
|
41
58
|
end
|
42
59
|
|
60
|
+
describe 'when --version argument is specified' do
|
61
|
+
before do
|
62
|
+
Object.send(:remove_const, :ARGV)
|
63
|
+
ARGV = ['--version']
|
64
|
+
end
|
65
|
+
|
66
|
+
# it 'should output the version stored in the VERSION file' do
|
67
|
+
# version = File.read(File.expand_path(File.join(File.dirname(__FILE__), '..', 'VERSION'))).chomp
|
68
|
+
# # TODO: capture version output
|
69
|
+
# lambda{ run_command }
|
70
|
+
# end
|
71
|
+
|
72
|
+
it 'should exit' do
|
73
|
+
lambda { run_command }.should.raise(SystemExit)
|
74
|
+
end
|
75
|
+
|
76
|
+
it 'should exit successfully' do
|
77
|
+
begin
|
78
|
+
run_command
|
79
|
+
rescue SystemExit => e
|
80
|
+
e.success?.should == true
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
43
85
|
describe "when the 'setup' command is specified" do
|
44
86
|
before do
|
45
87
|
Object.send(:remove_const, :ARGV)
|
@@ -51,9 +93,17 @@ describe 'wd command' do
|
|
51
93
|
Rake::Application.should.receive(:new).never
|
52
94
|
lambda { run_command }
|
53
95
|
end
|
54
|
-
|
55
|
-
it 'should
|
56
|
-
lambda { run_command }.should.raise
|
96
|
+
|
97
|
+
it 'should exit when a target is specified' do
|
98
|
+
lambda { run_command }.should.raise(SystemExit)
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'should exit with a failing status when a target is specified' do
|
102
|
+
begin
|
103
|
+
run_command
|
104
|
+
rescue SystemExit => e
|
105
|
+
e.success?.should == false
|
106
|
+
end
|
57
107
|
end
|
58
108
|
end
|
59
109
|
|
@@ -432,8 +482,16 @@ describe 'wd command' do
|
|
432
482
|
lambda { run_command }
|
433
483
|
end
|
434
484
|
|
435
|
-
it 'should
|
436
|
-
lambda { run_command }.should.raise
|
485
|
+
it 'should exit when a target is specified' do
|
486
|
+
lambda { run_command }.should.raise(SystemExit)
|
487
|
+
end
|
488
|
+
|
489
|
+
it 'should exit with a failing status when a target is specified' do
|
490
|
+
begin
|
491
|
+
run_command
|
492
|
+
rescue SystemExit => e
|
493
|
+
e.success?.should == false
|
494
|
+
end
|
437
495
|
end
|
438
496
|
end
|
439
497
|
|
@@ -854,13 +912,36 @@ describe 'wd command' do
|
|
854
912
|
ARGV = ['frazzlebazzle', 'shizzlebizzle']
|
855
913
|
end
|
856
914
|
|
857
|
-
|
858
|
-
|
915
|
+
describe 'when no target is specified' do
|
916
|
+
it 'should exit when a target is specified' do
|
917
|
+
lambda { run_command }.should.raise(SystemExit)
|
918
|
+
end
|
919
|
+
|
920
|
+
it 'should exit with a failing status when a target is specified' do
|
921
|
+
begin
|
922
|
+
run_command
|
923
|
+
rescue SystemExit => e
|
924
|
+
e.success?.should == false
|
925
|
+
end
|
926
|
+
end
|
859
927
|
end
|
860
|
-
|
861
|
-
|
862
|
-
|
863
|
-
|
928
|
+
|
929
|
+
describe 'when a target is specified' do
|
930
|
+
before do
|
931
|
+
ARGV.push('--to=foo')
|
932
|
+
end
|
933
|
+
|
934
|
+
it 'should exit when a target is specified' do
|
935
|
+
lambda { run_command }.should.raise(SystemExit)
|
936
|
+
end
|
937
|
+
|
938
|
+
it 'should exit with a failing status when a target is specified' do
|
939
|
+
begin
|
940
|
+
run_command
|
941
|
+
rescue SystemExit => e
|
942
|
+
e.success?.should == false
|
943
|
+
end
|
944
|
+
end
|
864
945
|
end
|
865
946
|
end
|
866
947
|
|
@@ -870,13 +951,36 @@ describe 'wd command' do
|
|
870
951
|
ARGV = ['frazzlebazzle']
|
871
952
|
end
|
872
953
|
|
873
|
-
|
874
|
-
|
954
|
+
describe 'when no target is specified' do
|
955
|
+
it 'should exit when a target is specified' do
|
956
|
+
lambda { run_command }.should.raise(SystemExit)
|
957
|
+
end
|
958
|
+
|
959
|
+
it 'should exit with a failing status when a target is specified' do
|
960
|
+
begin
|
961
|
+
run_command
|
962
|
+
rescue SystemExit => e
|
963
|
+
e.success?.should == false
|
964
|
+
end
|
965
|
+
end
|
875
966
|
end
|
876
|
-
|
877
|
-
|
878
|
-
|
879
|
-
|
967
|
+
|
968
|
+
describe 'when a target is specified' do
|
969
|
+
before do
|
970
|
+
ARGV.push('--to=foo')
|
971
|
+
end
|
972
|
+
|
973
|
+
it 'should exit when a target is specified' do
|
974
|
+
lambda { run_command }.should.raise(SystemExit)
|
975
|
+
end
|
976
|
+
|
977
|
+
it 'should exit with a failing status when a target is specified' do
|
978
|
+
begin
|
979
|
+
run_command
|
980
|
+
rescue SystemExit => e
|
981
|
+
e.success?.should == false
|
982
|
+
end
|
983
|
+
end
|
880
984
|
end
|
881
985
|
end
|
882
986
|
end
|
@@ -1,7 +1,7 @@
|
|
1
1
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper.rb'))
|
2
2
|
require File.expand_path(File.join(File.dirname(__FILE__), '..', '..', 'lib', 'whiskey_disk', 'helpers'))
|
3
3
|
|
4
|
-
describe '
|
4
|
+
describe 'when checking for a role during setup or deployment' do
|
5
5
|
it 'should accept a role string' do
|
6
6
|
lambda { role?('web') }.should.not.raise(ArgumentError)
|
7
7
|
end
|
@@ -41,3 +41,401 @@ describe '#role?' do
|
|
41
41
|
end
|
42
42
|
end
|
43
43
|
|
44
|
+
def set_git_changes(changes)
|
45
|
+
self.stub!(:git_changes).and_return(changes)
|
46
|
+
end
|
47
|
+
|
48
|
+
def set_rsync_changes(changes)
|
49
|
+
self.stub!(:rsync_changes).and_return(changes)
|
50
|
+
end
|
51
|
+
|
52
|
+
describe 'when determining if certain files changed when a deployment was run' do
|
53
|
+
before do
|
54
|
+
@matching_file = '/path/to/file'
|
55
|
+
@matching_path = '/path/to'
|
56
|
+
@non_matching_file = '/nowhere/file'
|
57
|
+
@substring_file = '/nowhere/filething'
|
58
|
+
@random_file = '/random/path'
|
59
|
+
|
60
|
+
set_git_changes([])
|
61
|
+
set_rsync_changes([])
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'should accept a path' do
|
65
|
+
lambda { changed?('foo') }.should.not.raise(ArgumentError)
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'should require a path' do
|
69
|
+
lambda { changed? }.should.raise(ArgumentError)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'should be true when the specified file is in the list of git changes' do
|
73
|
+
set_git_changes([ @matching_file, @random_file])
|
74
|
+
changed?(@matching_file).should.be.true
|
75
|
+
end
|
76
|
+
|
77
|
+
it 'should ignore trailing "/"s in the provided path when doing an exact git change match' do
|
78
|
+
set_git_changes([ @matching_file, @random_file])
|
79
|
+
changed?(@matching_file + '///').should.be.true
|
80
|
+
end
|
81
|
+
|
82
|
+
it 'should be true when the specified path is a full path prefix in the list of git changes' do
|
83
|
+
set_git_changes([ @matching_file , @random_file])
|
84
|
+
changed?(@matching_path).should.be.true
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'should ignore trailing "/"s in the provided path when doing a path git change match' do
|
88
|
+
set_git_changes([ @matching_file , @random_file])
|
89
|
+
changed?(@matching_path + '///').should.be.true
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'should be true when the specified file is in the list of rsync changes' do
|
93
|
+
set_rsync_changes([ @matching_file, @random_file])
|
94
|
+
changed?(@matching_file).should.be.true
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'should ignore trailing "/"s in the provided path when doing an exact rsync change match' do
|
98
|
+
set_rsync_changes([ @matching_file, @random_file])
|
99
|
+
changed?(@matching_file + "///").should.be.true
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'should be true when the specified path is a full path prefix in the list of git changes' do
|
103
|
+
set_rsync_changes([ @matching_file , @random_file])
|
104
|
+
changed?(@matching_path).should.be.true
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'should ignore trailing "/"s in the provided path when doing a path rsync change match' do
|
108
|
+
set_rsync_changes([ @matching_file , @random_file])
|
109
|
+
changed?(@matching_path + '///').should.be.true
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'should ignore regex metacharacters when looking for a git match' do
|
113
|
+
set_git_changes([ '/path/to/somestring'])
|
114
|
+
changed?('/path/to/some.*').should.be.false
|
115
|
+
end
|
116
|
+
|
117
|
+
it 'should ignore regex metacharacters when looking for an rsync match' do
|
118
|
+
set_rsync_changes([ '/path/to/somestring'])
|
119
|
+
changed?('/path/to/some.*').should.be.false
|
120
|
+
end
|
121
|
+
|
122
|
+
it 'should be true when the git changes file cannot be found' do
|
123
|
+
set_git_changes(nil)
|
124
|
+
changed?(@matching_file).should.be.true
|
125
|
+
end
|
126
|
+
|
127
|
+
it 'should be false if not path or file matches the specified file' do
|
128
|
+
set_git_changes([@matching_file, @matching_path, @random_file, @substring_file])
|
129
|
+
set_rsync_changes([@matching_file, @matching_path, @random_file, @substring_file])
|
130
|
+
changed?(@non_matching_file).should.be.false
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
describe "when finding files changed by git in a deployment" do
|
135
|
+
before do
|
136
|
+
@contents = 'CHANGELOG
|
137
|
+
README.markdown
|
138
|
+
Rakefile
|
139
|
+
VERSION
|
140
|
+
lib/whiskey_disk.rb
|
141
|
+
lib/whiskey_disk/config.rb
|
142
|
+
lib/whiskey_disk/helpers.rb
|
143
|
+
scenarios/git_repositories/project.git/objects/04/26e152e66c8cd42974279bdcae09be9839c172
|
144
|
+
scenarios/git_repositories/project.git/objects/04/f4de85eaf72ef1631dc6d7424045c0a749b757
|
145
|
+
scenarios/git_repositories/project.git/refs/heads/bad_rakefile
|
146
|
+
scenarios/git_repositories/project.git/refs/heads/master
|
147
|
+
scenarios/remote/deploy.yml
|
148
|
+
spec/integration/deployment_failures_spec.rb
|
149
|
+
spec/integration/post_rake_tasks_spec.rb
|
150
|
+
spec/integration/staleness_checks_spec.rb
|
151
|
+
spec/spec_helper.rb
|
152
|
+
spec/whiskey_disk/config_spec.rb
|
153
|
+
spec/whiskey_disk/helpers_spec.rb
|
154
|
+
spec/whiskey_disk_spec.rb
|
155
|
+
whiskey_disk.gemspec
|
156
|
+
'
|
157
|
+
end
|
158
|
+
|
159
|
+
it 'should work without arguments' do
|
160
|
+
lambda { git_changes }.should.not.raise(ArgumentError)
|
161
|
+
end
|
162
|
+
|
163
|
+
it 'should not allow arguments' do
|
164
|
+
lambda { git_changes(:foo) }.should.raise(ArgumentError)
|
165
|
+
end
|
166
|
+
|
167
|
+
it 'should return nil when a git changes file cannot be found' do
|
168
|
+
self.stub!(:read_git_changes_file).and_raise
|
169
|
+
git_changes.should.be.nil
|
170
|
+
end
|
171
|
+
|
172
|
+
it 'should return an empty list if no files are found in the git changes file' do
|
173
|
+
self.stub!(:read_git_changes_file).and_return('')
|
174
|
+
git_changes.should == []
|
175
|
+
end
|
176
|
+
|
177
|
+
it 'should return a list of all filenames mentioned in the git changes file' do
|
178
|
+
self.stub!(:read_git_changes_file).and_return(@contents)
|
179
|
+
git_changes.should == @contents.split("\n")
|
180
|
+
end
|
181
|
+
|
182
|
+
it 'should strip duplicates from filenames mentioned in the git changes file' do
|
183
|
+
lines = @contents.split("\n")
|
184
|
+
duplicates = @contents + lines.first + "\n" + lines.last + "\n"
|
185
|
+
self.stub!(:read_git_changes_file).and_return(duplicates)
|
186
|
+
git_changes.sort.should == @contents.split("\n").sort
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
describe "when finding files changed by rsync in a deployment" do
|
191
|
+
before do
|
192
|
+
@contents = '2011/02/27 20:11:42 [36728] receiving file list
|
193
|
+
2011/02/27 20:11:42 [36728] sent 24 bytes received 9 bytes total size 0
|
194
|
+
2011/02/27 20:11:58 [36780] receiving file list
|
195
|
+
2011/02/27 20:11:58 [36780] sent 24 bytes received 9 bytes total size 0
|
196
|
+
2011/02/27 20:12:09 [36808] receiving file list
|
197
|
+
2011/02/27 20:12:09 [36808] sent 24 bytes received 9 bytes total size 0
|
198
|
+
2011/02/27 20:12:19 [36835] receiving file list
|
199
|
+
2011/02/27 20:12:19 [36835] .d..t.... ./
|
200
|
+
2011/02/27 20:12:19 [36835] cd+++++++ Application Support/
|
201
|
+
2011/02/27 20:12:19 [36835] cd+++++++ Application Support/Google/
|
202
|
+
2011/02/27 20:12:19 [36835] cd+++++++ Application Support/Google/GoogleTalkPlugin.app/
|
203
|
+
2011/02/27 20:12:19 [36835] cd+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/
|
204
|
+
2011/02/27 20:12:19 [36835] >f+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/Info.plist
|
205
|
+
2011/02/27 20:12:19 [36835] cd+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/
|
206
|
+
2011/02/27 20:12:19 [36835] cd+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/
|
207
|
+
2011/02/27 20:12:19 [36835] cL+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/GoogleBreakpad -> Versions/Current/GoogleBreakpad
|
208
|
+
2011/02/27 20:12:19 [36835] cL+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Resources -> Versions/Current/Resources
|
209
|
+
2011/02/27 20:12:19 [36835] cd+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Versions/
|
210
|
+
2011/02/27 20:12:19 [36835] cL+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Versions/Current -> A
|
211
|
+
2011/02/27 20:12:19 [36835] cd+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Versions/A/
|
212
|
+
2011/02/27 20:12:19 [36835] cd+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Versions/A/Resources/
|
213
|
+
2011/02/27 20:12:19 [36835] cd+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Versions/A/Resources/Reporter.app/
|
214
|
+
2011/02/27 20:12:19 [36835] cd+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Versions/A/Resources/Reporter.app/Contents/
|
215
|
+
2011/02/27 20:12:19 [36835] cd+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/MacOS/
|
216
|
+
2011/02/27 20:12:20 [36835] >f+++++++ Application Support/Google/GoogleTalkPlugin.app/Contents/MacOS/GoogleTalkPlugin
|
217
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/
|
218
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/googletalkbrowserplugin.plugin/
|
219
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/googletalkbrowserplugin.plugin/Contents/
|
220
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/googletalkbrowserplugin.plugin/Contents/MacOS/
|
221
|
+
2011/02/27 20:12:20 [36835] >f+++++++ Internet Plug-Ins/googletalkbrowserplugin.plugin/Contents/MacOS/googletalkbrowserplugin
|
222
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/googletalkbrowserplugin.plugin/Contents/Resources/
|
223
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/npgtpo3dautoplugin.plugin/
|
224
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/
|
225
|
+
2011/02/27 20:12:20 [36835] >f+++++++ Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Info.plist
|
226
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks/
|
227
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks/Cg.framework/
|
228
|
+
2011/02/27 20:12:20 [36835] cL+++++++ Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks/Cg.framework/Cg -> Versions/Current/Cg
|
229
|
+
2011/02/27 20:12:20 [36835] cL+++++++ Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks/Cg.framework/Resources -> Versions/Current/Resources
|
230
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks/Cg.framework/Versions/
|
231
|
+
2011/02/27 20:12:20 [36835] cL+++++++ Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks/Cg.framework/Versions/Current -> 1.0
|
232
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks/Cg.framework/Versions/1.0/
|
233
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/MacOS/
|
234
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Resources/
|
235
|
+
2011/02/27 20:12:20 [36835] cd+++++++ Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Resources/English.lproj/
|
236
|
+
2011/02/27 20:12:20 [36835] cd+++++++ QuickTime/
|
237
|
+
2011/02/27 20:12:20 [36835] cd+++++++ QuickTime/Google Camera Adapter 0.component/
|
238
|
+
2011/02/27 20:12:20 [36835] cd+++++++ QuickTime/Google Camera Adapter 0.component/Contents/
|
239
|
+
2011/02/27 20:12:20 [36835] cd+++++++ QuickTime/Google Camera Adapter 0.component/Contents/MacOS/
|
240
|
+
2011/02/27 20:12:20 [36835] cd+++++++ QuickTime/Google Camera Adapter 0.component/Contents/Resources/
|
241
|
+
2011/02/27 20:12:20 [36835] cd+++++++ QuickTime/Google Camera Adapter 1.component/
|
242
|
+
2011/02/27 20:12:20 [36835] cd+++++++ QuickTime/Google Camera Adapter 1.component/Contents/
|
243
|
+
2011/02/27 20:12:20 [36835] >f+++++++ QuickTime/Google Camera Adapter 1.component/Contents/Info.plist
|
244
|
+
2011/02/27 20:12:20 [36835] cd+++++++ QuickTime/Google Camera Adapter 1.component/Contents/MacOS/
|
245
|
+
2011/02/27 20:12:20 [36835] cd+++++++ QuickTime/Google Camera Adapter 1.component/Contents/Resources/
|
246
|
+
2011/02/27 20:12:20 [36835] sent 386 bytes received 1431 bytes total size 5229466
|
247
|
+
'
|
248
|
+
|
249
|
+
@changes = [
|
250
|
+
"Application Support",
|
251
|
+
"Application Support/Google",
|
252
|
+
"Application Support/Google/GoogleTalkPlugin.app",
|
253
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents",
|
254
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks",
|
255
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework",
|
256
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/GoogleBreakpad -> Versions/Current/GoogleBreakpad",
|
257
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Resources -> Versions/Current/Resources",
|
258
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Versions",
|
259
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Versions/A",
|
260
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Versions/A/Resources",
|
261
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Versions/A/Resources/Reporter.app",
|
262
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Versions/A/Resources/Reporter.app/Contents",
|
263
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents/Frameworks/GoogleBreakpad.framework/Versions/Current -> A",
|
264
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents/Info.plist",
|
265
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents/MacOS",
|
266
|
+
"Application Support/Google/GoogleTalkPlugin.app/Contents/MacOS/GoogleTalkPlugin",
|
267
|
+
"Internet Plug-Ins",
|
268
|
+
"Internet Plug-Ins/googletalkbrowserplugin.plugin",
|
269
|
+
"Internet Plug-Ins/googletalkbrowserplugin.plugin/Contents",
|
270
|
+
"Internet Plug-Ins/googletalkbrowserplugin.plugin/Contents/MacOS",
|
271
|
+
"Internet Plug-Ins/googletalkbrowserplugin.plugin/Contents/MacOS/googletalkbrowserplugin",
|
272
|
+
"Internet Plug-Ins/googletalkbrowserplugin.plugin/Contents/Resources",
|
273
|
+
"Internet Plug-Ins/npgtpo3dautoplugin.plugin",
|
274
|
+
"Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents",
|
275
|
+
"Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks",
|
276
|
+
"Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks/Cg.framework",
|
277
|
+
"Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks/Cg.framework/Cg -> Versions/Current/Cg",
|
278
|
+
"Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks/Cg.framework/Resources -> Versions/Current/Resources",
|
279
|
+
"Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks/Cg.framework/Versions",
|
280
|
+
"Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks/Cg.framework/Versions/1.0",
|
281
|
+
"Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Frameworks/Cg.framework/Versions/Current -> 1.0",
|
282
|
+
"Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Info.plist",
|
283
|
+
"Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/MacOS",
|
284
|
+
"Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Resources",
|
285
|
+
"Internet Plug-Ins/npgtpo3dautoplugin.plugin/Contents/Resources/English.lproj",
|
286
|
+
"QuickTime",
|
287
|
+
"QuickTime/Google Camera Adapter 0.component",
|
288
|
+
"QuickTime/Google Camera Adapter 0.component/Contents",
|
289
|
+
"QuickTime/Google Camera Adapter 0.component/Contents/MacOS",
|
290
|
+
"QuickTime/Google Camera Adapter 0.component/Contents/Resources",
|
291
|
+
"QuickTime/Google Camera Adapter 1.component",
|
292
|
+
"QuickTime/Google Camera Adapter 1.component/Contents",
|
293
|
+
"QuickTime/Google Camera Adapter 1.component/Contents/Info.plist",
|
294
|
+
"QuickTime/Google Camera Adapter 1.component/Contents/MacOS",
|
295
|
+
"QuickTime/Google Camera Adapter 1.component/Contents/Resources",
|
296
|
+
]
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'should work without arguments' do
|
300
|
+
lambda { rsync_changes }.should.not.raise(ArgumentError)
|
301
|
+
end
|
302
|
+
|
303
|
+
it 'should not allow arguments' do
|
304
|
+
lambda { rsync_changes(:foo) }.should.raise(ArgumentError)
|
305
|
+
end
|
306
|
+
|
307
|
+
it 'should return nil when an rsync changes file cannot be found' do
|
308
|
+
self.stub!(:read_rsync_changes_file).and_raise
|
309
|
+
rsync_changes.should.be.nil
|
310
|
+
end
|
311
|
+
|
312
|
+
it 'should return an empty list if no files are found in the rsync changes file' do
|
313
|
+
self.stub!(:read_rsync_changes_file).and_return('')
|
314
|
+
rsync_changes.should == []
|
315
|
+
end
|
316
|
+
|
317
|
+
it 'should return a list of all changed filenames mentioned in the rsync changes file, excluding "."' do
|
318
|
+
self.stub!(:read_rsync_changes_file).and_return(@contents)
|
319
|
+
rsync_changes.sort.first.should == @changes.sort.first
|
320
|
+
end
|
321
|
+
end
|
322
|
+
|
323
|
+
describe 'when reading the git-related changes for a deployment' do
|
324
|
+
before do
|
325
|
+
@contents = 'git changes'
|
326
|
+
@changes_path = '/path/to/git/changes'
|
327
|
+
self.stub!(:git_changes_path).and_return(@changes_path)
|
328
|
+
File.stub!(:read).with(@changes_path).and_return(@contents)
|
329
|
+
end
|
330
|
+
|
331
|
+
it 'should work without arguments' do
|
332
|
+
lambda { read_git_changes_file }.should.not.raise(ArgumentError)
|
333
|
+
end
|
334
|
+
|
335
|
+
it 'should not allow arguments' do
|
336
|
+
lambda { read_git_changes_file(:foo) }.should.raise(ArgumentError)
|
337
|
+
end
|
338
|
+
|
339
|
+
it 'should read the git changes file' do
|
340
|
+
File.should.receive(:read) do |arg|
|
341
|
+
arg.should == @changes_path
|
342
|
+
@contents
|
343
|
+
end
|
344
|
+
read_git_changes_file
|
345
|
+
end
|
346
|
+
|
347
|
+
it 'should return the contents of the git changes file' do
|
348
|
+
read_git_changes_file.should == @contents
|
349
|
+
end
|
350
|
+
|
351
|
+
it 'should fail if the git changes file cannot be read' do
|
352
|
+
File.stub!(:read).with(@changes_path).and_raise(Errno::ENOENT)
|
353
|
+
lambda { read_git_changes_file }.should.raise(Errno::ENOENT)
|
354
|
+
end
|
355
|
+
end
|
356
|
+
|
357
|
+
describe 'when reading the rsync-related changes for a deployment' do
|
358
|
+
before do
|
359
|
+
@contents = 'rsync changes'
|
360
|
+
@changes_path = '/path/to/rsync/changes'
|
361
|
+
self.stub!(:rsync_changes_path).and_return(@changes_path)
|
362
|
+
File.stub!(:read).with(@changes_path).and_return(@contents)
|
363
|
+
end
|
364
|
+
|
365
|
+
it 'should work without arguments' do
|
366
|
+
lambda { read_rsync_changes_file }.should.not.raise(ArgumentError)
|
367
|
+
end
|
368
|
+
|
369
|
+
it 'should not allow arguments' do
|
370
|
+
lambda { read_rsync_changes_file(:foo) }.should.raise(ArgumentError)
|
371
|
+
end
|
372
|
+
|
373
|
+
it 'should read the rsync changes file' do
|
374
|
+
File.should.receive(:read) do |arg|
|
375
|
+
arg.should == @changes_path
|
376
|
+
@contents
|
377
|
+
end
|
378
|
+
read_rsync_changes_file
|
379
|
+
end
|
380
|
+
|
381
|
+
it 'should return the contents of the rsync changes file' do
|
382
|
+
read_rsync_changes_file.should == @contents
|
383
|
+
end
|
384
|
+
|
385
|
+
it 'should fail if the rsync changes file cannot be read' do
|
386
|
+
File.stub!(:read).with(@changes_path).and_raise(Errno::ENOENT)
|
387
|
+
lambda { read_rsync_changes_file }.should.raise(Errno::ENOENT)
|
388
|
+
end
|
389
|
+
end
|
390
|
+
|
391
|
+
describe 'computing the path to the git changes file' do
|
392
|
+
before do
|
393
|
+
@git_path = '/path/to/toplevel'
|
394
|
+
@io_handle = ''
|
395
|
+
IO.stub!(:popen).with("git rev-parse --show-toplevel").and_return(@io_handle)
|
396
|
+
@io_handle.stub!(:read).and_return(@git_path + "\n")
|
397
|
+
end
|
398
|
+
|
399
|
+
it 'should work without arguments' do
|
400
|
+
lambda { git_changes_path }.should.not.raise(ArgumentError)
|
401
|
+
end
|
402
|
+
|
403
|
+
it 'should not allow arguments' do
|
404
|
+
lambda { git_changes_path(:foo) }.should.raise(ArgumentError)
|
405
|
+
end
|
406
|
+
|
407
|
+
it 'should return the path to the .whiskey_disk_git_changes file in the git top-level path' do
|
408
|
+
git_changes_path.should == File.join(@git_path, '.whiskey_disk_git_changes')
|
409
|
+
end
|
410
|
+
|
411
|
+
it 'should return the path to the .whiskey_disk_git_changes file in the current directory of the git top-level cannot be found' do
|
412
|
+
@io_handle.stub!(:read).and_return('')
|
413
|
+
git_changes_path.should == File.join(Dir.pwd, '.whiskey_disk_git_changes')
|
414
|
+
end
|
415
|
+
end
|
416
|
+
|
417
|
+
describe 'computing the path to the rsync changes file' do
|
418
|
+
before do
|
419
|
+
@rsync_path = '/path/to/toplevel'
|
420
|
+
@io_handle = ''
|
421
|
+
IO.stub!(:popen).with("git rev-parse --show-toplevel").and_return(@io_handle)
|
422
|
+
@io_handle.stub!(:read).and_return(@rsync_path + "\n")
|
423
|
+
end
|
424
|
+
|
425
|
+
it 'should work without arguments' do
|
426
|
+
lambda { rsync_changes_path }.should.not.raise(ArgumentError)
|
427
|
+
end
|
428
|
+
|
429
|
+
it 'should not allow arguments' do
|
430
|
+
lambda { rsync_changes_path(:foo) }.should.raise(ArgumentError)
|
431
|
+
end
|
432
|
+
|
433
|
+
it 'should return the path to the .whiskey_disk_rsync_changes file in the git top-level path' do
|
434
|
+
rsync_changes_path.should == File.join(@rsync_path, '.whiskey_disk_rsync_changes')
|
435
|
+
end
|
436
|
+
|
437
|
+
it 'should return the path to the .whiskey_disk_rsync_changes file in the current directory of the git top-level cannot be found' do
|
438
|
+
@io_handle.stub!(:read).and_return('')
|
439
|
+
rsync_changes_path.should == File.join(Dir.pwd, '.whiskey_disk_rsync_changes')
|
440
|
+
end
|
441
|
+
end
|
@@ -24,6 +24,7 @@ describe 'rake tasks' do
|
|
24
24
|
:update_main_repository_checkout,
|
25
25
|
:update_configuration_repository_checkout,
|
26
26
|
:refresh_configuration,
|
27
|
+
:initialize_all_changes,
|
27
28
|
:run_post_setup_hooks,
|
28
29
|
:flush,
|
29
30
|
:summarize
|
@@ -87,6 +88,11 @@ describe 'rake tasks' do
|
|
87
88
|
end
|
88
89
|
end
|
89
90
|
|
91
|
+
it 'should clear any tracked git or rsync changes' do
|
92
|
+
WhiskeyDisk.should.receive(:initialize_all_changes)
|
93
|
+
@rake["deploy:setup"].invoke
|
94
|
+
end
|
95
|
+
|
90
96
|
describe 'when no configuration repository is specified' do
|
91
97
|
it 'should update the configuration repository checkout' do
|
92
98
|
WhiskeyDisk.should.not.receive(:update_configuration_repository_checkout)
|
data/spec/whiskey_disk_spec.rb
CHANGED
@@ -221,9 +221,14 @@ describe 'WhiskeyDisk' do
|
|
221
221
|
WhiskeyDisk.buffer.join(' ').should.match(%r{git checkout -b master origin/master})
|
222
222
|
end
|
223
223
|
|
224
|
+
it 'should fall back to a regular checkout of the master branch with origin branch when no branch is specified' do
|
225
|
+
WhiskeyDisk.checkout_main_repository
|
226
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{\|\| git checkout master origin/master})
|
227
|
+
end
|
228
|
+
|
224
229
|
it 'should fall back to a regular checkout of the master branch when no branch is specified' do
|
225
230
|
WhiskeyDisk.checkout_main_repository
|
226
|
-
WhiskeyDisk.buffer.join(' ').should.match(%r{\|\| git checkout master})
|
231
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{\|\| git checkout master origin/master \|\| git checkout master})
|
227
232
|
end
|
228
233
|
|
229
234
|
it 'should do a branch creation checkout of the specified branch when a branch is specified' do
|
@@ -232,10 +237,16 @@ describe 'WhiskeyDisk' do
|
|
232
237
|
WhiskeyDisk.buffer.join(' ').should.match(%r{git checkout -b production origin/production})
|
233
238
|
end
|
234
239
|
|
240
|
+
it 'should fall back to a regular checkout of the specified branch with origin branch when a branch is specified' do
|
241
|
+
WhiskeyDisk.configuration = @parameters.merge({'branch' => 'production'})
|
242
|
+
WhiskeyDisk.checkout_main_repository
|
243
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{\|\| git checkout production origin/production})
|
244
|
+
end
|
245
|
+
|
235
246
|
it 'should fall back to a regular checkout of the specified branch when a branch is specified' do
|
236
247
|
WhiskeyDisk.configuration = @parameters.merge({'branch' => 'production'})
|
237
248
|
WhiskeyDisk.checkout_main_repository
|
238
|
-
WhiskeyDisk.buffer.join(' ').should.match(%r{\|\| git checkout production})
|
249
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{\|\| git checkout production origin/production \|\| git checkout production})
|
239
250
|
end
|
240
251
|
|
241
252
|
it 'should do branch checkouts from the repository path' do
|
@@ -280,11 +291,34 @@ describe 'WhiskeyDisk' do
|
|
280
291
|
WhiskeyDisk.buffer.join(' ').should.match(%r{git checkout -b master origin/master})
|
281
292
|
end
|
282
293
|
|
294
|
+
it 'should fall back to a regular checkout of the master branch with origin branch when no branch is specified' do
|
295
|
+
WhiskeyDisk.checkout_configuration_repository
|
296
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{\|\| git checkout master origin/master})
|
297
|
+
end
|
298
|
+
|
299
|
+
it 'should fall back to a regular checkout of the master branch when no branch is specified' do
|
300
|
+
WhiskeyDisk.checkout_configuration_repository
|
301
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{\|\| git checkout master origin/master \|\| git checkout master})
|
302
|
+
end
|
303
|
+
|
283
304
|
it 'should do a branch creation checkout of the specified branch when a branch is specified' do
|
284
305
|
WhiskeyDisk.configuration = @parameters.merge({'config_branch' => 'production'})
|
285
306
|
WhiskeyDisk.checkout_configuration_repository
|
286
307
|
WhiskeyDisk.buffer.join(' ').should.match(%r{git checkout -b production origin/production})
|
287
308
|
end
|
309
|
+
|
310
|
+
it 'should fall back to a regular checkout of the specified branch with origin branch when a branch is specified' do
|
311
|
+
WhiskeyDisk.configuration = @parameters.merge({'config_branch' => 'production'})
|
312
|
+
WhiskeyDisk.checkout_configuration_repository
|
313
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{\|\| git checkout production origin/production})
|
314
|
+
end
|
315
|
+
|
316
|
+
it 'should fall back to a regular checkout of the specified branch when a branch is specified' do
|
317
|
+
WhiskeyDisk.configuration = @parameters.merge({'config_branch' => 'production'})
|
318
|
+
WhiskeyDisk.checkout_configuration_repository
|
319
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{\|\| git checkout production origin/production \|\| git checkout production})
|
320
|
+
end
|
321
|
+
|
288
322
|
end
|
289
323
|
|
290
324
|
describe 'updating the main repository checkout' do
|
@@ -303,15 +337,20 @@ describe 'WhiskeyDisk' do
|
|
303
337
|
WhiskeyDisk.buffer.join(' ').should.match(%r{cd /path/to/main/repo})
|
304
338
|
end
|
305
339
|
|
306
|
-
it 'should
|
340
|
+
it 'should clear out any existing git changes data' do
|
307
341
|
WhiskeyDisk.update_main_repository_checkout
|
308
|
-
WhiskeyDisk.buffer.join(' ').should.match(%r{
|
342
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{rm -f /path/to/main/repo/.whiskey_disk_git_changes})
|
309
343
|
end
|
310
|
-
|
311
|
-
it 'should
|
344
|
+
|
345
|
+
it 'should capture the current git HEAD ref for the specified branch' do
|
312
346
|
WhiskeyDisk.configuration = @parameters.merge({'branch' => 'production'})
|
313
347
|
WhiskeyDisk.update_main_repository_checkout
|
314
|
-
WhiskeyDisk.buffer.join(' ').should.match(%r{git
|
348
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{ml=\`cat .git/refs/heads/production\`})
|
349
|
+
end
|
350
|
+
|
351
|
+
it 'should capture the current git HEAD ref for the master branch if no branch is specified' do
|
352
|
+
WhiskeyDisk.update_main_repository_checkout
|
353
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{ml=\`cat .git/refs/heads/master\`})
|
315
354
|
end
|
316
355
|
|
317
356
|
it 'should attempt to fetch only the master branch from the origin if no branch is specified' do
|
@@ -325,6 +364,17 @@ describe 'WhiskeyDisk' do
|
|
325
364
|
WhiskeyDisk.buffer.join(' ').should.match(%r{git fetch origin \+refs/heads/production:refs/remotes/origin/production})
|
326
365
|
end
|
327
366
|
|
367
|
+
it 'should work from the default branch if no branch is specified' do
|
368
|
+
WhiskeyDisk.update_main_repository_checkout
|
369
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{git checkout master})
|
370
|
+
end
|
371
|
+
|
372
|
+
it 'should work from the specified branch if one is specified' do
|
373
|
+
WhiskeyDisk.configuration = @parameters.merge({'branch' => 'production'})
|
374
|
+
WhiskeyDisk.update_main_repository_checkout
|
375
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{git checkout production})
|
376
|
+
end
|
377
|
+
|
328
378
|
it 'should attempt to reset the master branch from the origin if no branch is specified' do
|
329
379
|
WhiskeyDisk.update_main_repository_checkout
|
330
380
|
WhiskeyDisk.buffer.join(' ').should.match(%r{git reset --hard origin/master})
|
@@ -335,11 +385,16 @@ describe 'WhiskeyDisk' do
|
|
335
385
|
WhiskeyDisk.update_main_repository_checkout
|
336
386
|
WhiskeyDisk.buffer.join(' ').should.match(%r{git reset --hard origin/production})
|
337
387
|
end
|
388
|
+
|
389
|
+
it 'should collect git changes data' do
|
390
|
+
WhiskeyDisk.update_main_repository_checkout
|
391
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{git diff --name-only \$\{ml\}\.\.HEAD > /path/to/main/repo/\.whiskey_disk_git_changes})
|
392
|
+
end
|
338
393
|
end
|
339
394
|
|
340
395
|
describe 'updating the configuration repository checkout' do
|
341
396
|
before do
|
342
|
-
@parameters = { 'deploy_config_to' => '/path/to/config/repo' }
|
397
|
+
@parameters = { 'deploy_config_to' => '/path/to/config/repo', 'deploy_to' => '/path/to/main/repo' }
|
343
398
|
WhiskeyDisk.configuration = @parameters
|
344
399
|
end
|
345
400
|
|
@@ -353,6 +408,11 @@ describe 'WhiskeyDisk' do
|
|
353
408
|
WhiskeyDisk.buffer.join(' ').should.match(%r{cd /path/to/config/repo})
|
354
409
|
end
|
355
410
|
|
411
|
+
it 'should clear out any existing rsync changes data' do
|
412
|
+
WhiskeyDisk.update_configuration_repository_checkout
|
413
|
+
WhiskeyDisk.buffer.join(' ').should.match(%r{rm -f /path/to/main/repo/.whiskey_disk_rsync_changes})
|
414
|
+
end
|
415
|
+
|
356
416
|
it 'should attempt to fetch only the master branch from the origin if no configuration branch is specified' do
|
357
417
|
WhiskeyDisk.update_configuration_repository_checkout
|
358
418
|
WhiskeyDisk.buffer.join(' ').should.match(%r{git fetch origin \+refs/heads/master:refs/remotes/origin/master})
|
@@ -407,6 +467,11 @@ describe 'WhiskeyDisk' do
|
|
407
467
|
WhiskeyDisk.refresh_configuration
|
408
468
|
WhiskeyDisk.buffer.last.should.match(%r{rsync.* /path/to/config/repo/whiskey_disk/staging/ /path/to/main/repo/})
|
409
469
|
end
|
470
|
+
|
471
|
+
it 'should capture rsync change data' do
|
472
|
+
WhiskeyDisk.refresh_configuration
|
473
|
+
WhiskeyDisk.buffer.last.should.match(%r{rsync.* --log-file=/path/to/main/repo/.whiskey_disk_rsync_changes })
|
474
|
+
end
|
410
475
|
end
|
411
476
|
|
412
477
|
describe 'running post setup hooks' do
|
@@ -931,6 +996,7 @@ describe 'WhiskeyDisk' do
|
|
931
996
|
@domain = { :name => @domain_name }
|
932
997
|
WhiskeyDisk.configuration = { 'domain' => [ @domain ] }
|
933
998
|
WhiskeyDisk.stub!(:system)
|
999
|
+
WhiskeyDisk.stub!(:puts)
|
934
1000
|
end
|
935
1001
|
|
936
1002
|
it 'should accept a domain and a command string' do
|
@@ -980,6 +1046,7 @@ describe 'WhiskeyDisk' do
|
|
980
1046
|
@domain = { :name => @domain_name }
|
981
1047
|
WhiskeyDisk.configuration = { 'domain' => [ @domain ] }
|
982
1048
|
WhiskeyDisk.stub!(:system)
|
1049
|
+
WhiskeyDisk.stub!(:puts)
|
983
1050
|
end
|
984
1051
|
|
985
1052
|
it 'should accept a domain and a command string' do
|
data/whiskey_disk.gemspec
CHANGED
@@ -5,11 +5,11 @@
|
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = %q{whiskey_disk}
|
8
|
-
s.version = "0.6.
|
8
|
+
s.version = "0.6.20"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Rick Bradley"]
|
12
|
-
s.date = %q{2011-
|
12
|
+
s.date = %q{2011-04-06}
|
13
13
|
s.description = %q{Opinionated gem for doing fast git-based server deployments.}
|
14
14
|
s.email = %q{rick@rickbradley.com}
|
15
15
|
s.executables = ["wd_role", "wd"]
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: whiskey_disk
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 47
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 0.6.
|
9
|
+
- 20
|
10
|
+
version: 0.6.20
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Rick Bradley
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-
|
18
|
+
date: 2011-04-06 00:00:00 -05:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|