mysqlnoio 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +4 -0
- data/.ruby-gemset +1 -0
- data/.ruby-version +1 -0
- data/.travis.yml +16 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +78 -0
- data/Guardfile +8 -0
- data/LICENSE +622 -0
- data/README.md +45 -0
- data/Rakefile +43 -0
- data/Vagrantfile +18 -0
- data/bin/mysql-noio +49 -0
- data/lib/mysqlnoio/about.rb +12 -0
- data/lib/mysqlnoio/errors.rb +11 -0
- data/lib/mysqlnoio/wrap.rb +34 -0
- data/lib/mysqlnoio/wrap_stack.rb +65 -0
- data/lib/mysqlnoio/wraps/blocks.rb +24 -0
- data/lib/mysqlnoio/wraps/deactivated_slave.rb +18 -0
- data/lib/mysqlnoio/wraps/global_lock.rb +21 -0
- data/lib/mysqlnoio.rb +19 -0
- data/mysqlnoio.gemspec +39 -0
- data/spec/integration/mysql-noio_spec.rb +17 -0
- data/spec/mysqlnoio/wrap_stack_spec.rb +66 -0
- data/spec/mysqlnoio/wraps/blocks_spec.rb +44 -0
- data/spec/mysqlnoio/wraps/deactivated_slave_spec.rb +25 -0
- data/spec/mysqlnoio/wraps/global_lock_spec.rb +25 -0
- data/spec/spec_helper.rb +6 -0
- data/vagrant/provision.sh +13 -0
- metadata +235 -0
data/Rakefile
ADDED
@@ -0,0 +1,43 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
require "rspec/core/rake_task"
|
3
|
+
require 'mysqlnoio'
|
4
|
+
|
5
|
+
desc "Builds the gem"
|
6
|
+
task :build do
|
7
|
+
sh "gem build mysqlnoio.gemspec"
|
8
|
+
end
|
9
|
+
|
10
|
+
desc "Publishes the gem to fury.io"
|
11
|
+
task :publish => [:build] do |t|
|
12
|
+
sh "git tag -f #{MySQLNoIo::VERSION}"
|
13
|
+
sh "git push origin #{MySQLNoIo::VERSION} -f"
|
14
|
+
sh "curl -F p1=@mysqlnoio-#{MySQLNoIo::VERSION}.gem https://push.fury.io/BEz67VknqnyqmV6p7Huq/"
|
15
|
+
end
|
16
|
+
|
17
|
+
desc "Cleans the project directory up"
|
18
|
+
task :clean do
|
19
|
+
sh "rm -rf doc/ tmp/"
|
20
|
+
sh "rm -f mysqlnoio-*.gem"
|
21
|
+
end
|
22
|
+
|
23
|
+
# Various RSpec Bitties
|
24
|
+
base_opts = '--color --order random'
|
25
|
+
desc "Run specs"
|
26
|
+
RSpec::Core::RakeTask.new(:spec) do |t|
|
27
|
+
t.verbose = false
|
28
|
+
t.rspec_opts = "#{base_opts} --tag ~integration"
|
29
|
+
end
|
30
|
+
|
31
|
+
desc "Run integration specs"
|
32
|
+
RSpec::Core::RakeTask.new(:integration) do |t|
|
33
|
+
t.verbose = false
|
34
|
+
t.rspec_opts = "#{base_opts} --tag integration"
|
35
|
+
end
|
36
|
+
|
37
|
+
desc "Run all specs"
|
38
|
+
RSpec::Core::RakeTask.new(:test) do |t|
|
39
|
+
t.verbose = false
|
40
|
+
t.rspec_opts = base_opts
|
41
|
+
end
|
42
|
+
|
43
|
+
task :default => :spec
|
data/Vagrantfile
ADDED
@@ -0,0 +1,18 @@
|
|
1
|
+
# -*- mode: ruby -*-
|
2
|
+
# vi: set ft=ruby :
|
3
|
+
|
4
|
+
$boot = <<SCRIPT
|
5
|
+
sudo apt-get install build-essential
|
6
|
+
|
7
|
+
curl -L https://get.rvm.io | bash -s --autolibs=3 --ruby
|
8
|
+
SCRIPT
|
9
|
+
|
10
|
+
Vagrant.configure("2") do |config|
|
11
|
+
config.vm.box = "ubuntu-12.04.2-server-adm54-vmware-fusion"
|
12
|
+
config.vm.box_url = "https://s3.amazonaws.com/gsc-vagrant-boxes/ubuntu-12.04.2-server-amd64.box"
|
13
|
+
|
14
|
+
config.vm.provision :shell do |shell|
|
15
|
+
shell.inline = $script
|
16
|
+
shell.path = 'vagrant/provision.sh'
|
17
|
+
end
|
18
|
+
end
|
data/bin/mysql-noio
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require 'optparse'
|
4
|
+
require 'mysqlnoio'
|
5
|
+
|
6
|
+
credentials = {}
|
7
|
+
wraps = []
|
8
|
+
|
9
|
+
OptionParser.new do |opts|
|
10
|
+
opts.banner = "Usage: mysql-noio [options] <command>"
|
11
|
+
|
12
|
+
# Determine the MySQL connection parameters
|
13
|
+
opts.on("-u", "--user USER", "MySQL Username") do |v|
|
14
|
+
credentials[:username] = v
|
15
|
+
end
|
16
|
+
|
17
|
+
opts.on("-p", "--password PASSWORD", "MySQL Password") do |v|
|
18
|
+
credentials[:password] = v
|
19
|
+
end
|
20
|
+
|
21
|
+
opts.on("-h", "--host HOST", "MySQL Server Host") do |v|
|
22
|
+
credentials[:host] = v
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
opts.on("-t", "--lock-tables", "Lock tables with a read lock") do |v|
|
27
|
+
wraps << :lock
|
28
|
+
end
|
29
|
+
|
30
|
+
opts.on("-s", "--stop-slave", "Stop the slave thread") do |v|
|
31
|
+
wraps << :stop
|
32
|
+
end
|
33
|
+
|
34
|
+
opts.on
|
35
|
+
end.parse!
|
36
|
+
|
37
|
+
client = Mysql2::Client.new(credentials)
|
38
|
+
|
39
|
+
stack = MySQLNoIo::WrapStack.new
|
40
|
+
stack.add_wrap MySQLNoIo::Wraps::DeactivatedSlave.new client if wraps.include? :stop
|
41
|
+
stack.add_wrap MySQLNoIo::Wraps::GlobalLock.new client if wraps.include? :lock
|
42
|
+
|
43
|
+
stack.execute do
|
44
|
+
spawn *ARGV
|
45
|
+
Process.wait
|
46
|
+
end
|
47
|
+
|
48
|
+
exit $?.to_i
|
49
|
+
|
@@ -0,0 +1,12 @@
|
|
1
|
+
|
2
|
+
module MySQLNoIo
|
3
|
+
# Used in Gemspec and Commander
|
4
|
+
NAME = 'mysqlnoio'
|
5
|
+
|
6
|
+
# Used in Gemspec and Commander
|
7
|
+
VERSION = '0.1.0'
|
8
|
+
|
9
|
+
# Used in Gemspec and Commander
|
10
|
+
DESCRIPTION = 'mysqlnoio allows you to execute commands while MySQL is locked.'
|
11
|
+
end
|
12
|
+
|
@@ -0,0 +1,34 @@
|
|
1
|
+
|
2
|
+
module MySQLNoIo
|
3
|
+
|
4
|
+
# A wrap represents a open/close block which always runs a before and an
|
5
|
+
# after statement.
|
6
|
+
#
|
7
|
+
# Passing a block to #execute will execute the block from between the
|
8
|
+
# statements.
|
9
|
+
#
|
10
|
+
# Example:
|
11
|
+
# class FooWrap
|
12
|
+
# def execute &block
|
13
|
+
# puts "Hi"
|
14
|
+
#
|
15
|
+
# yeild(block)
|
16
|
+
# ensure
|
17
|
+
# puts "Bye"
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
#
|
21
|
+
# foo = FooWrap.new()
|
22
|
+
# foo.execute do
|
23
|
+
# puts "Ahh! Safety!"
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
# Will output:
|
27
|
+
# Hi
|
28
|
+
# Ahh! Safety!
|
29
|
+
# Bye
|
30
|
+
#
|
31
|
+
class Wrap
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
@@ -0,0 +1,65 @@
|
|
1
|
+
|
2
|
+
module MySQLNoIo
|
3
|
+
# A WrapStack collects a series of Wraps, and runs their #execute commands
|
4
|
+
# inside one another.
|
5
|
+
#
|
6
|
+
# Example:
|
7
|
+
# stack = MySQLNoIo::WrapStack.new()a
|
8
|
+
#
|
9
|
+
# wrapFoo = Wrap::Foo.new()
|
10
|
+
# wrapBar = Wrap::Bar.new()
|
11
|
+
#
|
12
|
+
# stack.add_stack wrapFoo
|
13
|
+
# stack.add_stack wrapBar
|
14
|
+
# stack.execute do
|
15
|
+
# puts "hi"
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# Is identical to:
|
19
|
+
# wrapFoo.execute do
|
20
|
+
# wrapBar.execute do
|
21
|
+
# puts "hi"
|
22
|
+
# end
|
23
|
+
# end
|
24
|
+
#
|
25
|
+
class WrapStack
|
26
|
+
def initialize
|
27
|
+
@wraps = []
|
28
|
+
end
|
29
|
+
|
30
|
+
# Add a layer to wrap around the execution of the command
|
31
|
+
#
|
32
|
+
# @param [MySQLNoIo::Wrap] the wrapper to add to the stack
|
33
|
+
# @raise [MySQLNoIo::Errors::ArgumentError] if the wrapper is not sufficient
|
34
|
+
#
|
35
|
+
# @return [TrueClass]
|
36
|
+
def add_wrap wrap
|
37
|
+
unless wrap.respond_to?('execute')
|
38
|
+
raise MySQLNoIo::Errors::ArgumentError.new('Wrap must respond to #execute and accept a block.')
|
39
|
+
end
|
40
|
+
|
41
|
+
@wraps << wrap
|
42
|
+
|
43
|
+
true
|
44
|
+
end
|
45
|
+
|
46
|
+
# Execute your bit of code from within the safety and comfort of the
|
47
|
+
# wrappers appended to the stack.
|
48
|
+
def execute &block
|
49
|
+
# Brace yourself.
|
50
|
+
#
|
51
|
+
# This next bit of code creates a nested lamda like the WrapStack
|
52
|
+
# describes.
|
53
|
+
deep_proc = @wraps.reverse.inject(block) do |deep_proc, layer|
|
54
|
+
Proc.new do
|
55
|
+
layer.execute do
|
56
|
+
deep_proc.call
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
deep_proc.call
|
62
|
+
end
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
@@ -0,0 +1,24 @@
|
|
1
|
+
module MySQLNoIo
|
2
|
+
module Wraps
|
3
|
+
# Just an example Wrap for testing and examples.
|
4
|
+
class Blocks
|
5
|
+
# The before block will be run prior to the execution.
|
6
|
+
def before &block
|
7
|
+
@prior = block
|
8
|
+
end
|
9
|
+
|
10
|
+
# The after block will be run post execution.
|
11
|
+
def after &block
|
12
|
+
@post = block
|
13
|
+
end
|
14
|
+
|
15
|
+
# Call the prior block, then execute, and then call the post-block.
|
16
|
+
def execute &block
|
17
|
+
@prior.call if @prior.respond_to?(:call)
|
18
|
+
block.call
|
19
|
+
ensure
|
20
|
+
@post.call if @post.respond_to?(:call)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module MySQLNoIo
|
2
|
+
module Wraps
|
3
|
+
# Stops the database slave entirely for your command
|
4
|
+
class DeactivatedSlave
|
5
|
+
def initialize mysql
|
6
|
+
@mysql = mysql
|
7
|
+
end
|
8
|
+
|
9
|
+
def execute &block
|
10
|
+
@mysql.query('STOP SLAVE;')
|
11
|
+
yield
|
12
|
+
ensure
|
13
|
+
@mysql.query('START SLAVE;')
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
@@ -0,0 +1,21 @@
|
|
1
|
+
module MySQLNoIo
|
2
|
+
module Wraps
|
3
|
+
# Allows you to run commands against a MySQL database, while MySQL's
|
4
|
+
# tables are locked, and the tables are flushed.
|
5
|
+
class GlobalLock
|
6
|
+
# Prepare to set up the GlobalLock wrapper, with the mysql2 connection
|
7
|
+
def initialize mysql
|
8
|
+
@mysql = mysql
|
9
|
+
end
|
10
|
+
|
11
|
+
# Lock the tables, run our command, and then unlock the tables.
|
12
|
+
def execute &block
|
13
|
+
@mysql.query("FLUSH TABLES WITH READ LOCK;")
|
14
|
+
yield
|
15
|
+
ensure
|
16
|
+
@mysql.query("UNLOCK TABLES;")
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
21
|
+
|
data/lib/mysqlnoio.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
|
2
|
+
require 'mysql2'
|
3
|
+
|
4
|
+
require 'mysqlnoio/about'
|
5
|
+
|
6
|
+
require 'mysqlnoio/errors'
|
7
|
+
|
8
|
+
require 'mysqlnoio/wrap_stack'
|
9
|
+
require 'mysqlnoio/wrap'
|
10
|
+
require 'mysqlnoio/wraps/blocks'
|
11
|
+
require 'mysqlnoio/wraps/global_lock'
|
12
|
+
require 'mysqlnoio/wraps/deactivated_slave'
|
13
|
+
|
14
|
+
|
15
|
+
# See: README.md
|
16
|
+
module MySQLNoIo
|
17
|
+
|
18
|
+
end
|
19
|
+
|
data/mysqlnoio.gemspec
ADDED
@@ -0,0 +1,39 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
|
5
|
+
require 'mysqlnoio/about'
|
6
|
+
|
7
|
+
Gem::Specification.new do |gem|
|
8
|
+
gem.name = MySQLNoIo::NAME
|
9
|
+
gem.version = MySQLNoIo::VERSION
|
10
|
+
gem.description = MySQLNoIo::DESCRIPTION
|
11
|
+
gem.summary = 'Execute shell commands while MySQL IO is stopped.'
|
12
|
+
gem.homepage = 'https://zippykid.com'
|
13
|
+
gem.authors = ["ZippyKid", "Graham Christensen"]
|
14
|
+
gem.email = ["info@zippykid.com"]
|
15
|
+
gem.licenses = ["MIT"]
|
16
|
+
|
17
|
+
gem.files = `git ls-files`.split($/)
|
18
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
19
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
20
|
+
gem.require_paths = ["lib"]
|
21
|
+
|
22
|
+
gem.add_dependency('mysql2')
|
23
|
+
|
24
|
+
gem.add_development_dependency('rspec')
|
25
|
+
gem.add_development_dependency('debugger')
|
26
|
+
|
27
|
+
# Guard:
|
28
|
+
gem.add_development_dependency('guard')
|
29
|
+
gem.add_development_dependency('guard-rspec')
|
30
|
+
gem.add_development_dependency('guard-shell')
|
31
|
+
gem.add_development_dependency('rb-fsevent', '~> 0.9')
|
32
|
+
gem.add_development_dependency('rb-inotify', '~> 0.9')
|
33
|
+
gem.add_development_dependency('travis-lint')
|
34
|
+
|
35
|
+
# Docs
|
36
|
+
gem.add_development_dependency('yard')
|
37
|
+
gem.add_development_dependency('redcarpet')
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,17 @@
|
|
1
|
+
require 'spec_helper.rb'
|
2
|
+
|
3
|
+
describe "mysql-noio", :integration => true do
|
4
|
+
context "called with no parameters" do
|
5
|
+
let (:output) { `bundle exec #{project_root}/bin/mysql-noio 2>&1` }
|
6
|
+
|
7
|
+
it "exits with a zero error code" do
|
8
|
+
$?.to_i.should eq(0)
|
9
|
+
end
|
10
|
+
|
11
|
+
it "does not contain something that looks like a stack trace" do
|
12
|
+
output.should_not =~ /in `<main>'/
|
13
|
+
output.should_not =~ /syntax error/
|
14
|
+
end
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe MySQLNoIo::WrapStack do
|
4
|
+
let(:stack) { MySQLNoIo::WrapStack.new }
|
5
|
+
describe "#add_wrap" do
|
6
|
+
|
7
|
+
context "An invalid wrap is provided" do
|
8
|
+
it "expects the method to have an #execute method" do
|
9
|
+
expect {
|
10
|
+
stack.add_wrap(nil)
|
11
|
+
}.to raise_error(MySQLNoIo::Errors::ArgumentError, /\#execute/)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
context "A valid wrap is provided" do
|
16
|
+
let (:wrap) { double("MySQLNoIo::Wrap", execute: true) }
|
17
|
+
it "only requires the #execute method to be callable" do
|
18
|
+
stack.add_wrap(wrap).should eq(true)
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe "#execute" do
|
24
|
+
let (:wrap_foo) do
|
25
|
+
wrap = MySQLNoIo::Wraps::Blocks.new
|
26
|
+
wrap.before do
|
27
|
+
@output << "foo-before\n"
|
28
|
+
end
|
29
|
+
wrap.after do
|
30
|
+
@output << "foo-after\n"
|
31
|
+
end
|
32
|
+
|
33
|
+
wrap
|
34
|
+
end
|
35
|
+
|
36
|
+
let (:wrap_bar) do
|
37
|
+
wrap = MySQLNoIo::Wraps::Blocks.new
|
38
|
+
wrap.before do
|
39
|
+
@output << "bar-before\n"
|
40
|
+
end
|
41
|
+
wrap.after do
|
42
|
+
@output << "bar-after\n"
|
43
|
+
end
|
44
|
+
|
45
|
+
wrap
|
46
|
+
end
|
47
|
+
|
48
|
+
it "Calls the wrappers in order, and then my bits." do
|
49
|
+
@output = ""
|
50
|
+
stack.add_wrap wrap_foo
|
51
|
+
stack.add_wrap wrap_bar
|
52
|
+
stack.execute do
|
53
|
+
@output << "Cheesy filling!\n"
|
54
|
+
end
|
55
|
+
|
56
|
+
desired_output = "foo-before\n"
|
57
|
+
desired_output << "bar-before\n"
|
58
|
+
desired_output << "Cheesy filling!\n"
|
59
|
+
desired_output << "bar-after\n"
|
60
|
+
desired_output << "foo-after\n"
|
61
|
+
|
62
|
+
@output.should eq(desired_output)
|
63
|
+
end
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
@@ -0,0 +1,44 @@
|
|
1
|
+
|
2
|
+
describe MySQLNoIo::Wraps::Blocks do
|
3
|
+
subject { MySQLNoIo::Wraps::Blocks.new() }
|
4
|
+
context "accepts a before block" do
|
5
|
+
it { should respond_to :before }
|
6
|
+
end
|
7
|
+
|
8
|
+
context "accepts an after block" do
|
9
|
+
it { should respond_to :after }
|
10
|
+
end
|
11
|
+
|
12
|
+
describe "#execute" do
|
13
|
+
context "executing a block" do
|
14
|
+
let (:wrapper) { MySQLNoIo::Wraps::Blocks.new() }
|
15
|
+
let (:block_before) { Proc.new do @output << "chocolate" end }
|
16
|
+
let (:block_execute) { Proc.new do @output << "icing" end }
|
17
|
+
let (:block_after) { Proc.new do @output << "vanilla" end }
|
18
|
+
|
19
|
+
it "executes the block passed to #execute" do
|
20
|
+
@output = ""
|
21
|
+
wrapper.execute do block_execute.call end
|
22
|
+
|
23
|
+
@output.should eq("icing")
|
24
|
+
end
|
25
|
+
|
26
|
+
it "executes the before block ... before" do
|
27
|
+
@output = ""
|
28
|
+
wrapper.before do block_before.call end
|
29
|
+
wrapper.execute do block_execute.call end
|
30
|
+
|
31
|
+
@output.should eq("chocolateicing")
|
32
|
+
end
|
33
|
+
|
34
|
+
it "executes the after block ... after" do
|
35
|
+
@output = ""
|
36
|
+
wrapper.after do block_after.call end
|
37
|
+
wrapper.execute do block_execute.call end
|
38
|
+
|
39
|
+
@output.should eq("icingvanilla")
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
describe MySQLNoIo::Wraps::DeactivatedSlave do
|
2
|
+
describe "#execute" do
|
3
|
+
it "Runs STOP SLAVE and START SLAVE around our command" do
|
4
|
+
@cmds = ""
|
5
|
+
|
6
|
+
mysql = double("MySQL2::Client")
|
7
|
+
mysql.should_receive(:query).exactly(2).times do |arg|
|
8
|
+
@cmds << "#{arg}\n"
|
9
|
+
end
|
10
|
+
|
11
|
+
wrap = MySQLNoIo::Wraps::DeactivatedSlave.new mysql
|
12
|
+
wrap.execute do
|
13
|
+
@cmds << "-- my command\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
@cmds.should eq(<<-FOO
|
17
|
+
STOP SLAVE;
|
18
|
+
-- my command
|
19
|
+
START SLAVE;
|
20
|
+
FOO
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
@@ -0,0 +1,25 @@
|
|
1
|
+
describe MySQLNoIo::Wraps::GlobalLock do
|
2
|
+
describe "#execute" do
|
3
|
+
it "Runs lock and unlock around our command" do
|
4
|
+
@cmds = ""
|
5
|
+
|
6
|
+
mysql = double("MySQL2::Client")
|
7
|
+
mysql.should_receive(:query).exactly(2).times do |arg|
|
8
|
+
@cmds << "#{arg}\n"
|
9
|
+
end
|
10
|
+
|
11
|
+
wrap = MySQLNoIo::Wraps::GlobalLock.new mysql
|
12
|
+
wrap.execute do
|
13
|
+
@cmds << "-- my command\n"
|
14
|
+
end
|
15
|
+
|
16
|
+
@cmds.should eq(<<-FOO
|
17
|
+
FLUSH TABLES WITH READ LOCK;
|
18
|
+
-- my command
|
19
|
+
UNLOCK TABLES;
|
20
|
+
FOO
|
21
|
+
)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
data/spec/spec_helper.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
|
3
|
+
apt-get update
|
4
|
+
apt-get --yes install libmysqlclient-dev mysql-server-5.5
|
5
|
+
|
6
|
+
curl -L https://get.rvm.io | bash -s stable --autolibs=3 --ruby
|
7
|
+
source /usr/local/rvm/scripts/rvm
|
8
|
+
rvm in /vagrant do bundle install
|
9
|
+
|
10
|
+
cd /vagrant
|
11
|
+
|
12
|
+
rake
|
13
|
+
|