-
-
Save abhilashak/e32c7d6d2df4639a606e305967e386c2 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'English' | |
namespace :db do # rubocop:disable Metrics/BlockLength | |
task :prevent_disparate_pg_dump_versions => :environment do | |
allowed_pg_dump_version = '9.6.10'.freeze | |
`pg_dump --version` | |
pg_dump_exit_status = $CHILD_STATUS.exitstatus | |
locally_installed_version = `pg_dump --version`.chomp[/(\d.*)/,1] rescue nil | |
if locally_installed_version != allowed_pg_dump_version | |
puts <<~OUTPUT_BLOCK | |
Required pg_dump version: #{allowed_pg_dump_version} | |
Your version: #{locally_installed_version} | |
--- | |
Linux upgrade command: `sudo apt-get update && sudo apt-get upgrade` | |
OS X upgrade command: `brew upgrade [email protected]` | |
You may also need to tell OS X how to use your Homebrew version of postgres. | |
To do this, run `brew info [email protected]`. There will be a command output that tells you | |
how to add it to your path. Follow those instructions. | |
--- | |
OUTPUT_BLOCK | |
raise 'You must update your postgresql-client if you wish to proceed with migrating' | |
elsif pg_dump_exit_status == 127 | |
puts <<~OUTPUT_BLOCK | |
System postgres client not installed - it is needed for the db:migrate task. | |
--- | |
Linux install command: | |
`sudo add-apt-repository "deb http://apt.postgresql.org/pub/repos/apt/ $(lsb_release -sc)-pgdg main"` | |
`wget --quiet -O - https://www.postgresql.org/media/keys/ACCC4CF8.asc | sudo apt-key add -` | |
`sudo apt-get update && sudo apt-get install postgresql-9.6` | |
OS X install command: `brew install [email protected]` | |
--- | |
OUTPUT_BLOCK | |
raise 'You must install postgresql-client if you wish to proceed with migrating' | |
end | |
end | |
# keep structure.sql in sync with the actual files in the db/migrate folder | |
# this minimises the chance of merge conflicts if different branches add migrations | |
# since, ideally, migrations will not make it to master in this file unless the corresponding | |
# migration actaully exists | |
task :make_structure_sql_match_db_migrate_folder do | |
path = Rails.root.join('db', 'structure.sql') | |
double_newline = "\n\n" | |
structure_sql_lines = File.read(path).split(double_newline, -1) | |
migrations_in_repo = Set.new(Dir.glob('db/migrate/*.rb').map {|p| p.match(/[0-9]+/).try {|m| m[0]}}) | |
correct_structure_sql_lines = structure_sql_lines.find_all do |line| | |
not_a_schema_migration = line.blank? || | |
line == "\n" || | |
!line.start_with?("INSERT INTO schema_migrations") | |
if not_a_schema_migration | |
true | |
else | |
migration_number = line.match(/[0-9]+/).try {|m| m[0]} | |
migration_number && migrations_in_repo.include?(migration_number) | |
end | |
end.flatten | |
File.write(path, correct_structure_sql_lines.join(double_newline)) | |
end | |
# if someone creates a view on common DB we don't want it in structure.sql | |
# because it shoudn't be needed in tests | |
# once we are on Rails 5 a better option might be to do this at the pg_dump layer by passing in `extra_flags` to | |
# https://github.com/rails/rails/blob/master/activerecord/lib/active_record/tasks/postgresql_database_tasks.rb#L51 | |
task :remove_views_from_structure_sql do | |
path = Rails.root.join('db', 'structure.sql') | |
double_newline = "\n\n" | |
structure_sql_lines = File.read(path).split(double_newline, -1) | |
correct_structure_sql_lines = structure_sql_lines.find_all do |line| | |
line.present? && | |
!line.start_with?("CREATE VIEW") && # view definition | |
!line.include?("Type: VIEW; Schema: public;") # comment above view definition | |
end.flatten | |
File.write(path, correct_structure_sql_lines.join(double_newline)) | |
end | |
end | |
if Rails.env.development? | |
# see http://edgar.tumblr.com/post/52300664342/how-to-extend-an-existing-rake-task | |
# if you call #enhance with an array it sets it as a prereq (runs before) | |
# if you give #enhance a block it adds a behaviour (runs after) | |
# see https://github.com/ruby/rake/blob/v10.5.0/lib/rake/task.rb#L100 if you don't believe an API this odd could exist | |
Rake::Task['db:migrate'].enhance ['db:prevent_disparate_pg_dump_versions'] | |
Rake::Task['db:migrate'].enhance do | |
Rake::Task['db:make_structure_sql_match_db_migrate_folder'].invoke | |
end | |
Rake::Task['db:migrate'].enhance do | |
Rake::Task['db:remove_views_from_structure_sql'].invoke | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment