jsierles-sprinkle 0.1.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (89) hide show
  1. data/CREDITS +19 -0
  2. data/History.txt +4 -0
  3. data/MIT-LICENSE +20 -0
  4. data/Manifest.txt +87 -0
  5. data/README.txt +238 -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/packages/build_essential.rb +9 -0
  11. data/examples/packages/databases/mysql.rb +13 -0
  12. data/examples/packages/databases/sqlite3.rb +16 -0
  13. data/examples/packages/phusion.rb +55 -0
  14. data/examples/packages/ruby/rails.rb +9 -0
  15. data/examples/packages/ruby/ruby.rb +17 -0
  16. data/examples/packages/ruby/rubygems.rb +17 -0
  17. data/examples/packages/scm/git.rb +11 -0
  18. data/examples/packages/scm/subversion.rb +4 -0
  19. data/examples/packages/servers/apache.rb +15 -0
  20. data/examples/rails/README +15 -0
  21. data/examples/rails/deploy.rb +2 -0
  22. data/examples/rails/packages/database.rb +9 -0
  23. data/examples/rails/packages/essential.rb +9 -0
  24. data/examples/rails/packages/rails.rb +28 -0
  25. data/examples/rails/packages/scm.rb +11 -0
  26. data/examples/rails/packages/search.rb +11 -0
  27. data/examples/rails/packages/server.rb +28 -0
  28. data/examples/rails/rails.rb +73 -0
  29. data/examples/sprinkle/sprinkle.rb +38 -0
  30. data/lib/sprinkle.rb +32 -0
  31. data/lib/sprinkle/actors/actors.rb +17 -0
  32. data/lib/sprinkle/actors/capistrano.rb +117 -0
  33. data/lib/sprinkle/actors/local.rb +26 -0
  34. data/lib/sprinkle/actors/ssh.rb +81 -0
  35. data/lib/sprinkle/actors/vlad.rb +65 -0
  36. data/lib/sprinkle/configurable.rb +31 -0
  37. data/lib/sprinkle/deployment.rb +73 -0
  38. data/lib/sprinkle/extensions/arbitrary_options.rb +10 -0
  39. data/lib/sprinkle/extensions/array.rb +5 -0
  40. data/lib/sprinkle/extensions/blank_slate.rb +5 -0
  41. data/lib/sprinkle/extensions/dsl_accessor.rb +15 -0
  42. data/lib/sprinkle/extensions/string.rb +10 -0
  43. data/lib/sprinkle/extensions/symbol.rb +7 -0
  44. data/lib/sprinkle/installers/apt.rb +52 -0
  45. data/lib/sprinkle/installers/deb.rb +38 -0
  46. data/lib/sprinkle/installers/gem.rb +62 -0
  47. data/lib/sprinkle/installers/installer.rb +120 -0
  48. data/lib/sprinkle/installers/rake.rb +37 -0
  49. data/lib/sprinkle/installers/rpm.rb +37 -0
  50. data/lib/sprinkle/installers/source.rb +179 -0
  51. data/lib/sprinkle/installers/yum.rb +37 -0
  52. data/lib/sprinkle/package.rb +233 -0
  53. data/lib/sprinkle/policy.rb +125 -0
  54. data/lib/sprinkle/script.rb +23 -0
  55. data/lib/sprinkle/verifiers/directory.rb +16 -0
  56. data/lib/sprinkle/verifiers/executable.rb +36 -0
  57. data/lib/sprinkle/verifiers/file.rb +20 -0
  58. data/lib/sprinkle/verifiers/process.rb +21 -0
  59. data/lib/sprinkle/verifiers/ruby.rb +25 -0
  60. data/lib/sprinkle/verifiers/symlink.rb +30 -0
  61. data/lib/sprinkle/verify.rb +114 -0
  62. data/lib/sprinkle/version.rb +9 -0
  63. data/script/destroy +14 -0
  64. data/script/generate +14 -0
  65. data/spec/spec.opts +1 -0
  66. data/spec/spec_helper.rb +17 -0
  67. data/spec/sprinkle/actors/capistrano_spec.rb +170 -0
  68. data/spec/sprinkle/actors/local_spec.rb +29 -0
  69. data/spec/sprinkle/configurable_spec.rb +46 -0
  70. data/spec/sprinkle/deployment_spec.rb +80 -0
  71. data/spec/sprinkle/extensions/array_spec.rb +19 -0
  72. data/spec/sprinkle/extensions/string_spec.rb +21 -0
  73. data/spec/sprinkle/installers/apt_spec.rb +70 -0
  74. data/spec/sprinkle/installers/gem_spec.rb +75 -0
  75. data/spec/sprinkle/installers/installer_spec.rb +151 -0
  76. data/spec/sprinkle/installers/rake_spec.rb +29 -0
  77. data/spec/sprinkle/installers/rpm_spec.rb +50 -0
  78. data/spec/sprinkle/installers/source_spec.rb +331 -0
  79. data/spec/sprinkle/installers/yum_spec.rb +49 -0
  80. data/spec/sprinkle/package_spec.rb +422 -0
  81. data/spec/sprinkle/policy_spec.rb +126 -0
  82. data/spec/sprinkle/script_spec.rb +51 -0
  83. data/spec/sprinkle/sprinkle_spec.rb +25 -0
  84. data/spec/sprinkle/verify_spec.rb +160 -0
  85. data/sprinkle.gemspec +70 -0
  86. data/tasks/deployment.rake +34 -0
  87. data/tasks/environment.rake +7 -0
  88. data/tasks/rspec.rake +21 -0
  89. metadata +180 -0
