sprinkle 0.2.2 → 0.2.3

Sign up to get free protection for your applications and to get access to all the features.
data/CREDITS CHANGED
@@ -19,3 +19,8 @@ Jorgen Orehøj Erichsen (http://blog.erichsen.net)
19
19
  Joshua Sierles (http://diluvia.net)
20
20
  Julian Russell (http://github.com/plusplus)
21
21
  Dave (Gassto) (http://github.com/gassto)
22
+ Bodaniel Jeanes (http://bjeanes.github.com)
23
+ Jacob Harris (http://open.nytimes.com)
24
+ Justin Pease (http://jit.nuance9.com)
25
+ Tobias Lütke (http://blog.leetsoft.com)
26
+ Josh Reynolds (http://github.com/jreynolds)
data/Manifest.txt CHANGED
@@ -54,7 +54,13 @@ lib/sprinkle/installers/push_text.rb
54
54
  lib/sprinkle/installers/rake.rb
55
55
  lib/sprinkle/installers/rpm.rb
56
56
  lib/sprinkle/installers/source.rb
57
+ lib/sprinkle/installers/transfer.rb
57
58
  lib/sprinkle/installers/yum.rb
59
+ lib/sprinkle/installers/freebsd_pkg.rb
60
+ lib/sprinkle/installers/openbsd_pkg.rb
61
+ lib/sprinkle/installers/opensolaris_pkg.rb
62
+ lib/sprinkle/installers/bsd_port.rb
63
+ lib/sprinkle/installers/mac_port.rb
58
64
  lib/sprinkle/package.rb
59
65
  lib/sprinkle/policy.rb
60
66
  lib/sprinkle/script.rb
@@ -89,6 +95,10 @@ spec/sprinkle/installers/rake_spec.rb
89
95
  spec/sprinkle/installers/rpm_spec.rb
90
96
  spec/sprinkle/installers/source_spec.rb
91
97
  spec/sprinkle/installers/yum_spec.rb
98
+ spec/sprinkle/installers/openbsd_pkg_spec.rb
99
+ spec/sprinkle/installers/freebsd_pkg_spec.rb
100
+ spec/sprinkle/installers/bsd_port_spec.rb
101
+ spec/sprinkle/installers/mac_port_spec.rb
92
102
  spec/sprinkle/package_spec.rb
93
103
  spec/sprinkle/policy_spec.rb
94
104
  spec/sprinkle/script_spec.rb
data/bin/sprinkle CHANGED
@@ -73,7 +73,7 @@ def log_level(options)
73
73
  Object.logger.level = ActiveSupport::BufferedLogger::Severity::DEBUG if options[:verbose]
74
74
  end
75
75
 
76
- require 'sprinkle'
76
+ require File.dirname(__FILE__) + '/../lib/sprinkle'
77
77
 
78
78
  powder = OPTIONS[:path]
79
79
  raise "Sprinkle script is not readable: #{powder}" unless File.readable?(powder)
@@ -25,8 +25,15 @@ module Sprinkle
25
25
  @config = ::Capistrano::Configuration.new
26
26
  @config.logger.level = Sprinkle::OPTIONS[:verbose] ? ::Capistrano::Logger::INFO : ::Capistrano::Logger::IMPORTANT
27
27
  @config.set(:password) { ::Capistrano::CLI.password_prompt }
28
+
29
+ @config.set(:_sprinkle_actor, self)
30
+
31
+ def @config.recipes(script)
32
+ _sprinkle_actor.recipes(script)
33
+ end
34
+
28
35
  if block
29
- self.instance_eval &block
36
+ @config.instance_eval &block
30
37
  else
31
38
  @config.load 'deploy' # normally in the config directory for rails
32
39
  end
@@ -69,6 +76,22 @@ module Sprinkle
69
76
  end
70
77
  end
71
78
 
79
+ def transfer(name, source, destination, roles, recursive = true, suppress_and_return_failures = false)
80
+ define_task(name, roles) do
81
+ upload source, destination, :via => :scp, :recursive => recursive
82
+ end
83
+
84
+ begin
85
+ run(name)
86
+ return true
87
+ rescue ::Capistrano::CommandError => e
88
+ return false if suppress_and_return_failures
89
+
90
+ # Reraise error if we're not suppressing it
91
+ raise
92
+ end
93
+ end
94
+
72
95
  private
73
96
 
74
97
  # REVISIT: can we set the description somehow?
@@ -25,6 +25,13 @@ module Sprinkle
25
25
  return true
26
26
  end
27
27
 
28
+ def transfer(name, source, destination, roles, recursive = true, suppress_and_return_failures = false)
29
+ if recursive
30
+ flags = "-R "
31
+ end
32
+
33
+ system "cp #{flags}#{source} #{destination}"
34
+ end
28
35
  end
29
36
  end
30
37
  end
@@ -1,4 +1,5 @@
1
1
  require 'net/ssh/gateway'
2
+ require 'net/scp'
2
3
 
3
4
  module Sprinkle
4
5
  module Actors
@@ -26,7 +27,12 @@ module Sprinkle
26
27
  return process_with_gateway(name, commands, roles) if gateway_defined?
27
28
  process_direct(name, commands, roles)
28
29
  end
29
-
30
+
31
+ def transfer(name, source, destination, roles, recursive = true, suppress_and_return_failures = false)
32
+ return transfer_with_gateway(name, source, destination, roles, recursive) if gateway_defined?
33
+ transfer_direct(name, source, destination, roles, recursive)
34
+ end
35
+
30
36
  protected
31
37
 
32
38
  def process_with_gateway(name, commands, roles)
@@ -39,10 +45,25 @@ module Sprinkle
39
45
  Array(roles).each { |role| execute_on_role(commands, role) }
40
46
  end
41
47
 
48
+ def transfer_with_gateway(name, source, destination, roles, recursive)
49
+ on_gateway do |gateway|
50
+ Array(roles).each { |role| transfer_to_role(source, destination, role, recursive, gateway) }
51
+ end
52
+ end
53
+
54
+ def transfer_direct(name, source, destination, roles, recursive)
55
+ Array(roles).each { |role| transfer_to_role(source, destination, role, recursive) }
56
+ end
57
+
42
58
  def execute_on_role(commands, role, gateway = nil)
43
59
  hosts = @options[:roles][role]
44
60
  Array(hosts).each { |host| execute_on_host(commands, host, gateway) }
45
61
  end
62
+
63
+ def transfer_to_role(source, destination, role, gateway = nil)
64
+ hosts = @options[:roles][role]
65
+ Array(hosts).each { |host| transfer_to_host(source, destination, host, gateway) }
66
+ end
46
67
 
47
68
  def execute_on_host(commands, host, gateway = nil)
48
69
  if gateway # SSH connection via gateway
@@ -64,6 +85,23 @@ module Sprinkle
64
85
  end
65
86
  end
66
87
 
88
+ def transfer_to_host(source, destination, host, recursive, gateway = nil)
89
+ if gateway # SSH connection via gateway
90
+ gateway.ssh(host, @options[:user]) do |ssh|
91
+ transfer_on_connection(source, destination, recursive, ssh)
92
+ end
93
+ else # direct SSH connection
94
+ Net::SSH.start(host, @options[:user]) do |ssh|
95
+ transfer_on_connection(source, destination, recursive, ssh)
96
+ end
97
+ end
98
+ end
99
+
100
+ def transfer_on_connection(source, destination, recursive, connection)
101
+ scp = Net::SCP.new(connection)
102
+ scp.upload! source, destination, :recursive => recursive
103
+ end
104
+
67
105
  private
68
106
 
69
107
  def gateway_defined?
@@ -50,6 +50,19 @@ module Sprinkle
50
50
  rescue ::Vlad::CommandFailedError => e
51
51
  return false if suppress_and_return_failures
52
52
 
53
+ # Reraise error if we're not suppressing it
54
+ raise
55
+ end
56
+ end
57
+
58
+ # Sorry, all transfers are recursive
59
+ def transfer(name, source, destination, roles, recursive = true, suppress_and_return_failures = false) #:nodoc:
60
+ begin
61
+ rsync source, destination
62
+ return true
63
+ rescue ::Vlad::CommandFailedError => e
64
+ return false if suppress_and_return_failures
65
+
53
66
  # Reraise error if we're not suppressing it
54
67
  raise
55
68
  end
@@ -52,7 +52,7 @@ module Sprinkle
52
52
  # the actor. For more information on what configuration options are
53
53
  # available, view the corresponding Sprinkle::Actors page.
54
54
  def delivery(type, &block) #:doc:
55
- @style = Actors.const_get(type.to_s.titleize).new &block
55
+ @style = ("Sprinkle::Actors::" + type.to_s.titleize).constantize.new &block
56
56
  end
57
57
 
58
58
  def method_missing(sym, *args, &block) #:nodoc:
@@ -54,6 +54,7 @@ module Sprinkle
54
54
  cmd << " --source #{source}" if source
55
55
  cmd << " --install-dir #{repository}" if option?(:repository)
56
56
  cmd << " --no-rdoc --no-ri" unless option?(:build_docs)
57
+ cmd << " --http-proxy #{http_proxy}" if option?(:http_proxy)
57
58
  cmd << " -- #{build_flags}" if option?(:build_flags)
58
59
  cmd
59
60
  end
@@ -37,7 +37,7 @@ module Sprinkle
37
37
  protected
38
38
 
39
39
  def install_commands #:nodoc:
40
- "echo '#{@text}' |#{'sudo' if option?(:sudo)} tee -a #{@path}"
40
+ "echo -e '#{@text.gsub("\n", '\n')}' |#{'sudo' if option?(:sudo)} tee -a #{@path}"
41
41
  end
42
42
 
43
43
  end
@@ -46,16 +46,26 @@ module Sprinkle
46
46
  # package :magic_beans do
47
47
  # source 'http://magicbeansland.com/latest-1.1.1.tar.gz' do
48
48
  # prefix '/usr/local'
49
- #
49
+ #
50
50
  # pre :prepare { 'echo "Here we go folks."' }
51
51
  # post :extract { 'echo "I believe..."' }
52
52
  # pre :build { 'echo "Cross your fingers!"' }
53
53
  # end
54
54
  # end
55
55
  #
56
+ # Fourth, specifying a custom archive name because the downloaded file name
57
+ # differs from the source URL:
58
+ #
59
+ # package :gitosis do
60
+ # source 'http://github.com/crafterm/sprinkle/tarball/master' do
61
+ # custom_archive 'crafterm-sprinkle-518e33c835986c03ec7ae8ea88c657443b006f28.tar.gz'
62
+ # end
63
+ # end
64
+ #
56
65
  # As you can see, setting options is as simple as creating a
57
66
  # block and calling the option as a method with the value as
58
67
  # its parameter.
68
+
59
69
  class Source < Installer
60
70
  attr_accessor :source #:nodoc:
61
71
 
@@ -143,7 +153,7 @@ module Sprinkle
143
153
  end
144
154
 
145
155
  def extract_command #:nodoc:
146
- case @source
156
+ case archive_name
147
157
  when /(tar.gz)|(tgz)$/
148
158
  'tar xzf'
149
159
  when /(tar.bz2)|(tb2)$/
@@ -158,7 +168,7 @@ module Sprinkle
158
168
  end
159
169
 
160
170
  def archive_name #:nodoc:
161
- name = @source.split('/').last
171
+ name = @options[:custom_archive] || @source.split('/').last
162
172
  raise "Unable to determine archive name for source: #{source}, please update code knowledge" unless name
163
173
  name
164
174
  end
@@ -168,12 +178,12 @@ module Sprinkle
168
178
  end
169
179
 
170
180
  def base_dir #:nodoc:
171
- if @source.split('/').last =~ /(.*)\.(tar\.gz|tgz|tar\.bz2|tb2)/
181
+ if archive_name.split('/').last =~ /(.*)\.(tar\.gz|tgz|tar\.bz2|tar|tb2)/
172
182
  return $1
173
183
  end
174
184
  raise "Unknown base path for source archive: #{@source}, please update code knowledge"
175
185
  end
176
-
186
+
177
187
  end
178
188
  end
179
189
  end
@@ -0,0 +1,159 @@
1
+ # Blatantly stole this from Chef
2
+ class TemplateError < RuntimeError
3
+ attr_reader :original_exception, :context
4
+ SOURCE_CONTEXT_WINDOW = 2 unless defined? SOURCE_CONTEXT_WINDOW
5
+
6
+ def initialize(original_exception, template, context)
7
+ @original_exception, @template, @context = original_exception, template, context
8
+ end
9
+
10
+ def message
11
+ @original_exception.message
12
+ end
13
+
14
+ def line_number
15
+ @line_number ||= $1.to_i if original_exception.backtrace.find {|line| line =~ /\(erubis\):(\d+)/ }
16
+ end
17
+
18
+ def source_location
19
+ "on line ##{line_number}"
20
+ end
21
+
22
+ def source_listing
23
+ return nil if line_number.nil?
24
+
25
+ @source_listing ||= begin
26
+ line_index = line_number - 1
27
+ beginning_line = line_index <= SOURCE_CONTEXT_WINDOW ? 0 : line_index - SOURCE_CONTEXT_WINDOW
28
+ source_size = SOURCE_CONTEXT_WINDOW * 2 + 1
29
+ lines = @template.split(/\n/)
30
+ contextual_lines = lines[beginning_line, source_size]
31
+ output = []
32
+ contextual_lines.each_with_index do |line, index|
33
+ line_number = (index+beginning_line+1).to_s.rjust(3)
34
+ output << "#{line_number}: #{line}"
35
+ end
36
+ output.join("\n")
37
+ end
38
+ end
39
+
40
+ def to_s
41
+ "\n\n#{self.class} (#{message}) #{source_location}:\n\n" +
42
+ "#{source_listing}\n\n #{original_exception.backtrace.join("\n ")}\n\n"
43
+ end
44
+ end
45
+
46
+ module Sprinkle
47
+ module Installers
48
+ # Beware, strange "installer" coming your way.
49
+ #
50
+ # = File transfer installer
51
+ #
52
+ # This installer pushes files from the local disk to remote servers.
53
+ #
54
+ # == Example Usage
55
+ #
56
+ # Installing a nginx.conf onto remote servers
57
+ #
58
+ # package :nginx_conf do
59
+ # transfer 'files/nginx.conf', '/etc/nginx.conf'
60
+ # end
61
+ #
62
+ # If you user has access to 'sudo' and theres a file that requires
63
+ # priveledges, you can pass :sudo => true
64
+ #
65
+ # package :nginx_conf do
66
+ # transfer 'files/nginx.conf', '/etc/nginx.conf', :sudo => true
67
+ # end
68
+ #
69
+ # By default, transfers are recursive and you can move whole directories
70
+ # via this method. If you wish to disable recursive transfers, you can pass
71
+ # recursive => false, although it will not be obeyed when using the Vlad actor.
72
+ #
73
+ # If you pass the option :render => true, this tells transfer that the source file
74
+ # is an ERB template to be rendered locally before being transferred (you can declare
75
+ # variables in the package scope). When render is true, recursive is turned off.
76
+ #
77
+ # Finally, should you need to run commands before or after the file transfer (making
78
+ # directories or changing permissions), you can use the pre/post :install directives
79
+ # and they will be run.
80
+ class Transfer < Installer
81
+ attr_accessor :source, :destination #:nodoc:
82
+
83
+ def initialize(parent, source, destination, options={}, &block) #:nodoc:
84
+ super parent, options, &block
85
+ @source = source
86
+ @destination = destination
87
+ end
88
+
89
+ def install_commands
90
+ nil
91
+ end
92
+
93
+ def self.render_template(template, context, prefix)
94
+ require 'tempfile'
95
+ require 'erubis'
96
+
97
+ begin
98
+ eruby = Erubis::Eruby.new(template)
99
+ output = eruby.result(context)
100
+ rescue Object => e
101
+ raise TemplateError.new(e, template, context)
102
+ end
103
+
104
+ final_tempfile = Tempfile.new(prefix)
105
+ final_tempfile.print(output)
106
+ final_tempfile.close
107
+ final_tempfile
108
+ end
109
+
110
+ def render_template(template, context, prefix)
111
+ self.class.render_template(template, context, prefix)
112
+ end
113
+
114
+ def render_template_file(path, context, prefix)
115
+ template = File.read(path)
116
+ tempfile = render_template(template, binding(), @package.name)
117
+ tempfile
118
+ end
119
+
120
+ def process(roles) #:nodoc:
121
+ assert_delivery
122
+
123
+ if logger.debug?
124
+ logger.debug "transfer: #{@source} -> #{@destination} for roles: #{roles}\n"
125
+ end
126
+
127
+ unless Sprinkle::OPTIONS[:testing]
128
+ pre = pre_commands(:install)
129
+ unless pre.empty?
130
+ sequence = pre; sequence = sequence.join('; ') if sequence.is_a? Array
131
+ logger.info "#{@package.name} pre-transfer commands: #{sequence} for roles: #{roles}\n"
132
+ @delivery.process @package.name, sequence, roles
133
+ end
134
+
135
+ recursive = @options[:recursive]
136
+
137
+ if options[:render]
138
+ tempfile = render_template_file(@source, binding(), @package.name)
139
+ sourcepath = tempfile.path
140
+ logger.info "Rendering template #{@source} to temporary file #{sourcepath}"
141
+ recursive = false
142
+ else
143
+ sourcepath = @source
144
+ end
145
+
146
+ logger.info "--> Transferring #{sourcepath} to #{@destination} for roles: #{roles}"
147
+ @delivery.transfer(@package.name, sourcepath, @destination, roles, recursive)
148
+
149
+ post = post_commands(:install)
150
+ unless post.empty?
151
+ sequence = post; sequence = sequence.join('; ') if sequence.is_a? Array
152
+ logger.info "#{@package.name} post-transfer commands: #{sequence} for roles: #{roles}\n"
153
+ @delivery.process @package.name, sequence, roles
154
+ end
155
+ end
156
+ end
157
+ end
158
+ end
159
+ end
@@ -168,16 +168,24 @@ module Sprinkle
168
168
 
169
169
  def rake(name, options = {}, &block)
170
170
  @installer = Sprinkle::Installers::Rake.new(self, name, options, &block)
171
+ end
172
+
173
+ def noop(&block)
174
+ @installer = Sprinkle::Installers::Noop.new(self, name, options, &block)
171
175
  end
172
176
 
173
177
  def push_text(text, path, options = {}, &block)
174
178
  @installer = Sprinkle::Installers::PushText.new(self, text, path, options, &block)
175
179
  end
176
-
177
- def verify(description = '', &block)
178
- @verifications << Sprinkle::Verify.new(self, description, &block)
180
+
181
+ def transfer(source, destination, options = {}, &block)
182
+ @installer = Sprinkle::Installers::Transfer.new(self, source, destination, options, &block)
179
183
  end
180
184
 
185
+ def verify(description = '', &block)
186
+ @verifications << Sprinkle::Verify.new(self, description, &block)
187
+ end
188
+
181
189
  def process(deployment, roles)
182
190
  return if meta_package?
183
191
 
@@ -2,7 +2,7 @@ module Sprinkle #:nodoc:
2
2
  module VERSION #:nodoc:
3
3
  MAJOR = 0
4
4
  MINOR = 2
5
- TINY = 2
5
+ TINY = 3
6
6
 
7
7
  STRING = [MAJOR, MINOR, TINY].join('.')
8
8
  end
@@ -135,6 +135,51 @@ describe Sprinkle::Actors::Capistrano do
135
135
 
136
136
  end
137
137
 
138
+ describe 'transferring files' do
139
+
140
+ before do
141
+ @source = 'source'
142
+ @dest = 'dest'
143
+ @roles = %w( app )
144
+ @name = 'name'
145
+
146
+ @cap = create_cap do; recipes 'deploy'; end
147
+ @cap.stub!(:run).and_return
148
+
149
+ @testing_errors = false
150
+ end
151
+
152
+ it 'should dynamically create a capistrano task containing calling upload' do
153
+ @cap.config.should_receive(:task).and_return
154
+ end
155
+
156
+ it 'should invoke capistrano task after creation' do
157
+ @cap.should_receive(:run).with(@name).and_return
158
+ end
159
+
160
+ it 'should raise capistrano errors when suppressing parameter is not set' do
161
+ @testing_errors = true
162
+
163
+ @cap.should_receive(:run).and_raise(::Capistrano::CommandError)
164
+ lambda { @cap.process @name, @commands, @roles }.should raise_error(::Capistrano::CommandError)
165
+ end
166
+
167
+ it 'should not raise errors and instead return false when suppressing parameter is set' do
168
+ @testing_errors = true
169
+
170
+ @cap.should_receive(:run).and_raise(::Capistrano::CommandError)
171
+
172
+ value = nil
173
+ lambda { value = @cap.process(@name, @commands, @roles, true) }.should_not raise_error(::Capistrano::CommandError)
174
+
175
+ value.should_not be
176
+ end
177
+
178
+ after do
179
+ @cap.transfer @name, @source, @dest, @roles unless @testing_errors
180
+ end
181
+ end
182
+
138
183
  describe 'generated task' do
139
184
 
140
185
  before do
@@ -167,4 +212,54 @@ describe Sprinkle::Actors::Capistrano do
167
212
 
168
213
  end
169
214
 
215
+ describe 'generated transfer' do
216
+ before do
217
+ @source = 'source'
218
+ @dest = 'dest'
219
+ @roles = %w( app )
220
+ @name = 'name'
221
+
222
+ @cap = create_cap do; recipes 'deploy'; end
223
+ @cap.config.stub!(:upload).and_return
224
+ end
225
+
226
+ it 'should call upload with the source and destination via :scp' do
227
+ @cap.config.should_receive(:upload).with(@source, @dest, :via => :scp, :recursive => true).and_return
228
+ end
229
+
230
+ it 'should be applicable for the supplied roles' do
231
+ @cap.stub!(:run).and_return
232
+ @cap.config.should_receive(:task).with(:install_name, :roles => @roles).and_return
233
+ end
234
+
235
+ after do
236
+ @cap.transfer @name, @source, @dest, @roles
237
+ end
238
+ end
239
+
240
+ describe 'generated transfer when recursive is false' do
241
+ before do
242
+ @source = 'source'
243
+ @dest = 'dest'
244
+ @roles = %w( app )
245
+ @name = 'name'
246
+
247
+ @cap = create_cap do; recipes 'deploy'; end
248
+ @cap.config.stub!(:upload).and_return
249
+ end
250
+
251
+ it 'should call upload with the source and destination via :scp' do
252
+ @cap.config.should_receive(:upload).with(@source, @dest, :via => :scp, :recursive => false).and_return
253
+ end
254
+
255
+ it 'should be applicable for the supplied roles' do
256
+ @cap.stub!(:run).and_return
257
+ @cap.config.should_receive(:task).with(:install_name, :roles => @roles).and_return
258
+ end
259
+
260
+ after do
261
+ @cap.transfer @name, @source, @dest, @roles, false
262
+ end
263
+ end
264
+
170
265
  end
@@ -5,7 +5,7 @@ describe Sprinkle::Installers::Gem do
5
5
  before do
6
6
  @gem = 'rails'
7
7
  @version = '2.0.2'
8
- @options = { :source => 'http://gems.github.com/', :repository => '/tmp/gems', :build_flags => '--build_flag=foo' }
8
+ @options = { :source => 'http://gems.github.com/', :repository => '/tmp/gems', :build_flags => '--build_flag=foo', :http_proxy => 'http://proxy:8080' }
9
9
  end
10
10
 
11
11
  def create_gem(gem, version = nil, options = {}, &block)
@@ -39,6 +39,10 @@ describe Sprinkle::Installers::Gem do
39
39
  @installer.build_flags.should == @options[:build_flags]
40
40
  end
41
41
 
42
+ it 'should optionally store the http proxy' do
43
+ @installer.http_proxy.should == @options[:http_proxy]
44
+ end
45
+
42
46
  end
43
47
 
44
48
  describe 'during installation' do
@@ -86,6 +90,18 @@ describe Sprinkle::Installers::Gem do
86
90
 
87
91
  end
88
92
 
93
+ describe 'with http proxy' do
94
+
95
+ before do
96
+ @installer = create_gem @gem, nil, :http_proxy => 'http://proxy:8080'
97
+ end
98
+
99
+ it 'should install with defined build flags' do
100
+ @installer.send(:install_commands).should == "gem install #{@gem} --no-rdoc --no-ri --http-proxy http://proxy:8080"
101
+ end
102
+
103
+ end
104
+
89
105
  end
90
106
 
91
107
  end
@@ -36,7 +36,7 @@ describe Sprinkle::Installers::PushText do
36
36
  end
37
37
 
38
38
  it 'should automatically insert pre/post commands for the specified package' do
39
- @installer.send(:install_sequence).should == [ 'op1', "echo 'another-hair-brained-idea' | tee -a /dev/mind/late-night", 'op2' ]
39
+ @installer.send(:install_sequence).should == [ 'op1', "echo -e 'another-hair-brained-idea' | tee -a /dev/mind/late-night", 'op2' ]
40
40
  end
41
41
 
42
42
  end
@@ -48,7 +48,7 @@ describe Sprinkle::Installers::PushText do
48
48
  end
49
49
 
50
50
  it "should invoke the push installer with sudo" do
51
- @install_commands.should =~ /echo 'I\'m a special user' | sudo tee -a \/dev\/mind\/the-day-after/
51
+ @install_commands.should =~ /echo -e 'I\'m a special user' | sudo tee -a \/dev\/mind\/the-day-after/
52
52
  end
53
53
  end
54
54
 
@@ -161,6 +161,20 @@ describe Sprinkle::Installers::Source do
161
161
  )
162
162
  end
163
163
 
164
+ describe 'with a custom archive definition' do
165
+ before do
166
+ @installer.options[:custom_archive] = 'super-foo.tar'
167
+ end
168
+
169
+ it 'should install the source from the custom archive' do
170
+ @installer.send(:extract_commands).first.should =~ /super-foo/
171
+ @installer.send(:configure_commands).first.should =~ /super-foo/
172
+ @installer.send(:build_commands).first.should =~ /super-foo/
173
+ @installer.send(:install_commands).first.should =~ /super-foo/
174
+ end
175
+
176
+ end
177
+
164
178
  describe 'during a customized install' do
165
179
 
166
180
  before do
@@ -174,7 +188,7 @@ describe Sprinkle::Installers::Source do
174
188
  it 'should store the custom install commands' do
175
189
  @installer.options[:custom_install].should == 'ruby setup.rb'
176
190
  end
177
-
191
+
178
192
  it 'should identify as having a custom install command' do
179
193
  @installer.should be_custom_install
180
194
  end
@@ -190,25 +204,25 @@ describe Sprinkle::Installers::Source do
190
204
  it 'should install the source using a custom installation command' do
191
205
  @installer.send(:custom_install_commands).first.should =~ /ruby setup.rb/
192
206
  end
193
-
207
+
194
208
  it 'should be run relative to the source build area' do
195
209
  @installer.send(:custom_install_commands).first.should =~ %r{cd /usr/builds/ruby-1.8.6-p111}
196
210
  end
197
-
211
+
198
212
  describe 'with a customized directory' do
199
-
213
+
200
214
  before do
201
215
  @installer.options[:custom_dir] = 'test'
202
216
  end
203
-
217
+
204
218
  it 'should install the source from the custom dir path' do
205
219
  @installer.send(:custom_install_commands).first.should =~ /test/
206
220
  end
207
-
221
+
208
222
  it 'should store the custom build dir path' do
209
223
  @installer.options[:custom_dir].should == 'test'
210
224
  end
211
-
225
+
212
226
  end
213
227
 
214
228
  end
data/sprinkle.gemspec CHANGED
@@ -1,6 +1,6 @@
1
1
  Gem::Specification.new do |s|
2
2
  s.name = %q{sprinkle}
3
- s.version = "0.2.2"
3
+ s.version = "0.2.3"
4
4
 
5
5
  s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
6
6
  s.authors = ["Marcus Crafter", "Mitchell Hashimoto"]
@@ -21,6 +21,9 @@ task :check_version do
21
21
  end
22
22
  end
23
23
 
24
+ task :clobber_rcov do
25
+ end
26
+
24
27
  desc 'Install the package as a gem, without generating documentation(ri/rdoc)'
25
28
  task :install_gem_no_doc => [:clean, :package] do
26
29
  sh "#{'sudo ' unless Hoe::WINDOZE }gem install pkg/*.gem --no-rdoc --no-ri"
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: sprinkle
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.2
4
+ version: 0.2.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Marcus Crafter
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2009-03-11 00:00:00 +11:00
12
+ date: 2009-07-24 00:00:00 +10:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -50,7 +50,7 @@ dependencies:
50
50
  requirements:
51
51
  - - ">="
52
52
  - !ruby/object:Gem::Version
53
- version: 1.8.0
53
+ version: 2.3.2
54
54
  version:
55
55
  description: Ruby DSL based software provisioning tool
56
56
  email:
@@ -120,6 +120,7 @@ files:
120
120
  - lib/sprinkle/installers/rake.rb
121
121
  - lib/sprinkle/installers/rpm.rb
122
122
  - lib/sprinkle/installers/source.rb
123
+ - lib/sprinkle/installers/transfer.rb
123
124
  - lib/sprinkle/installers/yum.rb
124
125
  - lib/sprinkle/package.rb
125
126
  - lib/sprinkle/policy.rb
@@ -166,6 +167,8 @@ files:
166
167
  - tasks/rspec.rake
167
168
  has_rdoc: true
168
169
  homepage: http://sprinkle.rubyforge.org
170
+ licenses: []
171
+
169
172
  post_install_message:
170
173
  rdoc_options:
171
174
  - --main
@@ -187,9 +190,9 @@ required_rubygems_version: !ruby/object:Gem::Requirement
187
190
  requirements: []
188
191
 
189
192
  rubyforge_project: sprinkle
190
- rubygems_version: 1.3.1
193
+ rubygems_version: 1.3.4
191
194
  signing_key:
192
- specification_version: 2
195
+ specification_version: 3
193
196
  summary: Ruby DSL based software provisioning tool
194
197
  test_files: []
195
198