databranch 0.1.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.
@@ -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: []