databranch 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: f7b6a1603090c8eabfd52fef8aeb15dd58c2bf69
4
+ data.tar.gz: fda508a6a788fb10e0cd6ae282f4e43352b3a991
5
+ SHA512:
6
+ metadata.gz: a4b3c9a07686c128b09414fb40d5144b787f3a7135ab1ae9c3696412f441c41eaadb9f053060a168d94c7eb8192d578dc1781b1e86c0b412de546d8e41efd435
7
+ data.tar.gz: 25041abeff90f51e0682529e19010de10fa99738a7868ca6b1d6136bb77c46b9d68de4c4b84b36849f9f4927e3d817d8b12fecc23b9621650e0a27b69776afe8
@@ -0,0 +1,5 @@
1
+ require "databranch/version"
2
+
3
+ module Databranch
4
+ require 'databranch/railtie' if defined?(Rails)
5
+ end
@@ -0,0 +1,11 @@
1
+ require 'databranch'
2
+ require 'rails'
3
+ module Databranch
4
+ class Railtie < Rails::Railtie
5
+ railtie_name :databranch
6
+
7
+ rake_tasks do
8
+ load File.join(File.dirname(__FILE__),'../tasks/databranch.rake')
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,3 @@
1
+ module Databranch
2
+ VERSION = "0.1.1"
3
+ end
@@ -0,0 +1,93 @@
1
+ #!/bin/bash
2
+
3
+ previous_git_head=$1
4
+ new_git_head=$2
5
+
6
+ previous_branch=$(git rev-parse --symbolic-full-name --abbrev-ref @{-1})
7
+ new_branch=$(git rev-parse --symbolic-full-name --abbrev-ref HEAD)
8
+
9
+ checkout_type=$3
10
+ checkout_count=`git reflog --date=local | grep -o ${new_branch} | wc -l`
11
+
12
+ previous_database="${PWD##*/}_development_${previous_branch//-/_}"
13
+ fallback_database="${PWD##*/}_development_master"
14
+ new_database="${PWD##*/}_development_${new_branch//-/_}"
15
+ test_database="${PWD##*/}_test_${new_branch//-/_}"
16
+
17
+ function ensure_not_file_checkout {
18
+ # this is a file checkout so don't do anything
19
+ if [ "$checkout_type" == "0" ]; then exit; fi
20
+ }
21
+
22
+ function ensure_not_rebase {
23
+ # this is a rebase so don't do anything
24
+ if [ $new_branch == 'HEAD' ]; then exit; fi
25
+ }
26
+
27
+ function database_exists {
28
+ if psql -lqt | cut -d \| -f 1 | grep -w $1; then
29
+ return 0
30
+ else
31
+ return 1
32
+ fi
33
+ }
34
+
35
+ function new_branch_created {
36
+ if [ "$previous_git_head" == "$new_git_head" ] && [ ${checkout_count} -eq 1 ]; then
37
+ return 0
38
+ else
39
+ return 1
40
+ fi
41
+ }
42
+
43
+ function should_create_database {
44
+ database=$1
45
+ if database_exists $database; then
46
+ if new_branch_created; then
47
+ return 0
48
+ else
49
+ return 1
50
+ fi
51
+ else
52
+ return 0
53
+ fi
54
+ }
55
+
56
+ ensure_not_file_checkout
57
+ ensure_not_rebase
58
+
59
+ #possibly neccessary if order of operation below doesn't work as expected
60
+ #create_db = should_create_database $new_database
61
+
62
+ #move this into a function
63
+ if should_create_database $new_database; then
64
+ echo "Creating Database $new_database"
65
+ createdb $new_database
66
+ createdb $test_database
67
+
68
+ # simplify conditional logic to just assign database to copy from and the message to DRY it up
69
+ if database_exists $previous_database; then
70
+ echo "Copying data and schema from $previous_database from the previous branch"
71
+ pg_dump $previous_database | psql $new_database
72
+ echo "Creating the test database $test_database for this branch"
73
+ pg_dump -s $previous_database | psql $test_database
74
+ else
75
+ echo "Couldn't find a database for the previous branch"
76
+ echo "Copying data and schema from $fallback_database from the master branch"
77
+ pg_dump $fallback_database | psql $new_database
78
+ echo "Creating the test database $test_database for this branch"
79
+ pg_dump -s $fallback_database | psql $test_database
80
+ fi
81
+ else
82
+ echo "No need to create a database"
83
+ fi
84
+
85
+ echo ' prev branch: '$previous_branch
86
+ echo ' new branch: '$new_branch
87
+
88
+ if [ -f "tmp/pids/server.pid" ]
89
+ then
90
+ rails restart
91
+ else
92
+ touch tmp/restart.txt
93
+ fi
@@ -0,0 +1,7 @@
1
+ # Databranch
2
+ # ^
3
+ # ^^^
4
+ # ^^^^^
5
+ ./.git/hooks/databranch-post-checkout
6
+
7
+ # (^_^)/
@@ -0,0 +1,35 @@
1
+ #!/bin/bash
2
+
3
+ psql -t -A -c 'SELECT datname FROM pg_database' |
4
+ grep ^${PWD##*/}_development_.*$ |
5
+ grep -v master |
6
+ awk "{gsub(/^${PWD##*/}_development_/, \"\")}1" |
7
+ awk '{gsub(/_/, "-")}1' |
8
+ xargs -I {} bash -c 'if [ ! "`git branch --list {}`" ] ; then echo "{}"; fi' |
9
+ awk '{gsub(/-/, "_")}1' |
10
+ awk "\$0=\"${PWD##*/}_development_\"\$0" |
11
+ xargs -I {} bash -c '
12
+ echo "Drop database {}? (Y/n)"
13
+ read yn </dev/tty
14
+ case $yn in
15
+ [Yy] ) dropdb {};;
16
+ [Nn] ) exit;;
17
+ * ) exit;;
18
+ esac'
19
+
20
+ psql -t -A -c 'SELECT datname FROM pg_database' |
21
+ grep ^${PWD##*/}_test_.*$ |
22
+ grep -v master |
23
+ awk "{gsub(/^${PWD##*/}_test_/, \"\")}1" |
24
+ awk '{gsub(/_/, "-")}1' |
25
+ xargs -I {} bash -c 'if [ ! "`git branch --list {}`" ] ; then echo "{}"; fi' |
26
+ awk '{gsub(/-/, "_")}1' |
27
+ awk "\$0=\"${PWD##*/}_test_\"\$0" |
28
+ xargs -I {} bash -c '
29
+ echo "Drop database {}? (Y/n)"
30
+ read yn </dev/tty
31
+ case $yn in
32
+ [Yy] ) dropdb {};;
33
+ [Nn] ) exit;;
34
+ * ) exit;;
35
+ esac'
@@ -0,0 +1,7 @@
1
+ # Databranch
2
+ # ^
3
+ # ^^^
4
+ # ^^^^^
5
+ ./.git/hooks/databranch-post-commit
6
+
7
+ # (^_^)/
@@ -0,0 +1,76 @@
1
+ namespace :databranch do
2
+ desc 'Creates git hooks to change database based on branch'
3
+ task :install do
4
+ app_name = Rails.application.class.parent_name.underscore
5
+
6
+ # a .git repo in another location can be used with the $GIT_DIR or $GIT_OBJECT_DIRECTORY env vars, so check for this (https://git-scm.com/docs/git-init)
7
+ if !File.exists?('.git')
8
+ print "No Git repo exists, would you like to initiate one? (Y/n): "
9
+ git_confirmation = STDIN.gets.chomp.downcase
10
+ if git_confirmation.match(/y(?:es)?/)
11
+ puts "Initiating Git repo now"
12
+ `git init`
13
+ `git add .; git commit -m 'Initiate git repo'`
14
+ else
15
+ fail "A Git repo is required for Databranch to work. Please initiate one and then install Databranch."
16
+ end
17
+ end
18
+
19
+ `createdb #{app_name}_development_master` unless db_exists?("#{app_name}_development_master")
20
+ `createdb #{app_name}_test_master` unless db_exists?("#{app_name}_test_master")
21
+
22
+ if db_exists? "#{app_name}_development"
23
+ puts "Cloning the existing development database for master"
24
+ `pg_dump #{app_name}_development | psql #{app_name}_development_master`
25
+ end
26
+
27
+ if db_exists? "#{app_name}_test"
28
+ puts "Cloning the existing test database for master"
29
+ `pg_dump -s #{app_name}_test | psql #{app_name}_test_master`
30
+ end
31
+
32
+ File.open('./config/initializers/databranch.rb', 'w') do |file|
33
+ branch = '#{`git rev-parse --abbrev-ref HEAD`.chomp.underscore}'
34
+ file << %Q{ENV["DATABRANCH_#{app_name.upcase}_DEV"] = "#{app_name}_development_#{branch}"\n}
35
+ file << %Q{ENV["DATABRANCH_#{app_name.upcase}_TEST"] = "#{app_name}_test_#{branch}"}
36
+ end
37
+
38
+ current_file_path = File.expand_path(File.dirname(__FILE__))
39
+ post_checkout_code = File.read("#{current_file_path}/../hooks/post_checkout/post-checkout")
40
+ post_checkout_path = "./.git/hooks/post-checkout"
41
+
42
+ if File.exists? post_checkout_path
43
+ puts "A post-checkout hook already exists. Please add a line to your post-checkout hook file that executes the file 'databranch-post-checkout'"
44
+ else
45
+ File.open post_checkout_path, "w" do |file|
46
+ file << "#!/bin/bash\n\n"
47
+ file << post_checkout_code
48
+ end
49
+ end
50
+ FileUtils.copy("#{current_file_path}/../hooks/post_checkout/databranch-post-checkout", "./.git/hooks/databranch-post-checkout")
51
+ `chmod +x ./.git/hooks/post-checkout`
52
+ `chmod +x ./.git/hooks/databranch-post-checkout`
53
+
54
+
55
+ post_commit_code = File.read("#{current_file_path}/../hooks/post_commit/post-commit")
56
+ post_commit_path = "./.git/hooks/post-commit"
57
+
58
+ if File.exists? post_commit_path
59
+ puts "A post-commit hook already exists. Please add a line to your post-commit hook file that executes the file 'databranch-post-commit'"
60
+ else
61
+ File.open post_commit_path, "w" do |file|
62
+ file << "#!/bin/bash\n\n"
63
+ file << post_commit_code
64
+ end
65
+ end
66
+ FileUtils.copy("#{current_file_path}/../hooks/post_commit/databranch-post-commit", "./.git/hooks/databranch-post-commit")
67
+ `chmod +x ./.git/hooks/post-commit`
68
+ `chmod +x ./.git/hooks/databranch-post-commit`
69
+ end
70
+
71
+ def db_exists?(name)
72
+ true if PG.connect dbname: name
73
+ rescue PG::ConnectionBad => e
74
+ false
75
+ end
76
+ end
metadata ADDED
@@ -0,0 +1,113 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: databranch
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - Guru Khalsa
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2017-03-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.12'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.12'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: minitest
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '5.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '5.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pg
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: '0.19'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: '0.19'
69
+ description: Implements database branching in development and test by cloning the
70
+ database automatically, supplementing Git branching workflow. This prevents situations
71
+ where the database becomes stale due to schema or data inconsistencies between git
72
+ branches. It automates the process of creating and deleting branch database copies
73
+ by hooking into git.
74
+ email:
75
+ - guru5997@me.com
76
+ executables: []
77
+ extensions: []
78
+ extra_rdoc_files: []
79
+ files:
80
+ - lib/databranch.rb
81
+ - lib/databranch/railtie.rb
82
+ - lib/databranch/version.rb
83
+ - lib/hooks/post_checkout/databranch-post-checkout
84
+ - lib/hooks/post_checkout/post-checkout
85
+ - lib/hooks/post_commit/databranch-post-commit
86
+ - lib/hooks/post_commit/post-commit
87
+ - lib/tasks/databranch.rake
88
+ homepage: http://rubygems.org/gems/databranch
89
+ licenses:
90
+ - MIT
91
+ metadata: {}
92
+ post_install_message:
93
+ rdoc_options: []
94
+ require_paths:
95
+ - lib
96
+ required_ruby_version: !ruby/object:Gem::Requirement
97
+ requirements:
98
+ - - ">="
99
+ - !ruby/object:Gem::Version
100
+ version: '0'
101
+ required_rubygems_version: !ruby/object:Gem::Requirement
102
+ requirements:
103
+ - - ">="
104
+ - !ruby/object:Gem::Version
105
+ version: '0'
106
+ requirements: []
107
+ rubyforge_project:
108
+ rubygems_version: 2.5.1
109
+ signing_key:
110
+ specification_version: 4
111
+ summary: Implements database branching in development and test by cloning the database
112
+ automatically, supplementing Git branching workflow.
113
+ test_files: []