Skip to content

Instantly share code, notes, and snippets.

@spalladino
Last active June 20, 2017 17:58
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save spalladino/c8c51f12d1957a8b7de0 to your computer and use it in GitHub Desktop.
Save spalladino/c8c51f12d1957a8b7de0 to your computer and use it in GitHub Desktop.
Rake task to copy master development database into current database branch
<%
require 'config'
branch = `git rev-parse --abbrev-ref HEAD`.strip rescue nil
use_single_db = !Settings.db_per_branch || !branch || branch == 'master'
branch_spec = (use_single_db ? "" : "_#{branch}").underscore.gsub(/[\.\/\-]/, '_')
%>
development:
<<: *default
database: app_development<%= branch_spec %>
namespace :db do
desc "Copies master development database, or specified by SOURCE env param, into current branch name only if it does not exist"
task :clone do
config = Rails.application.config.database_configuration[Rails.env]
source_db = ENV['SOURCE'].presence || 'app_development'
target_db = config['database']
mysql_opts = "-u #{config['username']} "
mysql_opts << "--password=\"#{config['password']}\" " if config['password'].presence
`mysqlshow #{mysql_opts} #{target_db.gsub('_', '\\\\\_')}`
raise "Target database #{target_db} already exists" if $?.to_i == 0
`mysqlshow #{mysql_opts} #{source_db.gsub('_', '\\\\\_')}`
raise "Source database #{source_db} not found" if $?.to_i != 0
puts "Creating empty database #{target_db}"
`mysql #{mysql_opts} -e "CREATE DATABASE #{target_db}"`
puts "Copying #{source_db} into #{target_db}"
`mysqldump #{mysql_opts} #{source_db} | mysql #{mysql_opts} #{target_db}`
end
end
@joshuapinter
Copy link

joshuapinter commented Nov 17, 2016

Thanks for this!

I made a small improvement to automatically determine the source DB by replacing "master" in the target db name with the current branch name.

namespace :db do

  desc "Copies master development database, or specified by SOURCE env param, into current branch name only if it does not exist"
  task :clone_from_master do
    config = Rails.application.config.database_configuration[Rails.env]

    target_db = config['database']
    source_db = target_db.sub(CURRENT_BRANCH, ENV['SOURCE'].presence || 'master')

    mysql_opts =  "-u #{config['username']} "
    mysql_opts << "--password=\"#{config['password']}\" " if config['password'].presence

    `mysqlshow #{mysql_opts} #{target_db.gsub('_', '\\\\\_')}`
    raise "Target database #{target_db} already exists" if $?.to_i == 0

    `mysqlshow #{mysql_opts} #{source_db.gsub('_', '\\\\\_')}`
    raise "Source database #{source_db} not found" if $?.to_i != 0

    puts "Creating empty database #{target_db}"
    `mysql #{mysql_opts} -e "CREATE DATABASE #{target_db}"`

    puts "Copying #{source_db} into #{target_db}"
    `mysqldump #{mysql_opts} #{source_db} | mysql #{mysql_opts} #{target_db}`
  end

end

Where CURRENT_BRANCH is determined as a global constant like this:

CURRENT_BRANCH = `git status | head -1`.to_s.gsub('On branch ','').chomp

Thanks again!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment