Permalink
Browse files

Refactor pre/post command management to be located on the abstract in…

…staller class for reuse across derivatives. Updates to take advantage of this to allow pre/post install commands on all installer types, while still allowing complex installers to take complete control of command assembly if needed. Increment minor version number. Updated specs to validate
  • Loading branch information...
1 parent 0fa0baa commit b26a937755b9819e25dc9ba941b1c7063ca0ac77 @crafterm committed Jul 13, 2008
@@ -11,7 +11,7 @@ def initialize(parent, packages, &block)
protected
- def install_sequence
+ def install_commands
"DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive apt-get -qyu install #{@packages.join(' ')}"
end
@@ -20,13 +20,14 @@ def source(location = nil)
# rubygems 0.9.5+ installs dependencies by default, and does platform selection
- def install_sequence
+ def install_commands
cmd = "gem install #{gem}"
cmd << " --version '#{version}'" if version
cmd << " --source #{source}" if source
cmd << " --install-dir #{repository}" if repository
cmd
end
+
end
end
end
@@ -1,14 +1,25 @@
module Sprinkle
module Installers
class Installer
- attr_accessor :delivery, :package, :options
+ attr_accessor :delivery, :package, :options, :pre, :post
def initialize(package, options = {}, &block)
@package = package
@options = options
+ @pre = {}; @post = {}
self.instance_eval(&block) if block
end
+ def pre(stage, *commands)
+ @pre[stage] ||= []
+ @pre[stage] += commands
+ end
+
+ def post(stage, *commands)
+ @post[stage] ||= []
+ @post[stage] += commands
+ end
+
def defaults(deployment)
defaults = deployment.defaults[self.class.name.split(/::/).last.downcase.to_sym]
self.instance_eval(&defaults) if defaults
@@ -39,9 +50,36 @@ def method_missing(sym, *args, &block)
protected
+ # Installation is separated into two styles that concrete derivative installer classes
+ # can implement.
+ #
+ # Simple installers that issue a single or set of commands can overwride
+ # install_commands (eg. apt, gem, rpm). Pre/post install commands are included in this
+ # style for free.
+ #
+ # More complicated installers that have different stages, and require pre/post commands
+ # within stages can override install_sequence and take complete control of the install
+ # command sequence construction (eg. source based installer).
+
def install_sequence
+ commands = pre_commands(:install) + [ install_commands ] + post_commands(:install)
+ commands.flatten
+ end
+
+ def install_commands
raise 'Concrete installers implement this to specify commands to run to install their respective packages'
end
+
+ def pre_commands(stage)
+ dress @pre[stage] || [], :pre
+ end
+
+ def post_commands(stage)
+ dress @post[stage] || [], :post
+ end
+
+ def dress(commands, stage); commands; end
+
end
end
end
@@ -8,9 +8,10 @@ def initialize(parent, commands = [], &block)
protected
- def install_sequence
+ def install_commands
"rake #{@commands.join(' ')}"
end
+
end
end
end
@@ -11,9 +11,9 @@ def initialize(parent, packages, &block)
protected
- def install_sequence
- "rpm -Uvh #{@packages.join(' ')}"
- end
+ def install_commands
+ "rpm -Uvh #{@packages.join(' ')}"
+ end
end
end
@@ -1,24 +1,13 @@
module Sprinkle
module Installers
class Source < Installer
- attr_accessor :source, :pre, :post
+ attr_accessor :source
def initialize(parent, source, options = {}, &block)
- @pre = {}; @post = {}
@source = source
super parent, options, &block
end
- def pre(stage, *commands)
- @pre[stage] ||= []
- @pre[stage] += commands
- end
-
- def post(stage, *commands)
- @post[stage] ||= []
- @post[stage] += commands
- end
-
protected
def install_sequence
@@ -83,20 +72,14 @@ def custom_install_commands
dress @options[:custom_install], :install
end
- private
-
- def pre_commands(stage)
- dress @pre[stage] || [], :pre
- end
-
- def post_commands(stage)
- dress @post[stage] || [], :post
- end
+ protected
def dress(commands, stage)
commands.collect { |command| "bash -c 'cd #{build_dir} && #{command} >> #{@package.name}-#{stage}.log 2>&1'" }
end
+ private
+
def create_options(key, prefix)
@options[key].inject(' ') { |m, option| m << "#{prefix}-#{option} "; m }
end
View
@@ -2,7 +2,7 @@ module Sprinkle #:nodoc:
module VERSION #:nodoc:
MAJOR = 0
MINOR = 1
- TINY = 3
+ TINY = 4
STRING = [MAJOR, MINOR, TINY].join('.')
end
@@ -27,16 +27,23 @@ def create_apt(debs, &block)
describe 'during installation' do
before do
- @installer = create_apt 'ruby'
- @install_sequence = @installer.send :install_sequence
+ @installer = create_apt 'ruby' do
+ pre :install, 'op1'
+ post :install, 'op2'
+ end
+ @install_commands = @installer.send :install_commands
end
it 'should invoke the apt installer for all specified packages' do
- @install_sequence.should =~ /apt-get -qyu install ruby/
+ @install_commands.should =~ /apt-get -qyu install ruby/
end
it 'should specify a non interactive mode to the apt installer' do
- @install_sequence.should =~ /DEBIAN_FRONTEND=noninteractive/
+ @install_commands.should =~ /DEBIAN_FRONTEND=noninteractive/
+ end
+
+ it 'should automatically insert pre/post commands for the specified package' do
+ @installer.send(:install_sequence).should == [ 'op1', %(DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive apt-get -qyu install ruby), 'op2' ]
end
it 'should install a specific version if defined'
@@ -42,11 +42,18 @@ def create_gem(gem, version = nil, options = {}, &block)
describe 'without a version' do
before do
- @installer = create_gem @gem
+ @installer = create_gem @gem do
+ pre :install, 'op1'
+ post :install, 'op2'
+ end
end
- it 'should invoke the gem installer for all specified package' do
- @installer.send(:install_sequence).should == "gem install #{@gem}"
+ it 'should invoke the gem installer for the specified package' do
+ @installer.send(:install_commands).should == "gem install #{@gem}"
+ end
+
+ it 'should automatically insert pre/post commands for the specified package' do
+ @installer.send(:install_sequence).should == [ 'op1', "gem install #{@gem}", 'op2' ]
end
end
@@ -58,7 +65,7 @@ def create_gem(gem, version = nil, options = {}, &block)
end
it 'should install a specific version if defined' do
- @installer.send(:install_sequence).should == "gem install #{@gem} --version '#{@version}'"
+ @installer.send(:install_commands).should == "gem install #{@gem} --version '#{@version}'"
end
end
@@ -86,7 +86,7 @@ def install_sequence
end
- describe Sprinkle::Installers::Installer, 'during installation' do
+ describe 'during installation' do
it 'should request the install sequence from the concrete class' do
@installer.should_receive(:install_sequence).and_return(@sequence)
@@ -27,12 +27,19 @@ def create_rpm(debs, &block)
describe 'during installation' do
before do
- @installer = create_rpm 'ruby'
- @install_sequence = @installer.send :install_sequence
+ @installer = create_rpm 'ruby' do
+ pre :install, 'op1'
+ post :install, 'op2'
+ end
+ @install_commands = @installer.send :install_commands
+ end
+
+ it 'should invoke the rpm installer for all specified packages' do
+ @install_commands.should =~ /rpm -Uvh ruby/
end
- it 'should invoke the apt installer for all specified packages' do
- @install_sequence.should =~ /rpm -Uvh ruby/
+ it 'should automatically insert pre/post commands for the specified package' do
+ @installer.send(:install_sequence).should == [ 'op1', 'rpm -Uvh ruby', 'op2' ]
end
it 'should specify a non interactive mode to the apt installer'
View
@@ -1,27 +1,43 @@
Gem::Specification.new do |s|
s.name = %q{sprinkle}
- s.version = "0.1.2"
-
- s.specification_version = 2 if s.respond_to? :specification_version=
+ s.version = "0.1.4"
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
s.authors = ["Marcus Crafter"]
- s.date = %q{2008-06-03}
+ s.date = %q{2008-07-13}
s.default_executable = %q{sprinkle}
s.description = %q{Ruby DSL based software provisioning tool}
s.email = ["crafterm@redartisan.com"]
s.executables = ["sprinkle"]
s.extra_rdoc_files = ["History.txt", "Manifest.txt", "README.txt"]
- s.files = ["CREDITS", "History.txt", "MIT-LICENSE", "Manifest.txt", "README.txt", "Rakefile", "bin/sprinkle", "config/hoe.rb", "config/requirements.rb", "examples/merb/deploy.rb", "examples/rails/README", "examples/rails/deploy.rb", "examples/rails/packages/database.rb", "examples/rails/packages/essential.rb", "examples/rails/packages/rails.rb", "examples/rails/packages/search.rb", "examples/rails/packages/server.rb", "examples/rails/rails.rb", "examples/sprinkle/deploy.rb", "examples/sprinkle/sprinkle.rb", "lib/sprinkle.rb", "lib/sprinkle/actors/capistrano.rb", "lib/sprinkle/actors/vlad.rb", "lib/sprinkle/deployment.rb", "lib/sprinkle/extensions/arbitrary_options.rb", "lib/sprinkle/extensions/array.rb", "lib/sprinkle/extensions/blank_slate.rb", "lib/sprinkle/extensions/dsl_accessor.rb", "lib/sprinkle/extensions/string.rb", "lib/sprinkle/extensions/symbol.rb", "lib/sprinkle/installers/apt.rb", "lib/sprinkle/installers/gem.rb", "lib/sprinkle/installers/installer.rb", "lib/sprinkle/installers/rake.rb", "lib/sprinkle/installers/rpm.rb", "lib/sprinkle/installers/source.rb", "lib/sprinkle/package.rb", "lib/sprinkle/policy.rb", "lib/sprinkle/script.rb", "lib/sprinkle/version.rb", "script/destroy", "script/generate", "spec/spec.opts", "spec/spec_helper.rb", "spec/sprinkle/actors/capistrano_spec.rb", "spec/sprinkle/deployment_spec.rb", "spec/sprinkle/extensions/array_spec.rb", "spec/sprinkle/extensions/string_spec.rb", "spec/sprinkle/installers/apt_spec.rb", "spec/sprinkle/installers/gem_spec.rb", "spec/sprinkle/installers/installer_spec.rb", "spec/sprinkle/installers/rpm_spec.rb", "spec/sprinkle/installers/source_spec.rb", "spec/sprinkle/package_spec.rb", "spec/sprinkle/policy_spec.rb", "spec/sprinkle/script_spec.rb", "spec/sprinkle/sprinkle_spec.rb", "sprinkle.gemspec", "tasks/deployment.rake", "tasks/environment.rake", "tasks/rspec.rake", "thoughts.txt"]
+ s.files = ["CREDITS", "History.txt", "MIT-LICENSE", "Manifest.txt", "README.txt", "Rakefile", "bin/sprinkle", "config/hoe.rb", "config/requirements.rb", "examples/merb/deploy.rb", "examples/rails/README", "examples/rails/deploy.rb", "examples/rails/packages/database.rb", "examples/rails/packages/essential.rb", "examples/rails/packages/rails.rb", "examples/rails/packages/search.rb", "examples/rails/packages/server.rb", "examples/rails/rails.rb", "examples/sprinkle/sprinkle.rb", "lib/sprinkle.rb", "lib/sprinkle/actors/capistrano.rb", "lib/sprinkle/actors/vlad.rb", "lib/sprinkle/deployment.rb", "lib/sprinkle/extensions/arbitrary_options.rb", "lib/sprinkle/extensions/array.rb", "lib/sprinkle/extensions/blank_slate.rb", "lib/sprinkle/extensions/dsl_accessor.rb", "lib/sprinkle/extensions/string.rb", "lib/sprinkle/extensions/symbol.rb", "lib/sprinkle/installers/apt.rb", "lib/sprinkle/installers/gem.rb", "lib/sprinkle/installers/installer.rb", "lib/sprinkle/installers/rake.rb", "lib/sprinkle/installers/rpm.rb", "lib/sprinkle/installers/source.rb", "lib/sprinkle/package.rb", "lib/sprinkle/policy.rb", "lib/sprinkle/script.rb", "lib/sprinkle/version.rb", "script/destroy", "script/generate", "spec/spec.opts", "spec/spec_helper.rb", "spec/sprinkle/actors/capistrano_spec.rb", "spec/sprinkle/deployment_spec.rb", "spec/sprinkle/extensions/array_spec.rb", "spec/sprinkle/extensions/string_spec.rb", "spec/sprinkle/installers/apt_spec.rb", "spec/sprinkle/installers/gem_spec.rb", "spec/sprinkle/installers/installer_spec.rb", "spec/sprinkle/installers/rpm_spec.rb", "spec/sprinkle/installers/source_spec.rb", "spec/sprinkle/package_spec.rb", "spec/sprinkle/policy_spec.rb", "spec/sprinkle/script_spec.rb", "spec/sprinkle/sprinkle_spec.rb", "sprinkle.gemspec", "tasks/deployment.rake", "tasks/environment.rake", "tasks/rspec.rake"]
s.has_rdoc = true
s.homepage = %q{http://sprinkle.rubyforge.org}
s.rdoc_options = ["--main", "README.txt"]
s.require_paths = ["lib"]
s.rubyforge_project = %q{sprinkle}
- s.rubygems_version = %q{1.1.1}
+ s.rubygems_version = %q{1.2.0}
s.summary = %q{Ruby DSL based software provisioning tool}
- s.add_dependency(%q<activesupport>, [">= 2.0.2"])
- s.add_dependency(%q<highline>, [">= 1.4.0"])
- s.add_dependency(%q<capistrano>, [">= 2.2.0"])
+ if s.respond_to? :specification_version then
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
+ s.specification_version = 2
+
+ if current_version >= 3 then
+ s.add_runtime_dependency(%q<activesupport>, [">= 2.0.2"])
+ s.add_runtime_dependency(%q<highline>, [">= 1.4.0"])
+ s.add_runtime_dependency(%q<capistrano>, [">= 2.2.0"])
+ s.add_development_dependency(%q<hoe>, [">= 1.7.0"])
+ else
+ s.add_dependency(%q<activesupport>, [">= 2.0.2"])
+ s.add_dependency(%q<highline>, [">= 1.4.0"])
+ s.add_dependency(%q<capistrano>, [">= 2.2.0"])
+ s.add_dependency(%q<hoe>, [">= 1.7.0"])
+ end
+ else
+ s.add_dependency(%q<activesupport>, [">= 2.0.2"])
+ s.add_dependency(%q<highline>, [">= 1.4.0"])
+ s.add_dependency(%q<capistrano>, [">= 2.2.0"])
+ s.add_dependency(%q<hoe>, [">= 1.7.0"])
+ end
end

0 comments on commit b26a937

Please sign in to comment.