@@ -0,0 +1,10 @@
1
+ module ArbitraryOptions #:nodoc:
2
+ def self.included(base)
3
+ base.alias_method_chain :method_missing, :arbitrary_options
4
+ end
5
+
6
+ def method_missing_with_arbitrary_options(sym, *args, &block)
7
+ self.class.dsl_accessor sym
8
+ send(sym, *args, &block)
9
+ end
10
+ end
@@ -0,0 +1,5 @@
1
+ class Array #:nodoc:
2
+ def to_task_name
3
+ collect(&:to_task_name).join('_')
4
+ end
5
+ end
@@ -0,0 +1,5 @@
1
+ class BlankSlate #:nodoc:
2
+ instance_methods.each do |m|
3
+ undef_method(m) unless %w( __send__ __id__ send class inspect instance_eval instance_variables ).include?(m)
4
+ end
5
+ end
@@ -0,0 +1,15 @@
1
+ class Module #:nodoc:
2
+ def dsl_accessor(*symbols)
3
+ symbols.each do |sym|
4
+ class_eval %{
5
+ def #{sym}(*val)
6
+ if val.empty?
7
+ @#{sym}
8
+ else
9
+ @#{sym} = val.size == 1 ? val[0] : val
10
+ end
11
+ end
12
+ }
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,10 @@
1
+ class String #:nodoc:
2
+
3
+ # REVISIT: what chars shall we allow in task names?
4
+ def to_task_name
5
+ s = downcase
6
+ s.gsub!(/-/, '_') # all - to _ chars
7
+ s
8
+ end
9
+
10
+ end
@@ -0,0 +1,7 @@
1
+ class Symbol #:nodoc:
2
+
3
+ def to_task_name
4
+ to_s.to_task_name
5
+ end
6
+
7
+ end
@@ -0,0 +1,52 @@
1
+ module Sprinkle
2
+ module Installers
3
+ # = Apt Package Installer
4
+ #
5
+ # The Apt package installer uses the +apt-get+ command to install
6
+ # packages. The apt installer has only one option which can be
7
+ # modified which is the +dependencies_only+ option. When this is
8
+ # set to true, the installer uses +build-dep+ instead of +install+
9
+ # to only build the dependencies.
10
+ #
11
+ # == Example Usage
12
+ #
13
+ # First, a simple installation of the magic_beans package:
14
+ #
15
+ # package :magic_beans do
16
+ # description "Beans beans they're good for your heart..."
17
+ # apt 'magic_beans_package'
18
+ # end
19
+ #
20
+ # Second, only build the magic_beans dependencies:
21
+ #
22
+ # package :magic_beans_depends do
23
+ # apt 'magic_beans_package' { dependencies_only true }
24
+ # end
25
+ #
26
+ # As you can see, setting options is as simple as creating a
27
+ # block and calling the option as a method with the value as
28
+ # its parameter.
29
+ class Apt < Installer
30
+ attr_accessor :packages #:nodoc:
31
+
32
+ def initialize(parent, *packages, &block) #:nodoc:
33
+ packages.flatten!
34
+
35
+ options = { :dependencies_only => false }
36
+ options.update(packages.pop) if packages.last.is_a?(Hash)
37
+
38
+ super parent, options, &block
39
+
40
+ @packages = packages
41
+ end
42
+
43
+ protected
44
+
45
+ def install_commands #:nodoc:
46
+ command = @options[:dependencies_only] ? 'build-dep' : 'install'
47
+ "DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive apt-get -qyu #{command} #{@packages.join(' ')}"
48
+ end
49
+
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,38 @@
1
+ module Sprinkle
2
+ module Installers
3
+ # = Deb Package Installer
4
+ #
5
+ # The Deb installer installs deb packages sourced from a remote URL
6
+ #
7
+ # == Example Usage
8
+ #
9
+ # Installing the magic_beans deb.
10
+ #
11
+ # package :magic_beans do
12
+ # deb 'http://debs.example.com/magic_beans.deb'
13
+ # end
14
+ #
15
+ class Deb < Installer
16
+ attr_accessor :packages #:nodoc:
17
+
18
+ def initialize(parent, packages, &block) #:nodoc:
19
+ super parent, &block
20
+ packages = [packages] unless packages.is_a? Array
21
+ @packages = packages
22
+ end
23
+
24
+ protected
25
+
26
+ def install_commands #:nodoc:
27
+ "wget -cq --directory-prefix=/tmp #{@packages.join(' ')}; dpkg -i #{@packages.collect{|p| "/tmp/#{package_name(p)}"}.join(" ")}"
28
+ end
29
+
30
+ private
31
+
32
+ def package_name(url)
33
+ url.split('/').last
34
+ end
35
+
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,62 @@
1
+ module Sprinkle
2
+ module Installers
3
+ # = Ruby Gem Package Installer
4
+ #
5
+ # The gem package installer installs ruby gems.
6
+ #
7
+ # The installer has a single optional configuration: source.
8
+ # By changing source you can specify a given ruby gems
9
+ # repository from which to install.
10
+ #
11
+ # == Example Usage
12
+ #
13
+ # First, a simple installation of the magic_beans gem:
14
+ #
15
+ # package :magic_beans do
16
+ # description "Beans beans they're good for your heart..."
17
+ # gem 'magic_beans'
18
+ # end
19
+ #
20
+ # Second, install magic_beans gem from github:
21
+ #
22
+ # package :magic_beans do
23
+ # gem 'magic_beans_package' do
24
+ # source 'http://gems.github.com'
25
+ # end
26
+ # end
27
+ #
28
+ # As you can see, setting options is as simple as creating a
29
+ # block and calling the option as a method with the value as
30
+ # its parameter.
31
+ class Gem < Installer
32
+ attr_accessor :gem #:nodoc:
33
+
34
+ def initialize(parent, gem, options = {}, &block) #:nodoc:
35
+ super parent, options, &block
36
+ @gem = gem
37
+ end
38
+
39
+ def source(location = nil) #:nodoc:
40
+ # package defines an installer called source so here we specify a method directly
41
+ # rather than rely on the automatic options processing since packages' method missing
42
+ # won't be run
43
+ return @options[:source] unless location
44
+ @options[:source] = location
45
+ end
46
+
47
+ protected
48
+
49
+ # rubygems 0.9.5+ installs dependencies by default, and does platform selection
50
+
51
+ def install_commands #:nodoc:
52
+ cmd = "gem install #{gem}"
53
+ cmd << " --version '#{version}'" if version
54
+ cmd << " --source #{source}" if source
55
+ cmd << " --install-dir #{repository}" if option?(:repository)
56
+ cmd << " --no-rdoc --no-ri" unless option?(:build_docs)
57
+ cmd
58
+ end
59
+
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,120 @@
1
+ module Sprinkle
2
+ module Installers
3
+ # The base class which all installers must subclass, this class makes
4
+ # sure all installers share some general features, which are outlined
5
+ # below.
6
+ #
7
+ # = Pre/Post Installation Hooks
8
+ #
9
+ # With all intallation methods you have the ability to specify multiple
10
+ # pre/post installation hooks. This gives you the ability to specify
11
+ # commands to run before and after an installation takes place. All
12
+ # commands by default are sudo'd so there is no need to include "sudo"
13
+ # in the command itself. There are three ways to specify a pre/post hook.
14
+ #
15
+ # First, a single command:
16
+ #
17
+ # pre :install, 'echo "Hello, World!"'
18
+ # post :install, 'rm -rf /'
19
+ #
20
+ # Second, an array of commands:
21
+ #
22
+ # commands = ['echo "First"', 'echo "Then Another"']
23
+ # pre :install, commands
24
+ # post :install, commands
25
+ #
26
+ # Third, a block which returns either a single or multiple commands:
27
+ #
28
+ # pre :install do
29
+ # amount = 7 * 3
30
+ # "echo 'Before we install, lets plant #{amount} magic beans...'"
31
+ # end
32
+ # post :install do
33
+ # ['echo "Now... let's hope they sprout!", 'echo "Indeed they have!"']
34
+ # end
35
+ #
36
+ # = Other Pre/Post Hooks
37
+ #
38
+ # Some installation methods actually grant you more fine grained
39
+ # control of when commands are run rather than a blanket pre :install
40
+ # or post :install. If this is the case, it will be documented on
41
+ # the installation method's corresponding documentation page.
42
+ class Installer
43
+ include Sprinkle::Configurable
44
+ attr_accessor :delivery, :package, :options, :pre, :post #:nodoc:
45
+
46
+ def initialize(package, options = {}, &block) #:nodoc:
47
+ @package = package
48
+ @options = options
49
+ @pre = {}; @post = {}
50
+ self.instance_eval(&block) if block
51
+ end
52
+
53
+ def pre(stage, *commands)
54
+ @pre[stage] ||= []
55
+ @pre[stage] += commands
56
+ @pre[stage] += [yield] if block_given?
57
+ end
58
+
59
+ def post(stage, *commands)
60
+ @post[stage] ||= []
61
+ @post[stage] += commands
62
+ @post[stage] += [yield] if block_given?
63
+ end
64
+
65
+ def process(roles) #:nodoc:
66
+ assert_delivery
67
+
68
+ if logger.debug?
69
+ sequence = install_sequence; sequence = sequence.join('; ') if sequence.is_a? Array
70
+ logger.debug "#{@package.name} install sequence: #{sequence} for roles: #{roles}\n"
71
+ end
72
+
73
+ unless Sprinkle::OPTIONS[:testing]
74
+ logger.info "--> Installing #{package.name} for roles: #{roles}"
75
+ @delivery.process(@package.name, install_sequence, roles)
76
+ end
77
+ end
78
+
79
+ protected
80
+ # More complicated installers that have different stages, and require pre/post commands
81
+ # within stages can override install_sequence and take complete control of the install
82
+ # command sequence construction (eg. source based installer).
83
+ def install_sequence
84
+ commands = pre_commands(:install) + [ install_commands ] + post_commands(:install)
85
+ commands.flatten
86
+ end
87
+
88
+ # A concrete installer (subclass of this virtual class) must override this method
89
+ # and return the commands it needs to run as either a string or an array.
90
+ #
91
+ # <b>Overriding this method is required.</b>
92
+ def install_commands
93
+ raise 'Concrete installers implement this to specify commands to run to install their respective packages'
94
+ end
95
+
96
+ def pre_commands(stage) #:nodoc:
97
+ dress @pre[stage] || [], :pre
98
+ end
99
+
100
+ def post_commands(stage) #:nodoc:
101
+ dress @post[stage] || [], :post
102
+ end
103
+
104
+ # Concrete installers (subclasses of this virtual class) can override this method to
105
+ # specify stage-specific (pre-installation, post-installation, etc.) modifications
106
+ # of commands.
107
+ #
108
+ # An example usage of overriding this would be to prefix all commands for a
109
+ # certain stage to change to a certain directory. An example is given below:
110
+ #
111
+ # def dress(commands, stage)
112
+ # commands.collect { |x| "cd #{magic_beans_path} && #{x}" }
113
+ # end
114
+ #
115
+ # By default, no modifications are made to the commands.
116
+ def dress(commands, stage); commands; end
117
+
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,37 @@
1
+ module Sprinkle
2
+ module Installers
3
+ # = Rake Installer
4
+ #
5
+ # This installer runs a rake command.
6
+ #
7
+ # == Example Usage
8
+ #
9
+ # The following example runs the command "rake spec" on
10
+ # the remote server.
11
+ #
12
+ # package :spec do
13
+ # rake 'spec'
14
+ # end
15
+ #
16
+ # Specify a Rakefile with the :rakefile option.
17
+ #
18
+ # package :spec, :rakefile => "/var/setup/Rakefile" do
19
+ # rake 'spec'
20
+ # end
21
+
22
+ class Rake < Installer
23
+ def initialize(parent, commands = [], options = {}, &block) #:nodoc:
24
+ super parent, options, &block
25
+ @commands = commands.to_a
26
+ end
27
+
28
+ protected
29
+
30
+ def install_commands #:nodoc:
31
+ file = @options[:rakefile] ? "-f #{@options[:rakefile]} " : ""
32
+ "rake #{file}#{@commands.join(' ')}"
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,37 @@
1
+ module Sprinkle
2
+ module Installers
3
+ # = RPM Package Installer
4
+ #
5
+ # The RPM package installer installs RPM packages.
6
+ #
7
+ # == Example Usage
8
+ #
9
+ # Installing the magic_beans RPM. Its all the craze these days.
10
+ #
11
+ # package :magic_beans do
12
+ # rpm 'magic_beans'
13
+ # end
14
+ #
15
+ # You may also specify multiple rpms as an array:
16
+ #
17
+ # package :magic_beans do
18
+ # rpm %w(magic_beans magic_sauce)
19
+ # end
20
+ class Rpm < Installer
21
+ attr_accessor :packages #:nodoc:
22
+
23
+ def initialize(parent, packages, &block) #:nodoc:
24
+ super parent, &block
25
+ packages = [packages] unless packages.is_a? Array
26
+ @packages = packages
27
+ end
28
+
29
+ protected
30
+
31
+ def install_commands #:nodoc:
32
+ "rpm -Uvh #{@packages.join(' ')}"
33
+ end
34
+
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,179 @@
1
+ module Sprinkle
2
+ module Installers
3
+ # = Source Package Installer
4
+ #
5
+ # The source package installer installs software from source.
6
+ # It handles downloading, extracting, configuring, building,
7
+ # and installing software.
8
+ #
9
+ # == Configuration Options
10
+ #
11
+ # The source installer has many configuration options:
12
+ # * <b>prefix</b> - The prefix directory that is configured to.
13
+ # * <b>archives</b> - The location all the files are downloaded to.
14
+ # * <b>builds</b> - The directory the package is extracted to to configure and install
15
+ #
16
+ # == Pre/Post Hooks
17
+ #
18
+ # The source installer defines a myriad of new stages which can be hooked into:
19
+ # * <b>prepare</b> - Prepare is the stage which all the prefix, archives, and build directories are made.
20
+ # * <b>download</b> - Download is the stage which the software package is downloaded.
21
+ # * <b>extract</b> - Extract is the stage which the software package is extracted.
22
+ # * <b>configure</b> - Configure is the stage which the ./configure script is run.
23
+ # * <b>build</b> - Build is the stage in which `make` is called.
24
+ # * <b>install</b> - Install is the stage which `make install` is called.
25
+ #
26
+ # == Example Usage
27
+ #
28
+ # First, a simple package, no configuration:
29
+ #
30
+ # package :magic_beans do
31
+ # source 'http://magicbeansland.com/latest-1.1.1.tar.gz'
32
+ # end
33
+ #
34
+ # Second, specifying exactly where I want my files:
35
+ #
36
+ # package :magic_beans do
37
+ # source 'http://magicbeansland.com/latest-1.1.1.tar.gz' do
38
+ # prefix '/usr/local'
39
+ # archives '/tmp'
40
+ # builds '/tmp/builds'
41
+ # end
42
+ # end
43
+ #
44
+ # Third, specifying some hooks:
45
+ #
46
+ # package :magic_beans do
47
+ # source 'http://magicbeansland.com/latest-1.1.1.tar.gz' do
48
+ # prefix '/usr/local'
49
+ #
50
+ # pre :prepare { 'echo "Here we go folks."' }
51
+ # post :extract { 'echo "I believe..."' }
52
+ # pre :build { 'echo "Cross your fingers!"' }
53
+ # end
54
+ # end
55
+ #
56
+ # As you can see, setting options is as simple as creating a
57
+ # block and calling the option as a method with the value as
58
+ # its parameter.
59
+ class Source < Installer
60
+ attr_accessor :source #:nodoc:
61
+
62
+ def initialize(parent, source, options = {}, &block) #:nodoc:
63
+ @source = source
64
+ super parent, options, &block
65
+ end
66
+
67
+ protected
68
+
69
+ def install_sequence #:nodoc:
70
+ prepare + download + extract + configure + build + install
71
+ end
72
+
73
+ %w( prepare download extract configure build install ).each do |stage|
74
+ define_method stage do
75
+ pre_commands(stage.to_sym) + self.send("#{stage}_commands") + post_commands(stage.to_sym)
76
+ end
77
+ end
78
+
79
+ def prepare_commands #:nodoc:
80
+ raise 'No installation area defined' unless @options[:prefix]
81
+ raise 'No build area defined' unless @options[:builds]
82
+ raise 'No source download area defined' unless @options[:archives]
83
+
84
+ [ "mkdir -p #{@options[:prefix]}",
85
+ "mkdir -p #{@options[:builds]}",
86
+ "mkdir -p #{@options[:archives]}" ]
87
+ end
88
+
89
+ def download_commands #:nodoc:
90
+ [ "wget -cq --directory-prefix='#{@options[:archives]}' #{@source}" ]
91
+ end
92
+
93
+ def extract_commands #:nodoc:
94
+ [ "bash -c 'cd #{@options[:builds]} && #{extract_command} #{@options[:archives]}/#{archive_name}'" ]
95
+ end
96
+
97
+ def configure_commands #:nodoc:
98
+ return [] if custom_install?
99
+
100
+ command = "bash -c 'cd #{build_dir} && ./configure --prefix=#{@options[:prefix]} "
101
+
102
+ extras = {
103
+ :enable => '--enable', :disable => '--disable',
104
+ :with => '--with', :without => '--without'
105
+ }
106
+
107
+ extras.inject(command) { |m, (k, v)| m << create_options(k, v) if options[k]; m }
108
+
109
+ [ command << " > #{@package.name}-configure.log 2>&1'" ]
110
+ end
111
+
112
+ def build_commands #:nodoc:
113
+ return [] if custom_install?
114
+ [ "bash -c 'cd #{build_dir} && make > #{@package.name}-build.log 2>&1'" ]
115
+ end
116
+
117
+ def install_commands #:nodoc:
118
+ return custom_install_commands if custom_install?
119
+ [ "bash -c 'cd #{build_dir} && make install > #{@package.name}-install.log 2>&1'" ]
120
+ end
121
+
122
+ def custom_install? #:nodoc:
123
+ !! @options[:custom_install]
124
+ end
125
+
126
+ # REVISIT: must be better processing of custom install commands somehow? use splat operator?
127
+ def custom_install_commands #:nodoc:
128
+ dress @options[:custom_install], :install
129
+ end
130
+
131
+ protected
132
+
133
+ # dress is overriden from the base Sprinkle::Installers::Installer class so that the command changes
134
+ # directory to the build directory first. Also, the result of the command is logged.
135
+ def dress(commands, stage)
136
+ commands.collect { |command| "bash -c 'cd #{build_dir} && #{command} >> #{@package.name}-#{stage}.log 2>&1'" }
137
+ end
138
+
139
+ private
140
+
141
+ def create_options(key, prefix) #:nodoc:
142
+ @options[key].inject(' ') { |m, option| m << "#{prefix}-#{option} "; m }
143
+ end
144
+
145
+ def extract_command #:nodoc:
146
+ case @source
147
+ when /(tar.gz)|(tgz)$/
148
+ 'tar xzf'
149
+ when /(tar.bz2)|(tb2)$/
150
+ 'tar xjf'
151
+ when /tar$/
152
+ 'tar xf'
153
+ when /zip$/
154
+ 'unzip'
155
+ else
156
+ raise "Unknown source archive format: #{archive_name}"
157
+ end
158
+ end
159
+
160
+ def archive_name #:nodoc:
161
+ name = @source.split('/').last
162
+ raise "Unable to determine archive name for source: #{source}, please update code knowledge" unless name
163
+ name
164
+ end
165
+
166
+ def build_dir #:nodoc:
167
+ "#{@options[:builds]}/#{options[:custom_dir] || base_dir}"
168
+ end
169
+
170
+ def base_dir #:nodoc:
171
+ if @source.split('/').last =~ /(.*)\.(tar\.gz|tgz|tar\.bz2|tb2)/
172
+ return $1
173
+ end
174
+ raise "Unknown base path for source archive: #{@source}, please update code knowledge"
175
+ end
176
+
177
+ end
178
+ end
179
+ end