rubycut-babushka 0.10.8 → 0.15.6.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (142) hide show
  1. data/Gemfile +1 -0
  2. data/Gemfile.lock +17 -15
  3. data/README.markdown +163 -41
  4. data/Rakefile +1 -1
  5. data/bin/babushka +1 -1
  6. data/deps/apt.rb +44 -0
  7. data/deps/babushka.rb +54 -42
  8. data/deps/deprecated.rb +16 -0
  9. data/deps/dev.rb +28 -3
  10. data/deps/git.rb +27 -12
  11. data/deps/homebrew.rb +2 -2
  12. data/deps/packages.rb +14 -15
  13. data/deps/pkg_managers.rb +21 -75
  14. data/deps/ruby.rb +5 -19
  15. data/deps/rubygems.rb +3 -3
  16. data/deps/system.rb +2 -2
  17. data/deps/templates/app.rb +60 -41
  18. data/deps/templates/bin.rb +16 -0
  19. data/deps/templates/installer.rb +9 -9
  20. data/deps/templates/lib.rb +17 -0
  21. data/deps/templates/managed.rb +1 -38
  22. data/deps/templates/src.rb +16 -8
  23. data/deps/templates/task.rb +11 -0
  24. data/deps/templates/tmbundle.rb +16 -2
  25. data/lib/babushka.rb +2 -3
  26. data/lib/babushka/accepts_block_for.rb +5 -3
  27. data/lib/babushka/asset.rb +172 -0
  28. data/lib/babushka/base.rb +37 -8
  29. data/lib/babushka/bug_reporter.rb +6 -6
  30. data/lib/babushka/cmdline.rb +11 -10
  31. data/lib/babushka/cmdline/handler.rb +7 -3
  32. data/lib/babushka/cmdline/helpers.rb +15 -23
  33. data/lib/babushka/cmdline/parser.rb +1 -1
  34. data/lib/babushka/core_patches/object.rb +1 -1
  35. data/lib/babushka/core_patches/string.rb +8 -3
  36. data/lib/babushka/current_ruby.rb +44 -0
  37. data/lib/babushka/dep.rb +111 -185
  38. data/lib/babushka/dep_context.rb +8 -3
  39. data/lib/babushka/dep_definer.rb +45 -15
  40. data/lib/babushka/dep_pool.rb +5 -8
  41. data/lib/babushka/{meta_dep.rb → dep_template.rb} +21 -2
  42. data/lib/babushka/dsl.rb +3 -0
  43. data/lib/babushka/git_repo.rb +143 -49
  44. data/lib/babushka/helpers/git_helpers.rb +7 -6
  45. data/lib/babushka/helpers/log_helpers.rb +51 -13
  46. data/lib/babushka/helpers/path_helpers.rb +5 -7
  47. data/lib/babushka/helpers/run_helpers.rb +15 -55
  48. data/lib/babushka/helpers/shell_helpers.rb +18 -26
  49. data/lib/babushka/helpers/uri_helpers.rb +9 -18
  50. data/lib/babushka/lambda_chooser.rb +20 -13
  51. data/lib/babushka/parameter.rb +20 -4
  52. data/lib/babushka/path_checker.rb +72 -0
  53. data/lib/babushka/pkg_helper.rb +38 -13
  54. data/lib/babushka/pkg_helpers/apt_helper.rb +15 -8
  55. data/lib/babushka/pkg_helpers/binpkgsrc_helper.rb +15 -14
  56. data/lib/babushka/pkg_helpers/binports_helper.rb +7 -7
  57. data/lib/babushka/pkg_helpers/brew_helper.rb +17 -25
  58. data/lib/babushka/pkg_helpers/gem_helper.rb +36 -27
  59. data/lib/babushka/pkg_helpers/npm_helper.rb +9 -9
  60. data/lib/babushka/pkg_helpers/pacman_helper.rb +5 -4
  61. data/lib/babushka/pkg_helpers/pip_helper.rb +14 -10
  62. data/lib/babushka/pkg_helpers/unknown_pkg_helper.rb +19 -0
  63. data/lib/babushka/pkg_helpers/yum_helper.rb +1 -1
  64. data/lib/babushka/popen.rb +13 -10
  65. data/lib/babushka/prompt.rb +14 -1
  66. data/lib/babushka/renderable.rb +11 -9
  67. data/lib/babushka/resource.rb +5 -166
  68. data/lib/babushka/run_reporter.rb +12 -3
  69. data/lib/babushka/shell.rb +54 -44
  70. data/lib/babushka/source.rb +41 -20
  71. data/lib/babushka/source_pool.rb +20 -13
  72. data/lib/babushka/system_definitions.rb +11 -3
  73. data/lib/babushka/system_detector.rb +31 -0
  74. data/lib/babushka/system_matcher.rb +53 -0
  75. data/lib/babushka/system_profile.rb +67 -89
  76. data/lib/babushka/task.rb +36 -8
  77. data/lib/babushka/{meta_dep_context.rb → templated_dep_context.rb} +1 -1
  78. data/lib/babushka/vars.rb +46 -4
  79. data/lib/babushka/version_of.rb +35 -17
  80. data/lib/babushka/version_str.rb +12 -8
  81. data/lib/components.rb +9 -8
  82. data/lib/fancypath/fancypath.rb +109 -83
  83. data/lib/inkan/inkan.rb +14 -14
  84. data/lib/{babushka → levenshtein}/levenshtein.rb +0 -0
  85. data/spec/acceptance/acceptance.rb +4 -4
  86. data/spec/acceptance_helper.rb +10 -6
  87. data/spec/babushka/accepts_for_spec.rb +137 -142
  88. data/spec/babushka/accepts_for_support.rb +13 -6
  89. data/spec/babushka/asset_spec.rb +165 -0
  90. data/spec/babushka/cmdline/help_spec.rb +11 -9
  91. data/spec/babushka/cmdline/meet_spec.rb +15 -0
  92. data/spec/babushka/cmdline/version_spec.rb +1 -1
  93. data/spec/babushka/core_patches_spec.rb +9 -0
  94. data/spec/babushka/current_ruby_spec.rb +73 -0
  95. data/spec/babushka/dep_context_spec.rb +27 -13
  96. data/spec/babushka/dep_definer_spec.rb +108 -16
  97. data/spec/babushka/dep_spec.rb +87 -104
  98. data/spec/babushka/dep_template_spec.rb +176 -0
  99. data/spec/babushka/deps_spec.rb +48 -19
  100. data/spec/babushka/gem_helper_spec.rb +46 -59
  101. data/spec/babushka/git_repo_spec.rb +242 -51
  102. data/spec/babushka/ip_spec.rb +11 -11
  103. data/spec/babushka/lambda_chooser_spec.rb +47 -9
  104. data/spec/babushka/parameter_spec.rb +21 -0
  105. data/spec/babushka/path_checker_spec.rb +35 -0
  106. data/spec/babushka/path_helpers_spec.rb +51 -50
  107. data/spec/babushka/prompt_spec.rb +4 -4
  108. data/spec/babushka/renderable_spec.rb +61 -28
  109. data/spec/babushka/shell_helpers_spec.rb +110 -85
  110. data/spec/babushka/shell_spec.rb +15 -0
  111. data/spec/babushka/source_pool_spec.rb +204 -210
  112. data/spec/babushka/source_spec.rb +125 -42
  113. data/spec/babushka/source_support.rb +1 -1
  114. data/spec/babushka/system_profile_spec.rb +86 -49
  115. data/spec/babushka/task_spec.rb +80 -13
  116. data/spec/babushka/vars_spec.rb +2 -1
  117. data/spec/babushka/version_of_spec.rb +29 -2
  118. data/spec/babushka/version_str_spec.rb +91 -65
  119. data/spec/babushka/xml_string_spec.rb +1 -1
  120. data/spec/deps/bad/broken.rb +2 -2
  121. data/spec/deps/bad/working.rb +0 -1
  122. data/spec/deps/good/{meta.rb → template.rb} +0 -0
  123. data/spec/deps/good/test.rb +0 -3
  124. data/spec/deps/outer/deps.rb +0 -2
  125. data/spec/fancypath/fancypath_spec.rb +30 -0
  126. data/spec/inkan/inkan_spec.rb +34 -32
  127. data/spec/spec_helper.rb +7 -50
  128. data/spec/system_detector_spec.rb +70 -0
  129. metadata +163 -177
  130. data/deps/os_x.rb +0 -33
  131. data/deps/templates/ppa.rb +0 -24
  132. data/lib/babushka/core_patches/io.rb +0 -8
  133. data/lib/babushka/dep_runner.rb +0 -85
  134. data/lib/babushka/helpers/suggest_helpers.rb +0 -16
  135. data/lib/babushka/pkg_helpers/base_helper.rb +0 -19
  136. data/lib/babushka/pkg_helpers/macports_helper.rb +0 -22
  137. data/spec/babushka/dep_definer_support.rb +0 -36
  138. data/spec/babushka/meta_dep_definer_spec.rb +0 -127
  139. data/spec/babushka/meta_dep_wrapper_spec.rb +0 -32
  140. data/spec/babushka/resource_spec.rb +0 -141
  141. data/spec/babushka/run_helpers_spec.rb +0 -26
  142. data/spec/babushka/source_pool_support.rb +0 -31
