-
-
Save ghiculescu/234da1a8aada56d543e6b876a17859ff 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
# typed: false | |
require "English" | |
namespace :db do | |
task :prevent_disparate_pg_dump_versions => :environment do | |
allowed_pg_dump_version = "x.x.x".freeze | |
`pg_dump --version` | |
pg_dump_exit_status = $CHILD_STATUS.exitstatus | |
locally_installed_version = begin | |
`pg_dump --version`.chomp[/(\d.*)/, 1] | |
rescue StandardError | |
nil | |
end | |
if locally_installed_version != allowed_pg_dump_version | |
puts(<<~OUTPUT_BLOCK) | |
Required pg_dump version: #{allowed_pg_dump_version} | |
Your version: #{locally_installed_version} | |
OUTPUT_BLOCK | |
if Gem::Version.new(locally_installed_version) > Gem::Version.new(allowed_pg_dump_version) | |
puts(<<~OUTPUT_BLOCK) | |
--- | |
Your local version of postgresql is ahead of the pinned version in: | |
`lib/tasks/migrate_enhancements.rake`. | |
Please update `allowed_pg_dump_version` in `lib/tasks/migrate_enhancements.rake` | |
to match your version (as listed above). | |
--- | |
OUTPUT_BLOCK | |
raise("You must update `lib/tasks/migrate_enhancements.rake` if you wish to proceed with migrating") | |
else | |
puts(<<~OUTPUT_BLOCK) | |
--- | |
Linux upgrade command: `sudo apt-get update && sudo apt-get upgrade` | |
OS X upgrade command: `brew upgrade postgresql@9.6` | |
You may also need to tell OS X how to use your Homebrew version of postgres. | |
To do this, run `brew info postgresql@9.6`. 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") | |
end | |
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 postgresql@9.6` | |
--- | |
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 | |
# also removes duplicates! | |
task :make_structure_sql_match_db_migrate_folder do | |
path = Rails.root.join("db", "structure.sql") | |
structure_sql_lines = File.read(path).lines | |
migration_insert_index = structure_sql_lines.index { |l| l == "INSERT INTO \"schema_migrations\" (version) VALUES\n" } | |
migration_lines = structure_sql_lines[migration_insert_index + 1..-1] | |
migrations_in_repo = Set.new(Dir.glob("db/migrate/*.rb").map { |p| p.match(/[0-9]+/).try { |m| m[0] } }) | |
seen_migration_lines = Set.new | |
correct_structure_sql_lines = migration_lines.select do |line| | |
match = line.match(/\('(\d+)'\)/) | |
should_include = !match || (migrations_in_repo.include?(match[1]) && !seen_migration_lines.include?(match[1])) | |
seen_migration_lines << match[1] if should_include && match | |
should_include | |
end.flatten | |
index_of_last_populated_line = -correct_structure_sql_lines.reverse.index(&:present?) - 1 | |
if correct_structure_sql_lines[index_of_last_populated_line].end_with?(",\n") | |
correct_structure_sql_lines[index_of_last_populated_line] = "#{correct_structure_sql_lines[index_of_last_populated_line][0...-2]};" | |
end | |
File.write(path, (structure_sql_lines[0..migration_insert_index] + correct_structure_sql_lines).join) | |
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 | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment