auser-sprinkle 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (69) hide show
  1. data/CREDITS +16 -0
  2. data/History.txt +4 -0
  3. data/MIT-LICENSE +20 -0
  4. data/Manifest.txt +67 -0
  5. data/README.rdoc +224 -0
  6. data/Rakefile +4 -0
  7. data/bin/sprinkle +86 -0
  8. data/config/hoe.rb +70 -0
  9. data/config/requirements.rb +17 -0
  10. data/examples/merb/deploy.rb +5 -0
  11. data/examples/rails/README +15 -0
  12. data/examples/rails/deploy.rb +2 -0
  13. data/examples/rails/packages/database.rb +9 -0
  14. data/examples/rails/packages/essential.rb +6 -0
  15. data/examples/rails/packages/rails.rb +28 -0
  16. data/examples/rails/packages/search.rb +11 -0
  17. data/examples/rails/packages/server.rb +28 -0
  18. data/examples/rails/rails.rb +71 -0
  19. data/examples/sprinkle/sprinkle.rb +38 -0
  20. data/lib/sprinkle.rb +28 -0
  21. data/lib/sprinkle/actors/capistrano.rb +89 -0
  22. data/lib/sprinkle/actors/vlad.rb +39 -0
  23. data/lib/sprinkle/configurable.rb +24 -0
  24. data/lib/sprinkle/deployment.rb +33 -0
  25. data/lib/sprinkle/extensions/arbitrary_options.rb +10 -0
  26. data/lib/sprinkle/extensions/array.rb +7 -0
  27. data/lib/sprinkle/extensions/blank_slate.rb +5 -0
  28. data/lib/sprinkle/extensions/dsl_accessor.rb +15 -0
  29. data/lib/sprinkle/extensions/string.rb +10 -0
  30. data/lib/sprinkle/extensions/symbol.rb +7 -0
  31. data/lib/sprinkle/installers/apt.rb +25 -0
  32. data/lib/sprinkle/installers/gem.rb +33 -0
  33. data/lib/sprinkle/installers/installer.rb +74 -0
  34. data/lib/sprinkle/installers/rake.rb +17 -0
  35. data/lib/sprinkle/installers/rpm.rb +20 -0
  36. data/lib/sprinkle/installers/source.rb +121 -0
  37. data/lib/sprinkle/package.rb +127 -0
  38. data/lib/sprinkle/policy.rb +85 -0
  39. data/lib/sprinkle/script.rb +13 -0
  40. data/lib/sprinkle/verifiers/directory.rb +11 -0
  41. data/lib/sprinkle/verifiers/executable.rb +17 -0
  42. data/lib/sprinkle/verifiers/file.rb +11 -0
  43. data/lib/sprinkle/verifiers/symlink.rb +15 -0
  44. data/lib/sprinkle/verify.rb +55 -0
  45. data/lib/sprinkle/version.rb +9 -0
  46. data/script/destroy +14 -0
  47. data/script/generate +14 -0
  48. data/spec/spec.opts +1 -0
  49. data/spec/spec_helper.rb +17 -0
  50. data/spec/sprinkle/actors/capistrano_spec.rb +170 -0
  51. data/spec/sprinkle/configurable_spec.rb +46 -0
  52. data/spec/sprinkle/deployment_spec.rb +80 -0
  53. data/spec/sprinkle/extensions/array_spec.rb +19 -0
  54. data/spec/sprinkle/extensions/string_spec.rb +21 -0
  55. data/spec/sprinkle/installers/apt_spec.rb +74 -0
  56. data/spec/sprinkle/installers/gem_spec.rb +75 -0
  57. data/spec/sprinkle/installers/installer_spec.rb +151 -0
  58. data/spec/sprinkle/installers/rpm_spec.rb +50 -0
  59. data/spec/sprinkle/installers/source_spec.rb +331 -0
  60. data/spec/sprinkle/package_spec.rb +422 -0
  61. data/spec/sprinkle/policy_spec.rb +126 -0
  62. data/spec/sprinkle/script_spec.rb +51 -0
  63. data/spec/sprinkle/sprinkle_spec.rb +25 -0
  64. data/spec/sprinkle/verify_spec.rb +137 -0
  65. data/sprinkle.gemspec +43 -0
  66. data/tasks/deployment.rake +34 -0
  67. data/tasks/environment.rake +7 -0
  68. data/tasks/rspec.rake +21 -0
  69. metadata +158 -0