@@ -19,22 +19,20 @@ describe Source do
19
19
  it "should label nil paths as implicit" do
20
20
  Source.discover_uri_and_type(nil).should == [nil, :implicit]
21
21
  end
22
- it "should treat URLs containing auth info as private" do
22
+ it "should treat git:// as public" do
23
23
  [
24
- 'http://ben@server.org/benhoskings/babushka.git',
25
- 'https://ben:secret@server.org/benhoskings/babushka.git'
24
+ 'git://github.com/benhoskings/babushka-deps.git',
26
25
  ].each {|uri|
27
- Source.discover_uri_and_type(uri).should == [uri, :private]
26
+ Source.discover_uri_and_type(uri).should == [uri, :public]
28
27
  }
29
28
  end
30
- it "should treat git:// and friends as public" do
29
+ it "should treat other protocols as private" do
31
30
  [
32
- 'git://github.com/benhoskings/babushka-deps.git',
33
31
  'http://github.com/benhoskings/babushka-deps.git',
34
32
  'https://github.com/benhoskings/babushka-deps.git',
35
33
  'file:///Users/ben/babushka/deps'
36
34
  ].each {|uri|
37
- Source.discover_uri_and_type(uri).should == [uri, :public]
35
+ Source.discover_uri_and_type(uri).should == [uri, :private]
38
36
  }
