terraform 0.0.1 → 0.0.2
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/README.markdown +7 -5
- data/Rakefile +10 -0
- data/lib/terraform.rb +1 -1
- data/lib/terraform/dsl.rb +144 -0
- data/lib/terraform/version.rb +1 -1
- data/terraform.gemspec +4 -1
- data/test/test_helper.rb +24 -0
- data/test/unit/terraform/dsl_test.rb +97 -0
- metadata +43 -9
- data/lib/terraform/terraform_dsl.rb +0 -125
data/README.markdown
CHANGED
@@ -1,11 +1,12 @@
|
|
1
|
-
Terraform is a small goal-oriented DSL for setting up a machine, similar in purpose to Chef and
|
2
|
-
|
1
|
+
Terraform is a small goal-oriented DSL for setting up a machine, similar in purpose to Chef and Puppet. Its
|
2
|
+
design is inspired by Babushka, but it's simpler and tailored specifically for provisioning a machine for a
|
3
|
+
webapp.
|
3
4
|
|
4
5
|
Usage
|
5
6
|
-----
|
6
7
|
|
7
8
|
require "terraform_dsl"
|
8
|
-
include
|
9
|
+
include Terraform::Dsl
|
9
10
|
dep "my library" do
|
10
11
|
met? { (check if your dependency is met) }
|
11
12
|
meet { (install your dependency) }
|
@@ -15,10 +16,11 @@ A more detailed README is coming shortly.
|
|
15
16
|
|
16
17
|
Contribute
|
17
18
|
----------
|
18
|
-
When editing this gem, to test your changes, you can load your local copy of the gem in your project by using
|
19
|
+
When editing this gem, to test your changes, you can load your local copy of the gem in your project by using
|
20
|
+
this in your Gemfile:
|
19
21
|
|
20
22
|
gem "terraform", :path => "~/p/terraform"
|
21
23
|
|
22
24
|
Credits
|
23
25
|
-------
|
24
|
-
Dmac -- thanks for the name!
|
26
|
+
Dmac -- thanks for the name!
|
data/Rakefile
CHANGED
data/lib/terraform.rb
CHANGED
@@ -5,6 +5,6 @@ module Terraform
|
|
5
5
|
# Writes the terraform_dsl.rb to the given file or directory.
|
6
6
|
def self.write_dsl_file(path)
|
7
7
|
path = File.join(path, "terraform_dsl.rb") if File.directory?(path)
|
8
|
-
FileUtils.cp(File.expand_path(File.join(File.dirname(__FILE__), "terraform/
|
8
|
+
FileUtils.cp(File.expand_path(File.join(File.dirname(__FILE__), "terraform/dsl.rb")), path)
|
9
9
|
end
|
10
10
|
end
|
@@ -0,0 +1,144 @@
|
|
1
|
+
require "fileutils"
|
2
|
+
require "digest/md5"
|
3
|
+
|
4
|
+
module Terraform
|
5
|
+
module Dsl
|
6
|
+
def dep(name)
|
7
|
+
@dependencies ||= []
|
8
|
+
# If a dep gets required or defined twice, only run it once.
|
9
|
+
return if @dependencies.find { |dep| dep[:name] == name }
|
10
|
+
@dependencies.push(@current_dependency = { :name => name })
|
11
|
+
yield
|
12
|
+
fail_and_exit "Error: no 'met?' block defined for dep '#{name}'." unless @current_dependency[:met?]
|
13
|
+
fail_and_exit "Error: no 'meet' block defined for dep '#{name}'." unless @current_dependency[:meet]
|
14
|
+
end
|
15
|
+
def met?(&block) @current_dependency[:met?] = block end
|
16
|
+
def meet(&block) @current_dependency[:meet] = block end
|
17
|
+
def in_path?(command) `which #{command}`.size > 0 end
|
18
|
+
def fail_and_exit(message) puts message; exit 1 end
|
19
|
+
|
20
|
+
# Runs a command and raises an exception if its exit status was nonzero.
|
21
|
+
# - silent: if false, log the command being run and its stdout. False by default.
|
22
|
+
# - check_exit_code: raises an error if the command had a non-zero exit code. True by default.
|
23
|
+
def shell(command, options = {})
|
24
|
+
silent = (options[:silent] != false)
|
25
|
+
puts command unless silent
|
26
|
+
output = `#{command}`
|
27
|
+
puts output unless output.empty? || silent
|
28
|
+
raise "#{command} had a failure exit status of #{$?.to_i}" unless $?.to_i == 0
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def satisfy_dependencies
|
33
|
+
STDOUT.sync = true # Ensure that we flush logging output as we go along.
|
34
|
+
@dependencies.each do |dep|
|
35
|
+
unless dep[:met?].call
|
36
|
+
puts "* Dependency #{dep[:name]} is not met. Meeting it."
|
37
|
+
dep[:meet].call
|
38
|
+
fail_and_exit %Q("met?" for #{dep[:name]} is still false after running "meet".) unless dep[:met?].call
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
|
43
|
+
#
|
44
|
+
# These are very common tasks which are needed by almost everyone, and so they're bundled with this DSL.
|
45
|
+
#
|
46
|
+
|
47
|
+
def package_installed?(package) `dpkg -s #{package} 2> /dev/null | grep Status`.match(/\sinstalled/) end
|
48
|
+
def install_package(package)
|
49
|
+
# Specify a noninteractive frontend, so dpkg won't prompt you for info. -q is quiet; -y is "answer yes".
|
50
|
+
shell "sudo DEBIAN_FRONTEND=noninteractive apt-get install -qy #{package}"
|
51
|
+
end
|
52
|
+
|
53
|
+
def ensure_packages(*packages) packages.each { |package| ensure_package(package) } end
|
54
|
+
def ensure_package(package)
|
55
|
+
dep "package: #{package}" do
|
56
|
+
met? { package_installed?(package) }
|
57
|
+
meet { install_package(package) }
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
# Ensure an Ubuntu PPA is installed. The argument is the ppa location, in the form ppa:[USER]/[NAME]
|
62
|
+
def ensure_ppa(ppa)
|
63
|
+
ppa_part, location = ppa.split(":", 2)
|
64
|
+
fail_and_exit("PPA location must be of the form ppa:[USER]/[NAME]") unless (ppa_part == "ppa") && location
|
65
|
+
# The python-software-properties package provides the add-apt-repository convenience tool for editing
|
66
|
+
# the list of apt's source repositories.
|
67
|
+
ensure_package("python-software-properties")
|
68
|
+
dep "ppa: #{location}" do
|
69
|
+
met? { !`apt-cache policy 2> /dev/null | grep ppa.launchpad.net/#{location}/`.empty? }
|
70
|
+
meet do
|
71
|
+
shell "sudo add-apt-repository #{ppa}"#, :silent => true
|
72
|
+
shell "sudo apt-get update"#, :silent => true
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
def gem_installed?(gem) `gem list '#{gem}'`.include?(gem) end
|
78
|
+
|
79
|
+
def ensure_gem(gem)
|
80
|
+
dep "gem: #{gem}" do
|
81
|
+
met? { gem_installed?(gem) }
|
82
|
+
meet { shell "gem install #{gem} --no-ri --no-rdoc" }
|
83
|
+
end
|
84
|
+
end
|
85
|
+
|
86
|
+
# Ensures the file at dest_path is exactly the same as the one in source_path.
|
87
|
+
# Invokes the given block if the file is changed. Use this block to restart a service, for instance.
|
88
|
+
def ensure_file(source_path, dest_path, &on_change)
|
89
|
+
dep "file: #{dest_path}" do
|
90
|
+
met? do
|
91
|
+
raise "This file does not exist: #{source_path}" unless File.exists?(source_path)
|
92
|
+
File.exists?(dest_path) && (Digest::MD5.file(source_path) == Digest::MD5.file(dest_path))
|
93
|
+
end
|
94
|
+
meet do
|
95
|
+
FileUtils.cp(source_path, dest_path)
|
96
|
+
on_change.call if on_change
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
# A task which must be run once to be 'met'. For instance, this might be the DB migration script.
|
102
|
+
def ensure_run_once(name, &block)
|
103
|
+
dep "run task once: #{name}" do
|
104
|
+
has_run_once = false
|
105
|
+
met? { has_run_once }
|
106
|
+
meet do
|
107
|
+
yield
|
108
|
+
has_run_once = true
|
109
|
+
end
|
110
|
+
end
|
111
|
+
end
|
112
|
+
|
113
|
+
def ensure_rbenv
|
114
|
+
ensure_package "git-core"
|
115
|
+
dep "rbenv" do
|
116
|
+
met? { in_path?("rbenv") }
|
117
|
+
meet do
|
118
|
+
# These instructions are from https://github.com/sstephenson/rbenv/wiki/Using-rbenv-in-Production
|
119
|
+
shell "wget -q -O - https://raw.github.com/fesplugas/rbenv-installer/master/bin/rbenv-installer | bash"
|
120
|
+
# We need to run rbenv init after install, which adjusts the path. If exec is causing us problems
|
121
|
+
# down the road, we can perhaps simulate running rbenv init without execing.
|
122
|
+
unless ARGV.include?("--forked-after-rbenv") # To guard against an infinite forking loop.
|
123
|
+
exec "bash -c 'source ~/.bashrc; #{$0} --forked-after-rbenv'" # $0 is the current process's name.
|
124
|
+
end
|
125
|
+
end
|
126
|
+
end
|
127
|
+
end
|
128
|
+
|
129
|
+
# ruby_version is a rbenv ruby version string like "1.9.2-p290".
|
130
|
+
def ensure_rbenv_ruby(ruby_version)
|
131
|
+
ensure_rbenv
|
132
|
+
ensure_packages "curl", "build-essential", "libxslt1-dev", "libxml2-dev", "libssl-dev"
|
133
|
+
|
134
|
+
dep "rbenv ruby: #{ruby_version}" do
|
135
|
+
met? { `which ruby`.include?("rbenv") && `ruby -v`.include?(ruby_version.gsub("-", "")) }
|
136
|
+
meet do
|
137
|
+
puts "Compiling Ruby will take a few minutes."
|
138
|
+
shell "rbenv install #{ruby_version}"
|
139
|
+
shell "rbenv rehash"
|
140
|
+
end
|
141
|
+
end
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
data/lib/terraform/version.rb
CHANGED
data/terraform.gemspec
CHANGED
@@ -15,6 +15,9 @@ Gem::Specification.new do |s|
|
|
15
15
|
|
16
16
|
s.files = `git ls-files`.split("\n")
|
17
17
|
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
18
|
-
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map { |f| File.basename(f) }
|
19
19
|
s.require_paths = ["lib"]
|
20
|
+
|
21
|
+
s.add_development_dependency "scope", "~> 0.2.3"
|
22
|
+
s.add_development_dependency "rr", "~> 1.0.4"
|
20
23
|
end
|
data/test/test_helper.rb
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
require "bundler/setup"
|
2
|
+
require "minitest/autorun"
|
3
|
+
require "scope"
|
4
|
+
require "rr"
|
5
|
+
require "stringio"
|
6
|
+
|
7
|
+
$:.unshift(File.join(File.dirname(__FILE__), "../lib"))
|
8
|
+
|
9
|
+
module Scope
|
10
|
+
class TestCase
|
11
|
+
include RR::Adapters::MiniTest
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
module Kernel
|
16
|
+
def capture_output
|
17
|
+
result = StringIO.new
|
18
|
+
$stdout = result
|
19
|
+
yield
|
20
|
+
result.string
|
21
|
+
ensure
|
22
|
+
$stdout = STDOUT
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
require File.expand_path(File.join(File.dirname(__FILE__), "../../test_helper.rb"))
|
2
|
+
require "terraform/dsl"
|
3
|
+
|
4
|
+
class DslTest < Scope::TestCase
|
5
|
+
include Terraform::Dsl
|
6
|
+
|
7
|
+
class ProcessExit < StandardError; end
|
8
|
+
|
9
|
+
# Methods to mock for met? and meet blocks
|
10
|
+
def do_met() end
|
11
|
+
def do_meet() end
|
12
|
+
|
13
|
+
setup do
|
14
|
+
stub(self).fail_and_exit(anything) { raise ProcessExit }
|
15
|
+
end
|
16
|
+
|
17
|
+
context "dep declarations" do
|
18
|
+
should "fail if there is no met? or meet given" do
|
19
|
+
assert_raises(ProcessExit) do
|
20
|
+
dep("no met?") { meet {} }
|
21
|
+
end
|
22
|
+
assert_raises(ProcessExit) do
|
23
|
+
dep("no meet") { met? {} }
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
should "not run meet if met? is satisfied" do
|
28
|
+
mock(self).do_met { true }
|
29
|
+
mock(self).do_meet.never
|
30
|
+
dep "foo" do
|
31
|
+
met? { do_met }
|
32
|
+
meet { do_meet }
|
33
|
+
end
|
34
|
+
satisfy_dependencies
|
35
|
+
end
|
36
|
+
|
37
|
+
should "run meet if met? is not satisfied" do
|
38
|
+
met_run = false
|
39
|
+
mock(self).do_met.twice { result = met_run; met_run = true; result }
|
40
|
+
mock(self).do_meet
|
41
|
+
dep "foo" do
|
42
|
+
met? { do_met }
|
43
|
+
meet { do_meet }
|
44
|
+
end
|
45
|
+
message = capture_output { satisfy_dependencies }
|
46
|
+
assert_match /Dependency foo is not met/, message
|
47
|
+
end
|
48
|
+
|
49
|
+
should "only meet a dep once" do
|
50
|
+
met_run = false
|
51
|
+
mock(self).do_met.twice { result = met_run; met_run = true; result }
|
52
|
+
mock(self).do_meet
|
53
|
+
2.times do
|
54
|
+
dep "foo" do
|
55
|
+
met? { do_met }
|
56
|
+
meet { do_meet }
|
57
|
+
end
|
58
|
+
end
|
59
|
+
capture_output { satisfy_dependencies }
|
60
|
+
end
|
61
|
+
|
62
|
+
should "fail if met? still fails after running meet" do
|
63
|
+
mock(self).do_met.twice { false }
|
64
|
+
mock(self).do_meet
|
65
|
+
dep "foo" do
|
66
|
+
met? { do_met }
|
67
|
+
meet { do_meet }
|
68
|
+
end
|
69
|
+
assert_raises(ProcessExit) { capture_output { satisfy_dependencies } }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
|
73
|
+
context "ensure_ppa" do
|
74
|
+
should "fail if the PPA name is not the expected form" do
|
75
|
+
assert_raises(ProcessExit) { ensure_ppa("blah") }
|
76
|
+
assert_raises(ProcessExit) { ensure_ppa("http://some.ppa.url") }
|
77
|
+
end
|
78
|
+
|
79
|
+
# TODO(caleb): Add more unit tests. Having trouble coming up with unit tests that don't feel
|
80
|
+
# fragile/artificial. For helpers like these, integration tests of some kind that run on a vagrant box or
|
81
|
+
# something may prove more useful.
|
82
|
+
end
|
83
|
+
|
84
|
+
context "ensure_run_once" do
|
85
|
+
should "run a task exactly once" do
|
86
|
+
mock(self).do_meet.never
|
87
|
+
meet_run = false
|
88
|
+
ensure_run_once("foo") { meet_run = true }
|
89
|
+
dep "run task once: foo" do
|
90
|
+
met? { do_met }
|
91
|
+
meet { do_meet }
|
92
|
+
end
|
93
|
+
capture_output { satisfy_dependencies }
|
94
|
+
assert meet_run
|
95
|
+
end
|
96
|
+
end
|
97
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: terraform
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 27
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 0
|
9
|
-
-
|
10
|
-
version: 0.0.
|
9
|
+
- 2
|
10
|
+
version: 0.0.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Phil Crosby
|
@@ -15,10 +15,41 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2012-03-
|
18
|
+
date: 2012-03-27 00:00:00 -07:00
|
19
19
|
default_executable:
|
20
|
-
dependencies:
|
21
|
-
|
20
|
+
dependencies:
|
21
|
+
- !ruby/object:Gem::Dependency
|
22
|
+
name: scope
|
23
|
+
prerelease: false
|
24
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ~>
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
hash: 17
|
30
|
+
segments:
|
31
|
+
- 0
|
32
|
+
- 2
|
33
|
+
- 3
|
34
|
+
version: 0.2.3
|
35
|
+
type: :development
|
36
|
+
version_requirements: *id001
|
37
|
+
- !ruby/object:Gem::Dependency
|
38
|
+
name: rr
|
39
|
+
prerelease: false
|
40
|
+
requirement: &id002 !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ~>
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
hash: 31
|
46
|
+
segments:
|
47
|
+
- 1
|
48
|
+
- 0
|
49
|
+
- 4
|
50
|
+
version: 1.0.4
|
51
|
+
type: :development
|
52
|
+
version_requirements: *id002
|
22
53
|
description:
|
23
54
|
email:
|
24
55
|
- phil.crosby@gmail.com
|
@@ -34,9 +65,11 @@ files:
|
|
34
65
|
- README.markdown
|
35
66
|
- Rakefile
|
36
67
|
- lib/terraform.rb
|
37
|
-
- lib/terraform/
|
68
|
+
- lib/terraform/dsl.rb
|
38
69
|
- lib/terraform/version.rb
|
39
70
|
- terraform.gemspec
|
71
|
+
- test/test_helper.rb
|
72
|
+
- test/unit/terraform/dsl_test.rb
|
40
73
|
has_rdoc: true
|
41
74
|
homepage: http://github.com/philc/terraform
|
42
75
|
licenses: []
|
@@ -71,5 +104,6 @@ rubygems_version: 1.6.2
|
|
71
104
|
signing_key:
|
72
105
|
specification_version: 3
|
73
106
|
summary: Set up a cold, inhospitable system using Terraform.
|
74
|
-
test_files:
|
75
|
-
|
107
|
+
test_files:
|
108
|
+
- test/test_helper.rb
|
109
|
+
- test/unit/terraform/dsl_test.rb
|
@@ -1,125 +0,0 @@
|
|
1
|
-
# This is small goal-oriented DSL for installing system components, similar in purpose to Chef and Puppet.
|
2
|
-
# Its design is inspired by Babushka but it's simpler and tailored specifically for provisioning a machine
|
3
|
-
# for a webapp.
|
4
|
-
#
|
5
|
-
# Usage:
|
6
|
-
#
|
7
|
-
# require "terraform_dsl"
|
8
|
-
# include TerraformDsl
|
9
|
-
# dep "my library" do
|
10
|
-
# met? { (check if your dependency is met) }
|
11
|
-
# meet { (install your dependency) }
|
12
|
-
# end
|
13
|
-
|
14
|
-
require "fileutils"
|
15
|
-
require "digest/md5"
|
16
|
-
|
17
|
-
module TerraformDsl
|
18
|
-
def dep(name)
|
19
|
-
@dependencies ||= []
|
20
|
-
# If a dep gets required or defined twice, only run it once.
|
21
|
-
return if @dependencies.find { |dep| dep[:name] == name }
|
22
|
-
@dependencies.push(@current_dependency = { :name => name })
|
23
|
-
yield
|
24
|
-
end
|
25
|
-
def met?(&block) @current_dependency[:met?] = block end
|
26
|
-
def meet(&block) @current_dependency[:meet] = block end
|
27
|
-
def in_path?(command) `which #{command}`.size > 0 end
|
28
|
-
def fail_and_exit(message) puts message; exit 1 end
|
29
|
-
|
30
|
-
# Runs a command and raises an exception if its exit status was nonzero.
|
31
|
-
# - silent: if false, log the command being run and its stdout. False by default.
|
32
|
-
# - check_exit_code: raises an error if the command had a non-zero exit code. True by default.
|
33
|
-
def shell(command, options = {})
|
34
|
-
silent = (options[:silent] != false)
|
35
|
-
puts command unless silent
|
36
|
-
output = `#{command}`
|
37
|
-
puts output unless output.empty? || silent
|
38
|
-
raise "#{command} had a failure exit status of #{$?.to_i}" unless $?.to_i == 0
|
39
|
-
true
|
40
|
-
end
|
41
|
-
|
42
|
-
def satisfy_dependencies
|
43
|
-
STDOUT.sync = true # Ensure that we flush logging output as we go along.
|
44
|
-
@dependencies.each do |dep|
|
45
|
-
unless dep[:met?].call
|
46
|
-
puts "* Dependency #{dep[:name]} is not met. Meeting it."
|
47
|
-
dep[:meet].call
|
48
|
-
fail_and_exit %Q("met?" for #{dep[:name]} is still false after running "meet".) unless dep[:met?].call
|
49
|
-
end
|
50
|
-
end
|
51
|
-
end
|
52
|
-
|
53
|
-
#
|
54
|
-
# These are very common tasks which are needed by almost everyone, and so they're bundled with this DSL.
|
55
|
-
#
|
56
|
-
|
57
|
-
def package_installed?(package) `dpkg -s #{package} 2> /dev/null | grep Status`.match(/\sinstalled/) end
|
58
|
-
def install_package(package)
|
59
|
-
# Specify a noninteractive frontend, so dpkg won't prompt you for info. -q is quiet; -y is "answer yes".
|
60
|
-
shell "sudo DEBIAN_FRONTEND=noninteractive apt-get install -qy #{package}"
|
61
|
-
end
|
62
|
-
|
63
|
-
def ensure_packages(*packages) packages.each { |package| ensure_package(package) } end
|
64
|
-
def ensure_package(package)
|
65
|
-
dep package do
|
66
|
-
met? { package_installed?(package) }
|
67
|
-
meet { install_package(package) }
|
68
|
-
end
|
69
|
-
end
|
70
|
-
|
71
|
-
def gem_installed?(gem) `gem list '#{gem}'`.include?(gem) end
|
72
|
-
|
73
|
-
def ensure_gem(gem)
|
74
|
-
dep gem do
|
75
|
-
met? { gem_installed?(gem) }
|
76
|
-
meet { shell "gem install #{gem} --no-ri --no-rdoc" }
|
77
|
-
end
|
78
|
-
end
|
79
|
-
|
80
|
-
# Ensures the file at dest_path is exactly the same as the one in source_path.
|
81
|
-
# Invokes the given block if the file is changed. Use this block to restart a service, for instance.
|
82
|
-
def ensure_file(source_path, dest_path, &on_change)
|
83
|
-
dep dest_path do
|
84
|
-
met? do
|
85
|
-
raise "This file does not exist: #{source_path}" unless File.exists?(source_path)
|
86
|
-
File.exists?(dest_path) && (Digest::MD5.file(source_path) == Digest::MD5.file(dest_path))
|
87
|
-
end
|
88
|
-
meet do
|
89
|
-
FileUtils.cp(source_path, dest_path)
|
90
|
-
on_change.call if on_change
|
91
|
-
end
|
92
|
-
end
|
93
|
-
end
|
94
|
-
|
95
|
-
def ensure_rbenv
|
96
|
-
ensure_package "git-core"
|
97
|
-
dep "rbenv" do
|
98
|
-
met? { in_path?("rbenv") }
|
99
|
-
meet do
|
100
|
-
# These instructions are from https://github.com/sstephenson/rbenv/wiki/Using-rbenv-in-Production
|
101
|
-
shell "wget -q -O - https://raw.github.com/fesplugas/rbenv-installer/master/bin/rbenv-installer | bash"
|
102
|
-
# We need to run rbenv init after install, which adjusts the path. If exec is causing us problems
|
103
|
-
# down the road, we can perhaps simulate running rbenv init without execing.
|
104
|
-
unless ARGV.include?("--forked-after-rbenv") # To guard against an infinite forking loop.
|
105
|
-
exec "bash -c 'source ~/.bashrc; #{$0} --forked-after-rbenv'" # $0 is the current process's name.
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
|
111
|
-
# ruby_version is a rbenv ruby version string like "1.9.2-p290".
|
112
|
-
def ensure_rbenv_ruby(ruby_version)
|
113
|
-
ensure_rbenv
|
114
|
-
ensure_packages "curl", "build-essential", "libxslt1-dev", "libxml2-dev", "libssl-dev"
|
115
|
-
|
116
|
-
dep "rbenv ruby #{ruby_version}" do
|
117
|
-
met? { `which ruby`.include?("rbenv") && `ruby -v`.include?(ruby_version.gsub("-", "")) }
|
118
|
-
meet do
|
119
|
-
puts "Compiling Ruby will take a few minutes."
|
120
|
-
shell "rbenv install #{ruby_version}"
|
121
|
-
shell "rbenv rehash"
|
122
|
-
end
|
123
|
-
end
|
124
|
-
end
|
125
|
-
end
|