@@ -0,0 +1,46 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Sprinkle::Configurable do
4
+ module MyPrefix
5
+ class Configurable
6
+ include Sprinkle::Configurable
7
+ end
8
+ end
9
+
10
+ before do
11
+ @configurable = MyPrefix::Configurable.new
12
+ @default = Proc.new { }
13
+ @defaults = { :configurable => @default }
14
+ @deployment.stub!(:defaults).and_return(@defaults)
15
+ @deployment.stub!(:style)
16
+ end
17
+
18
+ it 'should be configurable via external defaults' do
19
+ @configurable.should respond_to(:defaults)
20
+ end
21
+
22
+ it 'should select the defaults for the particular concrete installer class' do
23
+ @deployment.should_receive(:defaults).and_return(@defaults)
24
+ @defaults.should_receive(:[]).with(:configurable).and_return(@default)
25
+ end
26
+
27
+ it 'should configure the installer delivery mechansim' do
28
+ @configurable.should_receive(:instance_eval)
29
+ end
30
+
31
+ it 'should maintain an options hash set arbitrarily via method missing' do
32
+ @configurable.instance_eval do
33
+ hsv 'gts'
34
+ end
35
+ @configurable.hsv.should == 'gts'
36
+ end
37
+
38
+ it 'should allow the delivery instance variable to be accessed' do
39
+ @configurable.delivery = "string"
40
+ @configurable.instance_variable_get(:@delivery).should eql("string")
41
+ end
42
+
43
+ after do
44
+ @configurable.defaults(@deployment)
45
+ end
46
+ end
@@ -0,0 +1,80 @@
1
+ require File.dirname(__FILE__) + '/../spec_helper'
2
+
3
+ describe Sprinkle::Deployment do
4
+ include Sprinkle::Deployment
5
+
6
+ def create_deployment(&block)
7
+ deployment do
8
+ delivery :capistrano, &block
9
+
10
+ source do
11
+ prefix '/usr/local'
12
+ end
13
+ end
14
+ end
15
+
16
+ describe 'when created' do
17
+
18
+ it 'should be invalid without a block descriptor' do
19
+ lambda { deployment }.should raise_error
20
+ end
21
+
22
+ it 'should be invalid without a delivery method' do
23
+ lambda { @deployment = deployment do; end }.should raise_error
24
+ end
25
+
26
+ it 'should optionally accept installer defaults' do
27
+ @deployment = create_deployment
28
+ @deployment.should respond_to(:source)
29
+ end
30
+
31
+ it 'should provide installer defaults as a proc when requested' do
32
+ @deployment = create_deployment
33
+ @deployment.defaults[:source].class.should == Proc
34
+ end
35
+
36
+ end
37
+
38
+ describe 'delivery specification' do
39
+
40
+ before do
41
+ @actor = mock(Sprinkle::Actors::Capistrano)
42
+ Sprinkle::Actors::Capistrano.stub!(:new).and_return(@actor)
43
+ end
44
+
45
+ it 'should automatically instantiate the delivery type' do
46
+ @deployment = create_deployment
47
+ @deployment.style.should == @actor
48
+ end
49
+
50
+ it 'should optionally accept a block to pass to the actor' do
51
+ lambda { @deployment = create_deployment }.should_not raise_error
52
+ end
53
+
54
+ describe 'with a block' do
55
+
56
+ it 'should pass the block to the actor for configuration' do
57
+ @deployment = create_deployment do; recipes 'deploy'; end
58
+ end
59
+
60
+ end
61
+ end
62
+
63
+ describe 'when processing policies' do
64
+
65
+ before do
66
+ @policy = mock(Policy, :process => true)
67
+ POLICIES = [ @policy ]
68
+ @deployment = create_deployment
69
+ end
70
+
71
+ it 'should apply all policies, passing itself as the deployment context' do
72
+ @policy.should_receive(:process).with(@deployment).and_return
73
+ end
74
+
75
+ after do
76
+ @deployment.process
77
+ end
78
+ end
79
+
80
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Array, 'task name conversions' do
4
+
5
+ it 'should be able to deliver a task name' do
6
+ ['build_essential'].to_task_name.should == 'build_essential'
7
+ end
8
+
9
+ it 'should join multiple elements together with a _ char' do
10
+ ['gdb', 'gcc', 'g++'].to_task_name.should == 'gdb_gcc_g++'
11
+ end
12
+
13
+ it 'should use the task name of the underlying array element' do
14
+ string = 'build-essential'
15
+ string.should_receive(:to_task_name).and_return('build_essential')
16
+ [string].to_task_name.should == 'build_essential'
17
+ end
18
+
19
+ end
@@ -0,0 +1,21 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe String, 'task name conversions' do
4
+
5
+ it 'should be able to deliver a task name' do
6
+ 'build_essential'.to_task_name.should == 'build_essential'
7
+ end
8
+
9
+ it 'should convert all - chars to _ in the task name' do
10
+ 'build-essential'.to_task_name.should == 'build_essential'
11
+ end
12
+
13
+ it 'should convert multiple - chars to _ chars in the task name' do
14
+ 'build--essential'.to_task_name.should == 'build__essential'
15
+ end
16
+
17
+ it 'should lowercase the task name' do
18
+ 'BUILD-ESSENTIAL'.to_task_name.should == 'build_essential'
19
+ end
20
+
21
+ end
@@ -0,0 +1,74 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Sprinkle::Installers::Apt do
4
+
5
+ before do
6
+ @package = mock(Sprinkle::Package, :name => 'package')
7
+ end
8
+
9
+ def create_apt(*debs, &block)
10
+ Sprinkle::Installers::Apt.new(@package, *debs, &block)
11
+ end
12
+
13
+ describe 'when created' do
14
+
15
+ it 'should accept a single package to install' do
16
+ @installer = create_apt 'ruby'
17
+ @installer.packages.should == [ 'ruby' ]
18
+ end
19
+
20
+ it 'should accept an array of packages to install' do
21
+ @installer = create_apt %w( gcc gdb g++ )
22
+ @installer.packages.should == ['gcc', 'gdb', 'g++']
23
+ end
24
+
25
+ end
26
+
27
+ describe 'when created for dependencies only install' do
28
+
29
+ it 'should remove options from packages list' do
30
+ @installer = create_apt 'ruby', :dependencies_only => true
31
+ @installer.packages.should == [ 'ruby' ]
32
+ end
33
+
34
+ end
35
+
36
+ describe 'during installation' do
37
+
38
+ before do
39
+ @installer = create_apt 'ruby' do
40
+ pre :install, 'op1'
41
+ post :install, 'op2'
42
+ end
43
+ @install_commands = @installer.send :install_commands
44
+ end
45
+
46
+ it 'should invoke the apt installer for all specified packages' do
47
+ @install_commands.should =~ /apt-get -qyu install ruby/
48
+ end
49
+
50
+ it 'should specify a non interactive mode to the apt installer' do
51
+ @install_commands.should =~ /DEBIAN_FRONTEND=noninteractive/
52
+ end
53
+
54
+ it 'should automatically insert pre/post commands for the specified package' do
55
+ @installer.send(:install_sequence).should == [ 'op1', %(DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive apt-get -qyu install ruby), 'op2' ]
56
+ end
57
+
58
+ it 'should install a specific version if defined'
59
+
60
+ end
61
+
62
+ describe 'during dependencies only installation' do
63
+
64
+ before do
65
+ @installer = create_apt 'ruby', :dependencies_only => true
66
+ @install_commands = @installer.send :install_commands
67
+ end
68
+
69
+ it 'should invoke the apt installer with build-dep command for all specified packages' do
70
+ @install_commands.should =~ /apt-get -qyu build-dep ruby/
71
+ end
72
+
73
+ end
74
+ end
@@ -0,0 +1,75 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Sprinkle::Installers::Gem do
4
+
5
+ before do
6
+ @gem = 'rails'
7
+ @version = '2.0.2'
8
+ @options = { :source => 'http://gems.github.com/', :repository => '/tmp/gems' }
9
+ end
10
+
11
+ def create_gem(gem, version = nil, options = {}, &block)
12
+ @package = mock(Sprinkle::Package, :name => gem, :version => version, :source => nil, :repository => nil)
13
+ Sprinkle::Installers::Gem.new(@package, gem, options, &block)
14
+ end
15
+
16
+ describe 'when created' do
17
+
18
+ before do
19
+ @installer = create_gem @gem, @version, @options
20
+ end
21
+
22
+ it 'should accept a single package to install' do
23
+ @installer.gem.should == @gem
24
+ end
25
+
26
+ it 'should optionally store a version of the gem to install' do
27
+ @installer.version.should == '2.0.2'
28
+ end
29
+
30
+ it 'should optionally store a source location of the gem to install' do
31
+ @installer.source.should == 'http://gems.github.com/'
32
+ end
33
+
34
+ it 'should optionally store the repository location where gems are to be installed' do
35
+ @installer.repository.should == @options[:repository]
36
+ end
37
+
38
+ end
39
+
40
+ describe 'during installation' do
41
+
42
+ describe 'without a version' do
43
+
44
+ before do
45
+ @installer = create_gem @gem do
46
+ pre :install, 'op1'
47
+ post :install, 'op2'
48
+ end
49
+ end
50
+
51
+ it 'should invoke the gem installer for the specified package' do
52
+ @installer.send(:install_commands).should == "gem install #{@gem}"
53
+ end
54
+
55
+ it 'should automatically insert pre/post commands for the specified package' do
56
+ @installer.send(:install_sequence).should == [ 'op1', "gem install #{@gem}", 'op2' ]
57
+ end
58
+
59
+ end
60
+
61
+ describe 'with a specific version' do
62
+
63
+ before do
64
+ @installer = create_gem @gem, @version
65
+ end
66
+
67
+ it 'should install a specific version if defined' do
68
+ @installer.send(:install_commands).should == "gem install #{@gem} --version '#{@version}'"
69
+ end
70
+
71
+ end
72
+
73
+ end
74
+
75
+ end
@@ -0,0 +1,151 @@
1
+ require File.dirname(__FILE__) + '/../../spec_helper'
2
+
3
+ describe Sprinkle::Installers::Installer do
4
+ include Sprinkle::Deployment
5
+
6
+ before do
7
+ @package = mock(Sprinkle::Package, :name => 'package')
8
+ @empty = Proc.new { }
9
+ @sequence = ['op1', 'op2']
10
+ @delivery = mock(Sprinkle::Deployment, :process => true)
11
+ @installer = create_installer
12
+ @installer.delivery = @delivery
13
+ @roles = []
14
+ @deployment = deployment do
15
+ delivery :capistrano
16
+ installer do; prefix '/usr/bin'; end
17
+ end
18
+ end
19
+
20
+ def create_installer(&block)
21
+ installer = Sprinkle::Installers::Installer.new @package, &block
22
+ installer.stub!(:puts).and_return
23
+
24
+ # this is actually an abstract class so we'll insert a few fake install sequences
25
+ class << installer
26
+ def install_sequence
27
+ ['op1', 'op2']
28
+ end
29
+ end
30
+
31
+ installer
32
+ end
33
+
34
+ describe 'when created' do
35
+
36
+ it 'should belong to a package' do
37
+ @installer.package.should == @package
38
+ end
39
+
40
+ describe 'with a block to customize installer defaults' do
41
+
42
+ it 'should accept an optional block to customize installers defaults' do
43
+ @installer = create_installer do; prefix '/usr/local'; end
44
+ @installer.prefix.should == '/usr/local'
45
+ end
46
+
47
+ it 'should override any deployment level defaults' do
48
+ @installer = create_installer do; prefix '/usr/local'; end
49
+ @installer.defaults(@deployment)
50
+ @installer.prefix.should == '/usr/local'
51
+ end
52
+ end
53
+ end
54
+
55
+ describe 'during configuration' do
56
+ # We just check to make sure it has the Sprinkle::Configurable method
57
+ it 'should be configurable' do
58
+ @installer.should respond_to(:defaults)
59
+ end
60
+ end
61
+
62
+ describe 'during installation' do
63
+
64
+ it 'should request the install sequence from the concrete class' do
65
+ @installer.should_receive(:install_sequence).and_return(@sequence)
66
+ end
67
+
68
+ describe 'when testing' do
69
+
70
+ before do
71
+ Sprinkle::OPTIONS[:testing] = true
72
+ @logger = mock(ActiveSupport::BufferedLogger, :debug => true, :debug? => true)
73
+ end
74
+
75
+ it 'should not invoke the delivery mechanism with the install sequence' do
76
+ @delivery.should_not_receive(:process)
77
+ end
78
+
79
+ it 'should print the install sequence to the console' do
80
+ @installer.should_receive(:logger).twice.and_return(@logger)
81
+ end
82
+
83
+ end
84
+
85
+ describe 'when in production' do
86
+ it 'should invoke the delivery mechanism to process the install sequence' do
87
+ @delivery.should_receive(:process).with(@package.name, @sequence, @roles)
88
+ end
89
+ end
90
+
91
+ describe "with a pre command" do
92
+
93
+ def create_installer_with_pre_command(cmd="")
94
+ installer = Sprinkle::Installers::Installer.new @package do
95
+ pre :install, cmd
96
+
97
+ def install_commands
98
+ ["installer"]
99
+ end
100
+ end
101
+
102
+ installer.stub!(:puts).and_return
103
+ installer.delivery = @delivery
104
+ installer
105
+ end
106
+ before do
107
+ @installer = create_installer_with_pre_command('run')
108
+ end
109
+ describe "string commands" do
110
+ it "should insert the pre command for the specific package in the installation process" do
111
+ @installer.send(:install_sequence).should == [ 'run', 'installer' ]
112
+ end
113
+ end
114
+ describe "blocks as commands" do
115
+ before(:each) do
116
+ @installer = Sprinkle::Installers::Installer.new @package do
117
+ pre :install do
118
+ %w(a b c)
119
+ end
120
+
121
+ def install_commands
122
+ ["installer"]
123
+ end
124
+ end
125
+
126
+ @installer.stub!(:puts).and_return
127
+ @installer.delivery = @delivery
128
+ end
129
+ it "should be able to store a block if it's the pre command" do
130
+ @installer.send(:install_sequence).should == [ "a", "b", "c", 'installer' ]
131
+ end
132
+ end
133
+ describe "blocks as commands" do
134
+ before(:each) do
135
+ @array = ["a", "b"]
136
+ @installer = create_installer_with_pre_command(@array)
137
+ end
138
+ it "should be able to store a block if it's the pre command" do
139
+ @installer.send(:install_sequence).should == [ @array, 'installer' ].flatten
140
+ end
141
+ end
142
+ end
143
+
144
+ after do
145
+ @installer.process(@roles)
146
+ Sprinkle::OPTIONS[:testing] = false
147
+ end
148
+
149
+ end
150
+
151
+ end