39
37
  end
40
38
  it "should treat ssh-style URLs as private" do
@@ -96,6 +94,52 @@ describe Source do
96
94
  end
97
95
  end
98
96
 
97
+ describe Source, '#cloneable?' do
98
+ it "should work for implicit sources" do
99
+ Source.new(nil).should_not be_cloneable
100
+ end
101
+ it "should work for local sources" do
102
+ Source.new('~/.babushka/deps').should_not be_cloneable
103
+ end
104
+ it "should work for public sources" do
105
+ Source.new('git://github.com/benhoskings/babushka-deps.git').should be_cloneable
106
+ end
107
+ it "should work for private sources" do
108
+ Source.new('git@github.com:benhoskings/babushka-deps.git').should be_cloneable
109
+ end
110
+ end
111
+
112
+ describe "#cloned?" do
113
+ it "should return false for implicit sources" do
114
+ Source.new(nil).should_not be_cloned
115
+ end
116
+ it "should return false for local sources" do
117
+ Source.new(nil).should_not be_cloned
118
+ end
119
+ context "for cloneable repos" do
120
+ subject { Source.new(*@remote_2) }
121
+ it "should not be cloned" do
122
+ subject.should_not be_cloned
123
+ end
124
+ it "should be cloned after loading" do
125
+ subject.load!
126
+ subject.should be_cloned
127
+ end
128
+ after {
129
+ subject.path.rm
130
+ }
131
+ end
132
+ end
133
+
134
+ describe '#clear!' do
135
+ let(:source) { Source.new(nil) }
136
+ it "should clear the deps and templates" do
137
+ source.deps.should_receive(:clear!)
138
+ source.templates.should_receive(:clear!)
139
+ source.clear!
140
+ end
141
+ end
142
+
99
143
  describe "loading deps" do
100
144
  context "with a good source" do
101
145
  before {
@@ -108,7 +152,7 @@ describe Source do
108
152
  end
109
153
  it "should not have defined the deps" do
110
154
  dep = @source.deps.for('test dep 1')
111
- dep.dep_defined?.should be_false
155
+ dep.context.should_not be_loaded
112
156
  end
113
157
  it "should store the source the dep was loaded from" do
114
158
  @source.deps.for('test dep 1').dep_source.should == @source
@@ -117,23 +161,22 @@ describe Source do
117
161
  context "with a source with errors" do
118
162
  before {
119
163
  @source = Source.new('spec/deps/bad')
120
- @source.load!
121
164
  }
122
- it "should recover from load errors" do
123
- @source.deps.names.should include('broken test dep 1')
124
- @source.deps.names.should include('test dep 1')
165
+ it "should raise an error" do
166
+ expect { @source.load! }.to raise_error(Babushka::SourceLoadError)
167
+ @source.deps.count.should == 0
125
168
  end
126
169
  end
127
170
  end
128
171
 
129
172
  describe "loading deps with parameters" do
130
173
  let(:source) { Source.new('spec/deps/params').tap(&:load!) }
131
- let(:requires) { source.deps.for('top-level dep with params').context.requires }
174
+ let(:requires) { source.deps.for('top-level dep with params').context.define!.requires }
132
175
  it "should store the right number of requirements" do
133
176
  requires.length.should == 2
134
177
  end
135
178
  it "should store the right kinds of objects" do
136
- requires.map(&:class).should == [String, Babushka::Dep::Requirement]
179
+ requires.map(&:class).should == [String, Babushka::DepRequirement]
137
180
  end
138
181
  it "should store string requirements properly" do
139
182
  requires.first.should == 'a dep without params'
@@ -165,7 +208,7 @@ describe Source do
165
208
  @dep = @source.deps.for('test dep 1')
166
209
  }
167
210
  it "should not have defined the deps" do
168
- @dep.dep_defined?.should == nil
211
+ @dep.context.should_not be_loaded
169
212
  end
170
213
  end
171
214
  end
@@ -183,6 +226,7 @@ describe Source do
183
226
  end
184
227
 
185
228
  describe Source, ".for_path" do
229
+ let(:source) { Source.for_path(source_path) }
186
230
  context "on a file" do
187
231
  before {
188
232
  `mkdir -p "#{tmp_prefix / 'sources'}"`
@@ -195,39 +239,48 @@ describe Source do
195
239
  end
196
240
  end
197
241
  context "on a dir" do
242
+ let(:source_path) { tmp_prefix / 'ad_hoc_source' }
198
243
  before {
199
244
  `mkdir -p "#{tmp_prefix / 'ad_hoc_source'}"`
200
- @source = Source.for_path(tmp_prefix / 'ad_hoc_source')
201
245
  }
202
246
  it "should work on a dir" do
203
- @source.should be_present
204
- @source.path.should == tmp_prefix / 'ad_hoc_source'
205
- @source.name.should == 'ad_hoc_source'
247
+ source.should be_present
248
+ source.path.should == tmp_prefix / 'ad_hoc_source'
249
+ source.name.should == 'ad_hoc_source'
250
+ end
251
+ it "should cache the source" do
252
+ Source.for_path(source_path).object_id.should == Source.for_path(source_path).object_id
206
253
  end
207
254
  end
208
255
  context "on a git repo" do
256
+ let(:source_path) { Source.source_prefix / 'remote_1' }
209
257
  before {
210
258
  Source.new(@remote_1.first).add!
211
- @source = Source.for_path(Source.source_prefix / 'remote_1')
212
259
  }
213
260
  it "should work on a git repo" do
214
- @source.should be_present
215
- @source.path.should == Source.source_prefix / 'remote_1'
216
- @source.name.should == 'remote_1'
261
+ source.should be_present
262
+ source.path.should == Source.source_prefix / 'remote_1'
263
+ source.name.should == 'remote_1'
264
+ end
265
+ it "should cache the source" do
266
+ Source.for_path(source_path).object_id.should == Source.for_path(source_path).object_id
217
267
  end
218
- after { @source.remove! }
268
+ after { source.remove! }
219
269
  end
220
270
  context "on a git repo with a custom name" do
271
+ let(:source_path) { Source.source_prefix / 'custom_name_test' }
221
272
  before {
222
273
  Source.new(@remote_1.first, :name => 'custom_name_test').add!
223
- @source = Source.for_path(Source.source_prefix / 'custom_name_test')
224
274
  }
225
275
  it "should work on a git repo" do
226
- @source.should be_present
227
- @source.path.should == Source.source_prefix / 'custom_name_test'
228
- @source.name.should == 'custom_name_test'
276
+ source.should be_present
277
+ source.path.should == Source.source_prefix / 'custom_name_test'
278
+ source.name.should == 'custom_name_test'
229
279
  end
230
- after { @source.remove! }
280
+ it "should cache the source" do
281
+ Source.for_path(source_path).object_id.should == Source.for_path(source_path).object_id
282
+ end
283
+ after { source.remove! }
231
284
  end
232
285
  end
233
286
 
@@ -241,7 +294,7 @@ describe Source do
241
294
  @source.deps.items.include?(@source.find('test dep 1')).should be_true
242
295
  end
243
296
  it "should find the specified template" do
244
- @source.find_template('test_meta_1').should be_an_instance_of(MetaDep)
297
+ @source.find_template('test_meta_1').should be_an_instance_of(DepTemplate)
245
298
  @source.templates.items.include?(@source.find_template('test_meta_1')).should be_true
246
299
  end
247
300
  end
@@ -252,7 +305,7 @@ describe Source do
252
305
  Source.new('spec/deps/good').should be_present
253
306
  end
254
307
  it "should be false for invalid paths" do
255
- Source.new('spec/deps/nonexistent').should_not be_present
308
+ Source.new('spec/deps/missing').should_not be_present
256
309
  end
257
310
  end
258
311
  context "for remote repos" do
@@ -282,7 +335,7 @@ describe Source do
282
335
  describe "cloning" do
283
336
  context "unreadable sources" do
284
337
  before {
285
- @source = Source.new(tmp_prefix / "nonexistent.git", :name => 'unreadable')
338
+ @source = Source.new(tmp_prefix / "missing.git", :name => 'unreadable')
286
339
  @source.add!
287
340
  }
288
341
  it "shouldn't work" do
@@ -318,9 +371,8 @@ describe Source do
318
371
  @nameless = Source.new(@remote_1.first)
319
372
  }
