flipp 0.0.1
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.md +17 -0
- data/Rakefile +2 -0
- data/flipp.gemspec +24 -0
- data/lib/flipp.rb +2 -0
- data/lib/flipp/flipp.rb +56 -0
- data/lib/flipp/railties/reestablish_connection.rb +11 -0
- data/lib/helpers/git_helper.rb +33 -0
- data/spec/lib/flipp/flipp_spec.rb +66 -0
- data/spec/lib/helpers/git_helper_spec.rb +41 -0
- data/spec/spec_helper.rb +3 -0
- data/tasks/flipp.rb +15 -0
- metadata +82 -0
data/README.md
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
# flipp
|
2
|
+
|
3
|
+
To alleviate issues around highly divergent development databases on feature/refactor branches, flipp helps switch databases upon new branch checkouts.
|
4
|
+
|
5
|
+
# Database Support
|
6
|
+
|
7
|
+
Current support is for MySQL only.
|
8
|
+
|
9
|
+
# Installation & Usage
|
10
|
+
|
11
|
+
1. Add `gem 'flipp'` to your Gemfile or do `gem install flipp`.
|
12
|
+
2. Run `rake flipp:install` from your project's root directory to install the git hook
|
13
|
+
3. Normal git workflow, ie. switch branches normally
|
14
|
+
|
15
|
+
# License
|
16
|
+
|
17
|
+
flipp is released under the MIT license
|
data/Rakefile
ADDED
data/flipp.gemspec
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
lib = File.expand_path('../lib/', __FILE__)
|
2
|
+
$:.unshift lib unless $:.include?(lib)
|
3
|
+
|
4
|
+
require 'bundler'
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "flipp"
|
8
|
+
s.version = '0.0.1'
|
9
|
+
s.platform = Gem::Platform::RUBY
|
10
|
+
s.authors = ["Mike Pack"]
|
11
|
+
s.email = ["mikepackdev@gmail.com"]
|
12
|
+
s.homepage = "http://www.mikepackdev.com"
|
13
|
+
s.summary = %q{Switch development databases upon branch checkouts.}
|
14
|
+
s.description = %q{To alleviate issues around highly divergent development databases on feature/refactor branches, flipp helps switch databases upon new branch checkouts.}
|
15
|
+
|
16
|
+
s.required_rubygems_version = ">= 1.3.6"
|
17
|
+
|
18
|
+
s.add_runtime_dependency 'active_record'
|
19
|
+
s.add_runtime_dependency 'database_exporter'
|
20
|
+
|
21
|
+
s.files = %w( README.md Rakefile flipp.gemspec tasks/flipp.rb ) + Dir["lib/**/*.rb"]
|
22
|
+
s.test_files = Dir["spec/**/*.rb"]
|
23
|
+
s.require_paths = ["lib"]
|
24
|
+
end
|
data/lib/flipp.rb
ADDED
data/lib/flipp/flipp.rb
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'active_record'
|
3
|
+
require 'database_exporter'
|
4
|
+
require File.join(File.dirname(__FILE__), '../helpers/git_helper')
|
5
|
+
|
6
|
+
# The Flipp class orchestrates the actual switching of databaseses
|
7
|
+
class Flipp
|
8
|
+
def initialize(branch = GitHelper.current_branch)
|
9
|
+
@branch = branch
|
10
|
+
end
|
11
|
+
|
12
|
+
def switch_databases
|
13
|
+
current_config = ActiveRecord::Base.connection_pool.spec.config
|
14
|
+
new_config = current_config.merge!({:database => new_database_name(current_config)})
|
15
|
+
|
16
|
+
puts "Switching databases (#{new_config[:database]})..."
|
17
|
+
|
18
|
+
# Try connecting to the new database
|
19
|
+
begin
|
20
|
+
ActiveRecord::Base.establish_connection new_config
|
21
|
+
rescue
|
22
|
+
create_new_db_or_fallback current_config, new_config
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
def create_new_db_or_fallback(current_config, new_config)
|
27
|
+
# Try creating then connecting to the new database
|
28
|
+
begin
|
29
|
+
create_and_copy_data! current_config, new_config
|
30
|
+
rescue => exception
|
31
|
+
# Fallback and use the original config
|
32
|
+
puts "Could not use the new database, falling back to your normal development database..."
|
33
|
+
ActiveRecord::Base.establish_connection current_config
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
37
|
+
def new_database_name(config)
|
38
|
+
# The new name for the database
|
39
|
+
# eg. if the original dev database is dev_db and the branch was "new_feature",
|
40
|
+
# the new database would be db_db_new_feature
|
41
|
+
config[:database] + '_' + @branch
|
42
|
+
end
|
43
|
+
|
44
|
+
def create_and_copy_data!(current_config, new_config)
|
45
|
+
# Copy the current development database's data to the new database
|
46
|
+
puts "Copying data to the new database (this could take a minute but will only run once)..."
|
47
|
+
copy_data current_config, new_config
|
48
|
+
|
49
|
+
# Try out the new database
|
50
|
+
ActiveRecord::Base.establish_connection new_config
|
51
|
+
end
|
52
|
+
|
53
|
+
def copy_data(current_config, new_config)
|
54
|
+
DatabaseExporter.new(current_config).copy(new_config)
|
55
|
+
end
|
56
|
+
end
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'flipp'
|
2
|
+
|
3
|
+
class ReestablishConnection < Rails::Railtie
|
4
|
+
initializer "restablish_connection.configure_rails_initialization" do
|
5
|
+
if Rails.env.development? and GitHelper.hook_installed?
|
6
|
+
# Use the connection determined by flipp
|
7
|
+
flipp = Flipp.new
|
8
|
+
flipp.switch_databases
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
module GitHelper
|
4
|
+
def self.hook_installed?
|
5
|
+
File.exists? '.git/hooks/post-checkout'
|
6
|
+
end
|
7
|
+
|
8
|
+
def self.install_hook
|
9
|
+
# Check for the .git directory
|
10
|
+
if File.directory? '.git'
|
11
|
+
unless File.directory? '.git/hooks'
|
12
|
+
# Create hooks directory
|
13
|
+
end
|
14
|
+
|
15
|
+
# Copy the file to the git hooks
|
16
|
+
puts 'Moving git hook into place...'
|
17
|
+
FileUtils.cp 'lib/git_hooks/post-checkout', File.expand_path('.git/hooks/post-checkout')
|
18
|
+
# And give it execute permissions
|
19
|
+
FileUtils.chmod 0755, '.git/hooks/post-checkout'
|
20
|
+
else
|
21
|
+
puts "Can't find your .git directory. Are you at the root of your project?"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
def self.uninstall_hook
|
26
|
+
puts 'Removing git hook...'
|
27
|
+
FileUtils.rm File.expand_path('.git/hooks/post-checkout')
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.current_branch
|
31
|
+
`git branch --no-color 2> /dev/null | sed -e '/^[^*]/d' -e 's/* /\1/'`.chomp[1..-1] # Remove control character
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,66 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe Flipp do
|
4
|
+
let(:flipp) { Flipp.new('new_feature_branch') }
|
5
|
+
let(:old_db) { {:adapter => 'mysql2', :host => 'localhost', :username => 'root', :database => 'old_db'} }
|
6
|
+
let(:new_db) { {:adapter => 'mysql2', :host => 'localhost', :username => 'root', :database => 'new_db'} }
|
7
|
+
|
8
|
+
describe '#switch_databases' do
|
9
|
+
before do
|
10
|
+
# Stub the current connection
|
11
|
+
ActiveRecord::Base.stub_chain(:connection_pool, :spec, :config).and_return({:adapter => 'mysql2', :host => 'localhost', :username => 'root', :database => 'old_db'})
|
12
|
+
end
|
13
|
+
|
14
|
+
it 'tries to connect to the new database' do
|
15
|
+
ActiveRecord::Base.should_receive(:establish_connection).with(an_instance_of(Hash))
|
16
|
+
flipp.switch_databases
|
17
|
+
end
|
18
|
+
|
19
|
+
it 'tries to create and copy data to new database, then connect' do
|
20
|
+
ActiveRecord::Base.stub(:establish_connection) { raise }
|
21
|
+
flipp.should_receive(:create_new_db_or_fallback).with(an_instance_of(Hash), an_instance_of(Hash))
|
22
|
+
flipp.switch_databases
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
describe '#create_new_db_or_fallback' do
|
27
|
+
it 'falls back on the original connection if the new database can not be formed' do
|
28
|
+
flipp.stub(:create_and_copy_data!) { raise }
|
29
|
+
flipp.should_receive(:create_and_copy_data!).with(old_db, new_db)
|
30
|
+
ActiveRecord::Base.should_receive(:establish_connection).with(old_db)
|
31
|
+
flipp.create_new_db_or_fallback(old_db, new_db)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
describe '#new_database_name' do
|
36
|
+
it 'constructs a database name consisting of the current dev db and the branch name' do
|
37
|
+
flipp.new_database_name({:database => 'dev_db'}).should == 'dev_db_new_feature_branch'
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
describe '#create_and_copy_data!' do
|
42
|
+
it 'copies the database' do
|
43
|
+
flipp.should_receive(:copy_data).with(old_db, new_db)
|
44
|
+
flipp.create_and_copy_data!(old_db, new_db)
|
45
|
+
end
|
46
|
+
|
47
|
+
it 'tries to connect to the new database' do
|
48
|
+
ActiveRecord::Base.should_receive(:establish_connection).with(new_db)
|
49
|
+
flipp.create_and_copy_data!(old_db, new_db)
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
describe '#copy_data' do
|
54
|
+
it 'invokes the database adapter and makes a copy' do
|
55
|
+
# Mock DatabaseExporter so we can access the #copy method
|
56
|
+
mock = double(DatabaseExporter)
|
57
|
+
DatabaseExporter.stub(:new).and_return(mock)
|
58
|
+
|
59
|
+
# Expect it to instantiate and call the #copy method
|
60
|
+
DatabaseExporter.should_receive(:new).with(old_db)
|
61
|
+
mock.should_receive(:copy).with(new_db)
|
62
|
+
|
63
|
+
flipp.copy_data(old_db, new_db)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe GitHelper do
|
4
|
+
describe '#hook_installed?' do
|
5
|
+
it 'returns true when the hook exists' do
|
6
|
+
FileUtils.touch '.git/hooks/post-checkout'
|
7
|
+
GitHelper.hook_installed?.should be_true
|
8
|
+
end
|
9
|
+
|
10
|
+
it 'returns false when the hook does not exists' do
|
11
|
+
FileUtils.rm '.git/hooks/post-checkout'
|
12
|
+
GitHelper.hook_installed?.should be_false
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
describe '#install_hook' do
|
17
|
+
it 'moves the git hook into place' do
|
18
|
+
GitHelper.install_hook
|
19
|
+
FileUtils.compare_file('.git/hooks/post-checkout', File.expand_path('../../../../lib/git_hooks/post-checkout', __FILE__))
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
describe '#uninstall_hook' do
|
24
|
+
before { GitHelper.install_hook }
|
25
|
+
|
26
|
+
it 'remove the git hook' do
|
27
|
+
GitHelper.uninstall_hook
|
28
|
+
GitHelper.hook_installed?.should be_false
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
describe '#current_branch' do
|
33
|
+
it 'returns the name of the current git branch' do
|
34
|
+
`git checkout -b new_and_fun_branch`
|
35
|
+
GitHelper.current_branch.should == 'new_and_fun_branch'
|
36
|
+
|
37
|
+
# Cleanup
|
38
|
+
`git checkout master && git branch -d new_and_fun_branch`
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
data/spec/spec_helper.rb
ADDED
data/tasks/flipp.rb
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
require File.join(File.dirname(__FILE__), '../lib/helpers/git_helper')
|
2
|
+
|
3
|
+
namespace :flipp do
|
4
|
+
desc 'Install flipp'
|
5
|
+
task :install do
|
6
|
+
# Move git hook into place
|
7
|
+
GitHelper.install_hook
|
8
|
+
end
|
9
|
+
|
10
|
+
desc 'Uninstall flipp'
|
11
|
+
task :uninstall do
|
12
|
+
# Remove git hook
|
13
|
+
GitHelper.uninstall_hook
|
14
|
+
end
|
15
|
+
end
|
metadata
ADDED
@@ -0,0 +1,82 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: flipp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Mike Pack
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-02-19 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: active_record
|
16
|
+
requirement: &70345674000980 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70345674000980
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: database_exporter
|
27
|
+
requirement: &70345673999500 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ! '>='
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: '0'
|
33
|
+
type: :runtime
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70345673999500
|
36
|
+
description: To alleviate issues around highly divergent development databases on
|
37
|
+
feature/refactor branches, flipp helps switch databases upon new branch checkouts.
|
38
|
+
email:
|
39
|
+
- mikepackdev@gmail.com
|
40
|
+
executables: []
|
41
|
+
extensions: []
|
42
|
+
extra_rdoc_files: []
|
43
|
+
files:
|
44
|
+
- README.md
|
45
|
+
- Rakefile
|
46
|
+
- flipp.gemspec
|
47
|
+
- tasks/flipp.rb
|
48
|
+
- lib/flipp/flipp.rb
|
49
|
+
- lib/flipp/railties/reestablish_connection.rb
|
50
|
+
- lib/flipp.rb
|
51
|
+
- lib/helpers/git_helper.rb
|
52
|
+
- spec/lib/flipp/flipp_spec.rb
|
53
|
+
- spec/lib/helpers/git_helper_spec.rb
|
54
|
+
- spec/spec_helper.rb
|
55
|
+
homepage: http://www.mikepackdev.com
|
56
|
+
licenses: []
|
57
|
+
post_install_message:
|
58
|
+
rdoc_options: []
|
59
|
+
require_paths:
|
60
|
+
- lib
|
61
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ! '>='
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
|
+
none: false
|
69
|
+
requirements:
|
70
|
+
- - ! '>='
|
71
|
+
- !ruby/object:Gem::Version
|
72
|
+
version: 1.3.6
|
73
|
+
requirements: []
|
74
|
+
rubyforge_project:
|
75
|
+
rubygems_version: 1.8.10
|
76
|
+
signing_key:
|
77
|
+
specification_version: 3
|
78
|
+
summary: Switch development databases upon branch checkouts.
|
79
|
+
test_files:
|
80
|
+
- spec/lib/flipp/flipp_spec.rb
|
81
|
+
- spec/lib/helpers/git_helper_spec.rb
|
82
|
+
- spec/spec_helper.rb
|