sprinkle 0.1.4
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.
- data/CREDITS +14 -0
- data/History.txt +4 -0
- data/MIT-LICENSE +20 -0
- data/Manifest.txt +63 -0
- data/README.rdoc +218 -0
- data/Rakefile +4 -0
- data/TODO +56 -0
- data/bin/sprinkle +79 -0
- data/config/hoe.rb +70 -0
- data/config/requirements.rb +17 -0
- data/examples/merb/deploy.rb +5 -0
- data/examples/rails/README +15 -0
- data/examples/rails/deploy.rb +2 -0
- data/examples/rails/packages/database.rb +9 -0
- data/examples/rails/packages/essential.rb +6 -0
- data/examples/rails/packages/rails.rb +28 -0
- data/examples/rails/packages/search.rb +11 -0
- data/examples/rails/packages/server.rb +28 -0
- data/examples/rails/rails.rb +71 -0
- data/examples/sprinkle/sprinkle.rb +38 -0
- data/lib/sprinkle/actors/capistrano.rb +80 -0
- data/lib/sprinkle/actors/vlad.rb +30 -0
- data/lib/sprinkle/deployment.rb +33 -0
- data/lib/sprinkle/extensions/arbitrary_options.rb +10 -0
- data/lib/sprinkle/extensions/array.rb +7 -0
- data/lib/sprinkle/extensions/blank_slate.rb +5 -0
- data/lib/sprinkle/extensions/dsl_accessor.rb +15 -0
- data/lib/sprinkle/extensions/string.rb +10 -0
- data/lib/sprinkle/extensions/symbol.rb +7 -0
- data/lib/sprinkle/installers/apt.rb +20 -0
- data/lib/sprinkle/installers/gem.rb +33 -0
- data/lib/sprinkle/installers/installer.rb +85 -0
- data/lib/sprinkle/installers/rake.rb +17 -0
- data/lib/sprinkle/installers/rpm.rb +20 -0
- data/lib/sprinkle/installers/source.rb +120 -0
- data/lib/sprinkle/package.rb +94 -0
- data/lib/sprinkle/policy.rb +85 -0
- data/lib/sprinkle/script.rb +13 -0
- data/lib/sprinkle/sequence.rb +21 -0
- data/lib/sprinkle/version.rb +9 -0
- data/lib/sprinkle.rb +26 -0
- data/script/destroy +14 -0
- data/script/generate +14 -0
- data/spec/spec.opts +1 -0
- data/spec/spec_helper.rb +17 -0
- data/spec/sprinkle/actors/capistrano_spec.rb +150 -0
- data/spec/sprinkle/deployment_spec.rb +80 -0
- data/spec/sprinkle/extensions/array_spec.rb +19 -0
- data/spec/sprinkle/extensions/string_spec.rb +21 -0
- data/spec/sprinkle/installers/apt_spec.rb +53 -0
- data/spec/sprinkle/installers/gem_spec.rb +75 -0
- data/spec/sprinkle/installers/installer_spec.rb +125 -0
- data/spec/sprinkle/installers/rpm_spec.rb +50 -0
- data/spec/sprinkle/installers/source_spec.rb +315 -0
- data/spec/sprinkle/package_spec.rb +247 -0
- data/spec/sprinkle/policy_spec.rb +126 -0
- data/spec/sprinkle/script_spec.rb +51 -0
- data/spec/sprinkle/sequence_spec.rb +44 -0
- data/spec/sprinkle/sprinkle_spec.rb +25 -0
- data/sprinkle.gemspec +43 -0
- data/tasks/deployment.rake +34 -0
- data/tasks/environment.rake +7 -0
- data/tasks/rspec.rake +21 -0
- metadata +157 -0
@@ -0,0 +1,71 @@
|
|
1
|
+
#!/usr/bin/env sprinkle -s
|
2
|
+
|
3
|
+
# Annotated Example Sprinkle Rails deployment script
|
4
|
+
#
|
5
|
+
# This is an example Sprinkle script configured to install Rails from gems, Apache, Ruby and
|
6
|
+
# Sphinx from source, and mysql from apt on an Ubuntu system.
|
7
|
+
#
|
8
|
+
# Installation is configured to run via capistrano (and an accompanying deploy.rb recipe script).
|
9
|
+
# Source based packages are downloaded and built into /usr/local on the remote system.
|
10
|
+
#
|
11
|
+
# A sprinkle script is separated into 3 different sections. Packages, policies and deployment:
|
12
|
+
|
13
|
+
|
14
|
+
# Packages (separate files for brevity)
|
15
|
+
#
|
16
|
+
# Defines the world of packages as we know it. Each package has a name and
|
17
|
+
# set of metadata including its installer type (eg. apt, source, gem, etc). Packages can have
|
18
|
+
# relationships to each other via dependencies.
|
19
|
+
|
20
|
+
require 'packages/essential'
|
21
|
+
require 'packages/rails'
|
22
|
+
require 'packages/database'
|
23
|
+
require 'packages/server'
|
24
|
+
require 'packages/search'
|
25
|
+
|
26
|
+
|
27
|
+
# Policies
|
28
|
+
#
|
29
|
+
# Names a group of packages (optionally with versions) that apply to a particular set of roles:
|
30
|
+
#
|
31
|
+
# Associates the rails policy to the application servers. Contains rails, and surrounding
|
32
|
+
# packages. Note, appserver, database, webserver and search are all virtual packages defined above.
|
33
|
+
# If there's only one implementation of a virtual package, it's selected automatically, otherwise
|
34
|
+
# the user is requested to select which one to use.
|
35
|
+
|
36
|
+
policy :rails, :roles => :app do
|
37
|
+
requires :rails, :version => '2.1.0'
|
38
|
+
requires :appserver
|
39
|
+
requires :database
|
40
|
+
requires :webserver
|
41
|
+
requires :search
|
42
|
+
end
|
43
|
+
|
44
|
+
|
45
|
+
# Deployment
|
46
|
+
#
|
47
|
+
# Defines script wide settings such as a delivery mechanism for executing commands on the target
|
48
|
+
# system (eg. capistrano), and installer defaults (eg. build locations, etc):
|
49
|
+
#
|
50
|
+
# Configures spinkle to use capistrano for delivery of commands to the remote machines (via
|
51
|
+
# the named 'deploy' recipe). Also configures 'source' installer defaults to put package gear
|
52
|
+
# in /usr/local
|
53
|
+
|
54
|
+
deployment do
|
55
|
+
|
56
|
+
# mechanism for deployment
|
57
|
+
delivery :capistrano do
|
58
|
+
recipes 'deploy'
|
59
|
+
end
|
60
|
+
|
61
|
+
# source based package installer defaults
|
62
|
+
source do
|
63
|
+
prefix '/usr/local'
|
64
|
+
archives '/usr/local/sources'
|
65
|
+
builds '/usr/local/build'
|
66
|
+
end
|
67
|
+
|
68
|
+
end
|
69
|
+
|
70
|
+
# End of script, given the above information, Spinkle will apply the defined policy on all roles using the
|
71
|
+
# deployment settings specified.
|
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env sprinkle -c -s
|
2
|
+
|
3
|
+
# Example of the simplest Sprinkle script to install a single gem on a remote host. This
|
4
|
+
# particular script assumes that rubygems (and ruby, etc) are already installed on the remote
|
5
|
+
# host. To see a larger example of installing an entire ruby, rubygems, gem stack from source,
|
6
|
+
# please see the rails example.
|
7
|
+
|
8
|
+
# Packages, only sprinkle is defined in this world
|
9
|
+
|
10
|
+
package :sprinkle do
|
11
|
+
description 'Sprinkle Provisioning Tool'
|
12
|
+
gem 'crafterm-sprinkle' do
|
13
|
+
source 'http://gems.github.com' # use alternate gem server
|
14
|
+
#repository '/opt/local/gems' # specify an alternate local gem repository
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
|
19
|
+
# Policies, sprinkle policy requires only the sprinkle gem
|
20
|
+
|
21
|
+
policy :sprinkle, :roles => :app do
|
22
|
+
requires :sprinkle
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
# Deployment settings
|
27
|
+
|
28
|
+
deployment do
|
29
|
+
|
30
|
+
# use vlad for deployment
|
31
|
+
delivery :vlad do
|
32
|
+
role :app, 'yourhost.com'
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
36
|
+
|
37
|
+
# End of script, given the above information, Spinkle will apply the defined policy on all roles using the
|
38
|
+
# deployment settings specified.
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'capistrano/cli'
|
2
|
+
|
3
|
+
module Sprinkle
|
4
|
+
module Actors
|
5
|
+
class Capistrano
|
6
|
+
attr_accessor :config, :loaded_recipes
|
7
|
+
|
8
|
+
def initialize(&block)
|
9
|
+
@config = ::Capistrano::Configuration.new
|
10
|
+
@config.logger.level = Sprinkle::OPTIONS[:verbose] ? ::Capistrano::Logger::INFO : ::Capistrano::Logger::IMPORTANT
|
11
|
+
@config.set(:password) { ::Capistrano::CLI.password_prompt }
|
12
|
+
if block
|
13
|
+
self.instance_eval &block
|
14
|
+
else
|
15
|
+
@config.load 'deploy' # normally in the config directory for rails
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def recipes(script)
|
20
|
+
@loaded_recipes ||= []
|
21
|
+
@config.load script
|
22
|
+
@loaded_recipes << script
|
23
|
+
end
|
24
|
+
|
25
|
+
def process(name, commands, roles)
|
26
|
+
define_task(name, roles) do
|
27
|
+
via = fetch(:run_method, :sudo)
|
28
|
+
commands.each do |command|
|
29
|
+
invoke_command command, :via => via
|
30
|
+
end
|
31
|
+
end
|
32
|
+
run(name)
|
33
|
+
end
|
34
|
+
|
35
|
+
private
|
36
|
+
|
37
|
+
# REVISIT: can we set the description somehow?
|
38
|
+
def define_task(name, roles, &block)
|
39
|
+
@config.task task_sym(name), :roles => roles, &block
|
40
|
+
end
|
41
|
+
|
42
|
+
def run(task)
|
43
|
+
@config.send task_sym(task)
|
44
|
+
end
|
45
|
+
|
46
|
+
def task_sym(name)
|
47
|
+
"install_#{name.to_task_name}".to_sym
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
=begin
|
55
|
+
|
56
|
+
# channel: the SSH channel object used for this response
|
57
|
+
# stream: either :err or :out, for stderr or stdout responses
|
58
|
+
# output: the text that the server is sending, might be in chunks
|
59
|
+
run "apt-get update" do |channel, stream, output|
|
60
|
+
if output =~ /Are you sure?/
|
61
|
+
answer = Capistrano::CLI.ui.ask("Are you sure: ")
|
62
|
+
channel.send_data(answer + "\n")
|
63
|
+
else
|
64
|
+
# allow the default callback to be processed
|
65
|
+
Capistrano::Configuration.default_io_proc.call[channel, stream, output]
|
66
|
+
end
|
67
|
+
end
|
68
|
+
|
69
|
+
|
70
|
+
|
71
|
+
You can tell subversion to use a different username+password by
|
72
|
+
setting a couple variables:
|
73
|
+
set :svn_username, "my svn username"
|
74
|
+
set :svn_password, "my svn password"
|
75
|
+
If you don't want to set the password explicitly in your recipe like
|
76
|
+
that, you can make capistrano prompt you for it like this:
|
77
|
+
set(:svn_password) { Capistrano::CLI.password_prompt("Subversion
|
78
|
+
password: ") }
|
79
|
+
- Jamis
|
80
|
+
=end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Actors
|
3
|
+
class Vlad
|
4
|
+
require 'vlad'
|
5
|
+
attr_accessor :loaded_recipes
|
6
|
+
|
7
|
+
def initialize(&block)
|
8
|
+
self.instance_eval &block if block
|
9
|
+
end
|
10
|
+
|
11
|
+
def script(name)
|
12
|
+
@loaded_recipes ||= []
|
13
|
+
self.load name
|
14
|
+
@loaded_recipes << script
|
15
|
+
end
|
16
|
+
|
17
|
+
def process(name, commands, roles)
|
18
|
+
commands = commands.join ' && ' if commands.is_a? Array
|
19
|
+
t = remote_task(task_sym(name), :roles => roles) { run commands }
|
20
|
+
t.invoke
|
21
|
+
end
|
22
|
+
|
23
|
+
private
|
24
|
+
|
25
|
+
def task_sym(name)
|
26
|
+
"install_#{name.to_task_name}".to_sym
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Deployment
|
3
|
+
def deployment(&block)
|
4
|
+
@deployment = Deployment.new(&block)
|
5
|
+
end
|
6
|
+
|
7
|
+
class Deployment
|
8
|
+
attr_accessor :style, :defaults
|
9
|
+
|
10
|
+
def initialize(&block)
|
11
|
+
@defaults = {}
|
12
|
+
self.instance_eval(&block)
|
13
|
+
raise 'No delivery mechanism defined' unless @style
|
14
|
+
end
|
15
|
+
|
16
|
+
def delivery(type, &block)
|
17
|
+
@style = Actors.const_get(type.to_s.titleize).new &block
|
18
|
+
end
|
19
|
+
|
20
|
+
def method_missing(sym, *args, &block)
|
21
|
+
@defaults[sym] = block
|
22
|
+
end
|
23
|
+
|
24
|
+
def respond_to?(sym); !!@defaults[sym]; end
|
25
|
+
|
26
|
+
def process
|
27
|
+
POLICIES.each do |policy|
|
28
|
+
policy.process(self)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Installers
|
3
|
+
class Apt < Installer
|
4
|
+
attr_accessor :packages
|
5
|
+
|
6
|
+
def initialize(parent, packages, &block)
|
7
|
+
super parent, &block
|
8
|
+
packages = [packages] unless packages.is_a? Array
|
9
|
+
@packages = packages
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def install_commands
|
15
|
+
"DEBCONF_TERSE='yes' DEBIAN_PRIORITY='critical' DEBIAN_FRONTEND=noninteractive apt-get -qyu install #{@packages.join(' ')}"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Installers
|
3
|
+
class Gem < Installer
|
4
|
+
attr_accessor :gem
|
5
|
+
|
6
|
+
def initialize(parent, gem, options = {}, &block)
|
7
|
+
super parent, options, &block
|
8
|
+
@gem = gem
|
9
|
+
end
|
10
|
+
|
11
|
+
def source(location = nil)
|
12
|
+
# package defines an installer called source so here we specify a method directly
|
13
|
+
# rather than rely on the automatic options processing since packages' method missing
|
14
|
+
# won't be run
|
15
|
+
return @options[:source] unless location
|
16
|
+
@options[:source] = location
|
17
|
+
end
|
18
|
+
|
19
|
+
protected
|
20
|
+
|
21
|
+
# rubygems 0.9.5+ installs dependencies by default, and does platform selection
|
22
|
+
|
23
|
+
def install_commands
|
24
|
+
cmd = "gem install #{gem}"
|
25
|
+
cmd << " --version '#{version}'" if version
|
26
|
+
cmd << " --source #{source}" if source
|
27
|
+
cmd << " --install-dir #{repository}" if repository
|
28
|
+
cmd
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,85 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Installers
|
3
|
+
class Installer
|
4
|
+
attr_accessor :delivery, :package, :options, :pre, :post
|
5
|
+
|
6
|
+
def initialize(package, options = {}, &block)
|
7
|
+
@package = package
|
8
|
+
@options = options
|
9
|
+
@pre = {}; @post = {}
|
10
|
+
self.instance_eval(&block) if block
|
11
|
+
end
|
12
|
+
|
13
|
+
def pre(stage, *commands)
|
14
|
+
@pre[stage] ||= []
|
15
|
+
@pre[stage] += commands
|
16
|
+
end
|
17
|
+
|
18
|
+
def post(stage, *commands)
|
19
|
+
@post[stage] ||= []
|
20
|
+
@post[stage] += commands
|
21
|
+
end
|
22
|
+
|
23
|
+
def defaults(deployment)
|
24
|
+
defaults = deployment.defaults[self.class.name.split(/::/).last.downcase.to_sym]
|
25
|
+
self.instance_eval(&defaults) if defaults
|
26
|
+
@delivery = deployment.style
|
27
|
+
end
|
28
|
+
|
29
|
+
def process(roles)
|
30
|
+
raise 'Unknown command delivery target' unless @delivery
|
31
|
+
|
32
|
+
if logger.debug?
|
33
|
+
sequence = install_sequence; sequence = sequence.join('; ') if sequence.is_a? Array
|
34
|
+
logger.debug "#{@package.name} install sequence: #{sequence} for roles: #{roles}\n"
|
35
|
+
end
|
36
|
+
|
37
|
+
unless Sprinkle::OPTIONS[:testing]
|
38
|
+
logger.info "--> Installing #{package.name} for roles: #{roles}"
|
39
|
+
@delivery.process(@package.name, install_sequence, roles)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
def method_missing(sym, *args, &block)
|
44
|
+
unless args.empty? # mutate if not set
|
45
|
+
@options[sym] = *args unless @options[sym]
|
46
|
+
end
|
47
|
+
|
48
|
+
@options[sym] || @package.send(sym, *args, &block) # try the parents options if unknown
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
# Installation is separated into two styles that concrete derivative installer classes
|
54
|
+
# can implement.
|
55
|
+
#
|
56
|
+
# Simple installers that issue a single or set of commands can overwride
|
57
|
+
# install_commands (eg. apt, gem, rpm). Pre/post install commands are included in this
|
58
|
+
# style for free.
|
59
|
+
#
|
60
|
+
# More complicated installers that have different stages, and require pre/post commands
|
61
|
+
# within stages can override install_sequence and take complete control of the install
|
62
|
+
# command sequence construction (eg. source based installer).
|
63
|
+
|
64
|
+
def install_sequence
|
65
|
+
commands = pre_commands(:install) + [ install_commands ] + post_commands(:install)
|
66
|
+
commands.flatten
|
67
|
+
end
|
68
|
+
|
69
|
+
def install_commands
|
70
|
+
raise 'Concrete installers implement this to specify commands to run to install their respective packages'
|
71
|
+
end
|
72
|
+
|
73
|
+
def pre_commands(stage)
|
74
|
+
dress @pre[stage] || [], :pre
|
75
|
+
end
|
76
|
+
|
77
|
+
def post_commands(stage)
|
78
|
+
dress @post[stage] || [], :post
|
79
|
+
end
|
80
|
+
|
81
|
+
def dress(commands, stage); commands; end
|
82
|
+
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
@@ -0,0 +1,17 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Installers
|
3
|
+
class Rake < Installer
|
4
|
+
def initialize(parent, commands = [], &block)
|
5
|
+
super parent, &block
|
6
|
+
@commands = commands
|
7
|
+
end
|
8
|
+
|
9
|
+
protected
|
10
|
+
|
11
|
+
def install_commands
|
12
|
+
"rake #{@commands.join(' ')}"
|
13
|
+
end
|
14
|
+
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Installers
|
3
|
+
class Rpm < Installer
|
4
|
+
attr_accessor :packages
|
5
|
+
|
6
|
+
def initialize(parent, packages, &block)
|
7
|
+
super parent, &block
|
8
|
+
packages = [packages] unless packages.is_a? Array
|
9
|
+
@packages = packages
|
10
|
+
end
|
11
|
+
|
12
|
+
protected
|
13
|
+
|
14
|
+
def install_commands
|
15
|
+
"rpm -Uvh #{@packages.join(' ')}"
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,120 @@
|
|
1
|
+
module Sprinkle
|
2
|
+
module Installers
|
3
|
+
class Source < Installer
|
4
|
+
attr_accessor :source
|
5
|
+
|
6
|
+
def initialize(parent, source, options = {}, &block)
|
7
|
+
@source = source
|
8
|
+
super parent, options, &block
|
9
|
+
end
|
10
|
+
|
11
|
+
protected
|
12
|
+
|
13
|
+
def install_sequence
|
14
|
+
prepare + download + extract + configure + build + install
|
15
|
+
end
|
16
|
+
|
17
|
+
%w( prepare download extract configure build install ).each do |stage|
|
18
|
+
define_method stage do
|
19
|
+
pre_commands(stage.to_sym) + self.send("#{stage}_commands") + post_commands(stage.to_sym)
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
def prepare_commands
|
24
|
+
raise 'No installation area defined' unless @options[:prefix]
|
25
|
+
raise 'No build area defined' unless @options[:builds]
|
26
|
+
raise 'No source download area defined' unless @options[:archives]
|
27
|
+
|
28
|
+
[ "mkdir -p #{@options[:prefix]}",
|
29
|
+
"mkdir -p #{@options[:builds]}",
|
30
|
+
"mkdir -p #{@options[:archives]}" ]
|
31
|
+
end
|
32
|
+
|
33
|
+
def download_commands
|
34
|
+
[ "wget -cq --directory-prefix='#{@options[:archives]}' #{@source}" ]
|
35
|
+
end
|
36
|
+
|
37
|
+
def extract_commands
|
38
|
+
[ "bash -c 'cd #{@options[:builds]} && #{extract_command} #{@options[:archives]}/#{archive_name}'" ]
|
39
|
+
end
|
40
|
+
|
41
|
+
def configure_commands
|
42
|
+
return [] if custom_install?
|
43
|
+
|
44
|
+
command = "bash -c 'cd #{build_dir} && ./configure --prefix=#{@options[:prefix]} "
|
45
|
+
|
46
|
+
extras = {
|
47
|
+
:enable => '--enable', :disable => '--disable',
|
48
|
+
:with => '--with', :without => '--without'
|
49
|
+
}
|
50
|
+
|
51
|
+
extras.inject(command) { |m, (k, v)| m << create_options(k, v) if options[k]; m }
|
52
|
+
|
53
|
+
[ command << " > #{@package.name}-configure.log 2>&1'" ]
|
54
|
+
end
|
55
|
+
|
56
|
+
def build_commands
|
57
|
+
return [] if custom_install?
|
58
|
+
[ "bash -c 'cd #{build_dir} && make > #{@package.name}-build.log 2>&1'" ]
|
59
|
+
end
|
60
|
+
|
61
|
+
def install_commands
|
62
|
+
return custom_install_commands if custom_install?
|
63
|
+
[ "bash -c 'cd #{build_dir} && make install > #{@package.name}-install.log 2>&1'" ]
|
64
|
+
end
|
65
|
+
|
66
|
+
def custom_install?
|
67
|
+
!! @options[:custom_install]
|
68
|
+
end
|
69
|
+
|
70
|
+
# REVISIT: must be better processing of custom install commands somehow? use splat operator?
|
71
|
+
def custom_install_commands
|
72
|
+
dress @options[:custom_install], :install
|
73
|
+
end
|
74
|
+
|
75
|
+
protected
|
76
|
+
|
77
|
+
def dress(commands, stage)
|
78
|
+
commands.collect { |command| "bash -c 'cd #{build_dir} && #{command} >> #{@package.name}-#{stage}.log 2>&1'" }
|
79
|
+
end
|
80
|
+
|
81
|
+
private
|
82
|
+
|
83
|
+
def create_options(key, prefix)
|
84
|
+
@options[key].inject(' ') { |m, option| m << "#{prefix}-#{option} "; m }
|
85
|
+
end
|
86
|
+
|
87
|
+
def extract_command
|
88
|
+
case @source
|
89
|
+
when /(tar.gz)|(tgz)$/
|
90
|
+
'tar xzf'
|
91
|
+
when /(tar.bz2)|(tb2)$/
|
92
|
+
'tar xjf'
|
93
|
+
when /tar$/
|
94
|
+
'tar xf'
|
95
|
+
when /zip$/
|
96
|
+
'unzip'
|
97
|
+
else
|
98
|
+
raise "Unknown source archive format: #{archive_name}"
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def archive_name
|
103
|
+
name = @source.split('/').last
|
104
|
+
raise "Unable to determine archive name for source: #{source}, please update code knowledge" unless name
|
105
|
+
name
|
106
|
+
end
|
107
|
+
|
108
|
+
def build_dir
|
109
|
+
"#{@options[:builds]}/#{base_dir}"
|
110
|
+
end
|
111
|
+
|
112
|
+
def base_dir
|
113
|
+
if @source.split('/').last =~ /(.*)\.(tar\.gz|tgz|tar\.bz2|tb2)/
|
114
|
+
return $1
|
115
|
+
end
|
116
|
+
raise "Unknown base path for source archive: #{@source}, please update code knowledge"
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|