320
373
  it "should use the basename as the name" do
321
- File.directory?(tmp_prefix / 'sources/remote_1').should be_false
374
+ GitHelpers.should_receive(:git).with(@remote_1.first, :to => (tmp_prefix / 'sources/remote_1'), :log => true)
322
375
  @nameless.add!
323
- File.directory?(tmp_prefix / 'sources/remote_1').should be_true
324
376
  end
325
377
  it "should set the name in the source" do
326
378
  @nameless.name.should == 'remote_1'
@@ -379,14 +431,45 @@ describe Source do
379
431
  end
380
432
  end
381
433
 
382
- describe "classification" do
383
- it "should treat file:// as public" do
384
- (source = Source.new(*@remote_1)).add!
385
- [source.uri, source.name, source.type].should == [@remote_1.first, 'remote_1', :public]
386
- end
387
- it "should treat local paths as local" do
388
- (source = Source.new(@remote_1.first.gsub(/^file:\/\//, ''), @remote_1.last)).add!
389
- [source.uri, source.name, source.type].should == [@remote_1.first.gsub(/^file:\/\//, ''), 'remote_1', :local]
434
+ describe "updating" do
435
+ before {
436
+ @source = Source.new(*@remote_2)
437
+ }
438
+ it "should update when the source isn't cloned" do
439
+ @source.should_receive(:update!)
440
+ @source.load!
441
+ end
442
+ it "should not update when the source is already cloned" do
443
+ @source.stub!(:cloned?).and_return(true)
444
+ @source.should_not_receive(:update!)
445
+ @source.load!
446
+ end
447
+ it "should update when the source is already cloned and update is true" do
448
+ @source.stub!(:cloned?).and_return(true)
449
+ @source.should_receive(:update!)
450
+ @source.load!(true)
451
+ end
452
+ end
453
+
454
+ describe '#remove!' do
455
+ it "should not delete a non-cloneable source" do
456
+ source = Source.new('spec/deps/good')
457
+ source.path.should_not_receive(:rm)
458
+ source.remove!
459
+ end
460
+ it "should not delete a nonexistent source" do
461
+ source = Source.new('spec/deps/nonexistent')
462
+ source.path.should_not_receive(:rm)
463
+ source.remove!
464
+ end
465
+ context 'on a cloneable source' do
466
+ let(:source) { Source.new(*@remote_2) }
467
+
468
+ it "should delete the source" do
469
+ source.path.should_receive(:rm)
470
+ source.update!
471
+ source.remove!
472
+ end
390
473
  end
391
474
  end
392
475
  end
@@ -4,7 +4,7 @@ def make_source_remote name = 'test'
4
4
  ["file://#{tmp_prefix / 'source_remotes' / name}", {:name => name}].tap {|source|
5
5
  source_path = source.first.gsub(/^file:\/\//, '')
6
6
  unless File.exists? source_path / '.git'
7
- shell %Q{
7
+ ShellHelpers.shell %Q{
8
8
  mkdir -p "#{source_path}" &&
9
9
  cd "#{source_path}" &&
10
10
  git init &&
@@ -1,61 +1,98 @@
1
1
  require 'spec_helper'
2
2
 
3
- describe Babushka::SystemProfile, '.for_host' do
4
- it "should return OSXSystemProfile on Darwin boxes" do
5
- Babushka::SystemProfile.should_receive(:shell).with("uname -s").and_return("Darwin")
6
- Babushka::SystemProfile.for_host.should be_an_instance_of(Babushka::OSXSystemProfile)
7
- end
8
- it "should return nil on unknown boxes" do
9
- Babushka::SystemProfile.should_receive(:shell).with("uname -s").and_return("LolOS")
10
- Babushka::SystemProfile.for_host.should be_nil
11
- end
12
- context "on BSD boxes" do
13
- it "should return DragonFlySystemProfile on Dragonfly boxes" do
14
- Babushka::SystemProfile.should_receive(:shell).with("uname -s").and_return("DragonFly")
15
- Babushka::SystemProfile.for_host.should be_an_instance_of(Babushka::DragonFlySystemProfile)
3
+ describe Babushka::SystemProfile do
4
+ subject {
5
+ Babushka::SystemDetector.profile_for_host
6
+ }
7
+
8
+ describe '#cpu_type' do
9
+ it "should return the type reported by `uname`" do
10
+ subject.should_receive(:shell).with('uname -m').and_return('x86')
11
+ subject.cpu_type.should == 'x86'
16
12
  end
17
- it "should return FreeBSDSystemProfile on FreeBSD boxes" do
18
- Babushka::SystemProfile.should_receive(:shell).with("uname -s").and_return("FreeBSD")
19
- Babushka::SystemProfile.for_host.should be_an_instance_of(Babushka::FreeBSDSystemProfile)
13
+ it "should substitute 'x86_64' for 'amd64'" do
14
+ subject.should_receive(:shell).with('uname -m').and_return('amd64')
15
+ subject.cpu_type.should == 'x86_64'
20
16
  end
21
17
  end
22
- context "on Linux boxes" do
23
- before {
24
- Babushka::SystemProfile.should_receive(:shell).with("uname -s").and_return("Linux")
25
- File.stub!(:exists?).and_return(false)
26
- }
27
- it "should return DebianSystemProfile on Debian boxes" do
28
- File.should_receive(:exists?).with("/etc/debian_version").and_return(true)
29
- Babushka::AptHelper.stub!(:install!) # so an `lsb_release` install isn't attempted
30
- Babushka::SystemProfile.for_host.should be_an_instance_of(Babushka::DebianSystemProfile)
31
- end
32
- it "should return RedhatSystemProfile on Red Hat boxes" do
33
- File.should_receive(:exists?).with("/etc/redhat-release").and_return(true)
34
- Babushka::SystemProfile.for_host.should be_an_instance_of(Babushka::RedhatSystemProfile)
35
- end
36
- it "should return LinuxSystemProfile on unknown Linux boxes" do
37
- Babushka::SystemProfile.for_host.class.should == Babushka::LinuxSystemProfile
38
- end
39
- it "should return a proper description on unknown Linux boxes" do
40
- Babushka::SystemProfile.for_host.description.should == "Linux unknown"
18
+
19
+ describe SystemProfile, '#public_ip' do
20
+ context "on OS X" do
21
+ before {
22
+ ShellHelpers.should_receive(:shell).with("uname -s").and_return("Darwin")
23
+ subject.should_receive(:shell).with('netstat -nr').and_return("
24
+ Routing tables
25
+
26
+ Internet:
27
+ Destination Gateway Flags Refs Use Netif Expire
28
+ default 10.0.1.1 UGSc 17 0 en0
29
+ 10.0.1/24 link#4 UCS 3 0 en0
30
+ 10.0.1.1 0:24:36:9e:85:7a UHLWIi 16 3 en0 621
31
+ 10.0.1.30 7c:c5:37:39:66:3e UHLWIi 0 8397 en0 686
32
+ 10.0.1.31 127.0.0.1 UHS 0 0 lo0
33
+ 127 127.0.0.1 UCS 0 0 lo0
34
+ 127.0.0.1 127.0.0.1 UH 3 43559 lo0
35
+ 169.254 link#4 UCS 0 0 en0
36
+
37
+ Internet6:
38
+ Destination Gateway Flags Netif Expire
39
+ ::1 link#1 UHL lo0
40
+ fe80::%lo0/64 fe80::1%lo0 UcI lo0
41
+ fe80::1%lo0 link#1 UHLI lo0
42
+ fe80::%en0/64 link#4 UCI en0
43
+ fe80::21f:f3ff:fe05:4659%en0 0:1f:f3:5:46:59 UHLWIi en0
44
+ fe80::223:6cff:fe82:3451%en0 0:23:6c:82:34:51 UHLWIi en0
45
+ fe80::62c5:47ff:fe03:5238%en0 60:c5:47:3:52:38 UHLWIi en0
46
+ fe80::62c5:47ff:fe03:5b6a%en0 60:c5:47:3:5b:6a UHLI lo0
47
+ fe80::6aa8:6dff:fe08:6ea2%en0 68:a8:6d:8:6e:a2 UHLWIi en0
48
+ fe80::e6ce:8fff:fe17:53c%en0 e4:ce:8f:17:5:3c UHLWIi en0
49
+ ff01::%lo0/32 fe80::1%lo0 UmCI lo0
50
+ ff01::%en0/32 link#4 UmCI en0
51
+ ff02::%lo0/32 fe80::1%lo0 UmCI lo0
52
+ ff02::%en0/32 link#4 UmCI en0
53
+ ff02::fb%en0 link#4 UHmW3I en0 350
54
+ ")
55
+ subject.should_receive(:shell).with('ifconfig', 'en0').and_return("
56
+ en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
57
+ ether 60:c5:47:03:5b:6a
58
+ inet6 fe80::62c5:47ff:fe03:5b6a%en0 prefixlen 64 scopeid 0x4
59
+ inet 10.0.1.31 netmask 0xffffff00 broadcast 10.0.1.255
60
+ media: autoselect
61
+ status: active
62
+ ")
63
+ }
64
+ it "should return the correct IP" do
65
+ subject.public_ip.should == '10.0.1.31'
66
+ end
41
67
  end
42
- context "version matching" do
68
+
69
+ context "on Linux" do
43
70
  before {
44
- File.should_receive(:exists?).with("/etc/debian_version").and_return(true)
45
- @profile = Babushka::SystemProfile.for_host
46
- @profile.should_receive(:ensure_lsb_release).and_return(true)
47
- @profile.should_receive(:shell).with("lsb_release -a").and_return(%Q{
48
- No LSB modules are available.
49
- Distributor ID: Debian
50
- Description: Debian GNU/Linux 6.0.1 (squeeze)
51
- Release: 6.0.1
52
- Codename: squeeze
53
- }.strip)
71
+ ShellHelpers.should_receive(:shell).with("uname -s").and_return("Linux")
72
+ subject.should_receive(:shell).with('netstat -nr').and_return("
73
+ Kernel IP routing table
74
+ Destination Gateway Genmask Flags MSS Window irtt Iface
75
+ 49.156.17.0 0.0.0.0 255.255.255.0 U 0 0 0 eth0
76
+ 10.0.0.0 0.0.0.0 255.0.0.0 U 0 0 0 eth1
77
+ 0.0.0.0 49.156.17.1 0.0.0.0 UG 0 0 0 eth0
78
+ ")
79
+ subject.should_receive(:shell).with('ifconfig', 'eth0').and_return("
80
+ eth0 Link encap:Ethernet HWaddr 00:16:31:9c:11:ad
81
+ inet addr:49.156.17.173 Bcast:49.156.17.255 Mask:255.255.255.0
82
+ inet6 addr: fe80::216:31ff:fe9c:11ad/64 Scope:Link
83
+ UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
84
+ RX packets:1314347 errors:0 dropped:0 overruns:0 frame:0
85
+ TX packets:743081 errors:0 dropped:0 overruns:0 carrier:0
86
+ collisions:0 txqueuelen:1000
87
+ RX bytes:1044706658 (1.0 GB) TX bytes:96454071 (96.4 MB)
88
+ Interrupt:16
89
+ ")
54
90
  }
55
- it "should detect debian squeeze" do
56
- @profile.match_list.should == [:squeeze, :debian, :apt, :linux, :all]
57
- @profile.version.should == '6.0.1'
91
+ it "should return the correct IP" do
92
+ subject.public_ip.should == '49.156.17.173'
58
93
  end
59
94
  end
95
+
60
96
  end
97
+
61
98
  end
@@ -16,7 +16,7 @@ describe Task, "process" do
16
16
  Dep('task spec').should_receive(:process)
17
17
  }
18
18
  it "should run a dep when just the name is passed" do
19
- Base.task.process ['task spec']
19
+ Base.task.process ['task spec'], {}
20
20
  end
21
21
  end
22
22
  describe "variable assignment" do
@@ -33,22 +33,22 @@ describe Task, "process" do
33
33
  end
34
34
  describe "argument assignment" do
35
35
  it "should work when with_vars contains no arguments" do
36
- @dep = dep('task spec arg passing, no args')
37
- @dep.should_receive(:with).with({}).and_return(@dep)
38
- @dep.should_receive(:process).with({:top_level => true})
39
- Base.task.process ['task spec arg passing, no args']
36
+ the_dep = dep('task spec arg passing, no args')
37
+ the_dep.should_receive(:with).with({}).and_return(the_dep)
38
+ the_dep.should_receive(:process)
39
+ Base.task.process ['task spec arg passing, no args'], {}
40
40
  end
41
41
  it "should provide the values in with_vars as dep arguments with symbol names" do
42
- @dep = dep('task spec arg passing, 1 arg', :arg)
43
- @dep.should_receive(:with).with({:arg => 'something argy'}).and_return(@dep)
44
- @dep.should_receive(:process).with({:top_level => true})
42
+ the_dep = dep('task spec arg passing, 1 arg', :arg)
43
+ the_dep.should_receive(:with).with({:arg => 'something argy'}).and_return(the_dep)
44
+ the_dep.should_receive(:process)
45
45
  Base.task.process ['task spec arg passing, 1 arg'], {'arg' => 'something argy'}
46
46
  end
47
47
  it "should print a warning about unexpected arguments, and not pass them to Dep#with" do
48
- @dep = dep('task spec arg passing, unexpected arg', :expected)
48
+ the_dep = dep('task spec arg passing, unexpected arg', :expected)
49
49
  Base.task.should_receive(:log_warn).with(%{Ignoring unexpected argument "unexpected", which the dep 'task spec arg passing, unexpected arg' would reject.})
50
- @dep.should_receive(:with).with({:expected => 'something argy'}).and_return(@dep)
51
- @dep.should_receive(:process).with({:top_level => true})
50
+ the_dep.should_receive(:with).with({:expected => 'something argy'}).and_return(the_dep)
51
+ the_dep.should_receive(:process)
52
52
  Base.task.process ['task spec arg passing, unexpected arg'], {'expected' => 'something argy', 'unexpected' => 'nobody expects the Spanish arg!'}
53
53
  end
54
54
  end
@@ -57,6 +57,73 @@ describe Task, "process" do
57
57
  }
58
58
  end
59
59
 
60
+ describe Task, 'caching' do
61
+ it "should not cache outside a #cache block" do
62
+ counter = 0
63
+ Base.task.cached(:not_caching) { counter += 1 }
64
+ Base.task.cached(:not_caching) { counter += 1 }
65
+ counter.should == 2
66
+ end
67
+ it "should not yield #hit on a cache miss" do
68
+ hit = false
69
+ Base.task.cache {
70
+ Base.task.cached(:key_miss, :hit => lambda{ hit = true }) {
71
+ 'a miss'
72
+ }.should == 'a miss'
73
+ }
74
+ hit.should be_false
75
+ end
76
+ it "should yield #hit on a cache hit" do
77
+ hit = false
78
+ Base.task.cache {
79
+ Base.task.cached(:key_hit) { 'a hit' }
80
+ Base.task.cached(:key_hit, :hit => lambda{|value| hit = value })
81
+ }
82
+ hit.should == 'a hit'
83
+ end
84
+ it "should maintain the cached value" do
85
+ result = nil
86
+ Base.task.cache {
87
+ Base.task.cached(:key_another_hit) { 'another hit' }
88
+ result = Base.task.cached(:key_another_hit) { 'a replacement' }
89
+ }
90
+ result.should == 'another hit'
91
+ end
92
+ end
93
+
94
+ describe Task, 'dep caching' do
95
+ before {
96
+ dep 'caching child b', :arg_b1, :arg_b2
97
+ dep 'caching child c', :arg_c1
98
+ dep 'caching child a', :arg_a do
99
+ requires 'caching child b'.with(:arg_b2 => 'a value')
100
+ requires 'caching child c'.with('some value')
101
+ end
102
+ dep 'caching parent' do
103
+ requires 'caching child a'
104
+ requires 'caching child b'.with('more', 'values')
105
+ requires 'caching child c'.with('some value')
106
+ end
107
+ }
108
+ it "should run the deps the right number of times" do
109
+ Dep('caching parent').should_receive(:process_self).once
110
+ Dep('caching child a').should_receive(:process_self).once.and_return(true)
111
+ Dep('caching child b').should_receive(:process_self).twice.and_return(true)
112
+ Dep('caching child c').should_receive(:process_self).once.and_return(true)
113
+ Base.task.process ['caching parent'], {}
114
+ end
115
+ it "should cache the dep requirements" do
116
+ Base.task.process ['caching parent'], {}
117
+ Base.task.caches.should == {
118
+ DepRequirement.new('caching parent', []) => true,
119
+ DepRequirement.new('caching child a', [nil]) => true,
120
+ DepRequirement.new('caching child b', [nil, 'a value']) => true,
121
+ DepRequirement.new('caching child b', ['more', 'values']) => true,
122
+ DepRequirement.new('caching child c', ['some value']) => true
123
+ }
124
+ end
125
+ end
126
+
60
127
  describe Task, "saved vars" do
61
128
  before {
62
129
  Base.task.vars.stub!(:saved_vars).and_return(Hashish.hash.merge(
@@ -74,6 +141,7 @@ end
74
141
 
75
142
  describe Task, "vars_for_save" do
76
143
  before {
144
+ Base.task.process [], {} # Clear out Base.task.vars
77
145
  Base.task.vars.stub!(:vars).and_return(standard_vars)
78
146
  @vars_for_save = Base.task.vars.for_save
79
147
  }
@@ -99,10 +167,9 @@ describe Task, "vars_for_save" do
99
167
  before {
100
168
  Base.task.vars.stub!(:saved_vars).and_return(standard_vars)
101
169
  Base.task.vars.stub!(:vars).and_return(standard_vars.reject {|k,v| %w[username versions vhost_type].include? k })
102
- @new_vars_for_save = Base.task.vars.for_save
103
170
  }
104
171
  it "should preserve old values" do
105
- (@vars_for_save.keys - @new_vars_for_save.keys).should == []
172
+ (@vars_for_save.keys - Base.task.vars.for_save.keys).should == []
106
173
  end
107
174
  end
108
175
  describe "referred values" do