mirror of
https://gitlab.com/gitlab-org/gitlab-foss.git
synced 2025-07-23 00:47:51 +00:00
125 lines
2.9 KiB
Ruby
Executable File
125 lines
2.9 KiB
Ruby
Executable File
#!/usr/bin/env ruby
|
|
|
|
# frozen_string_literal: true
|
|
|
|
ENV['RAILS_ENV'] = 'test'
|
|
|
|
require 'optparse'
|
|
require 'open3'
|
|
require 'fileutils'
|
|
require 'uri'
|
|
require 'gitlab-chronic'
|
|
|
|
class MigrationsTimestampRefresher
|
|
##
|
|
# Directories where migrations are stored
|
|
MIGRATION_DIRS = %w[db/migrate db/post_migrate].join(' ').freeze
|
|
|
|
def initialize(options)
|
|
@options = options
|
|
end
|
|
|
|
def execute
|
|
Dir.chdir(File.expand_path('..', __dir__)) do
|
|
refresh_migrations
|
|
regenerate_schema
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
attr_reader :options
|
|
|
|
def refresh_migrations
|
|
migrations = untracked_schema_migrations + committed_schema_migrations
|
|
migrations = migrations.sort_by { |file| file.slice(/\d{14}/) }
|
|
migrations.each do |file|
|
|
new_file = file.gsub(/\d{14}/, next_migration_number)
|
|
puts "\e[32m$ mv #{file} #{new_file}\e[37m"
|
|
|
|
FileUtils.mv(file, new_file)
|
|
end
|
|
end
|
|
|
|
def regenerate_schema
|
|
run('./scripts/regenerate-schema')
|
|
end
|
|
|
|
def next_migration_number
|
|
@next_migration_number ||= seed_migration_number.to_i
|
|
@next_migration_number += rand(2..5)
|
|
@next_migration_number.to_s
|
|
end
|
|
|
|
def seed_migration_number
|
|
Chronic
|
|
.parse(options.fetch(:after, 'now'))
|
|
.utc.strftime("%Y%m%d%H%M%S")
|
|
end
|
|
|
|
def untracked_schema_migrations
|
|
git_command = "git ls-files --others --exclude-standard -- #{MIGRATION_DIRS}"
|
|
run(git_command).chomp.split("\n")
|
|
end
|
|
|
|
def committed_schema_migrations
|
|
git_command = "git diff --name-only --diff-filter=A #{merge_base} -- #{MIGRATION_DIRS}"
|
|
run(git_command).chomp.split("\n")
|
|
end
|
|
|
|
##
|
|
# Run the given +cmd+.
|
|
#
|
|
# The command is colored green, and the output of the command is
|
|
# colored gray.
|
|
# When the command failed an exception is raised.
|
|
def run(cmd)
|
|
puts "\e[32m$ #{cmd}\e[37m"
|
|
stdout_str, stderr_str, status = Open3.capture3(cmd)
|
|
puts "#{stdout_str}#{stderr_str}\e[0m"
|
|
raise("Command failed: #{stderr_str}") unless status.success?
|
|
|
|
stdout_str
|
|
end
|
|
|
|
##
|
|
# Return the base commit between source and target branch.
|
|
def merge_base
|
|
@merge_base ||= run("git merge-base #{target_branch} #{source_ref}").chomp
|
|
end
|
|
|
|
##
|
|
# Return the name of the target branch
|
|
#
|
|
# Get source ref from CI environment variable, or read the +TARGET+
|
|
# environment+ variable, or default to +HEAD+.
|
|
def target_branch
|
|
ENV['CI_MERGE_REQUEST_TARGET_BRANCH_NAME'] || ENV['TARGET'] || ENV['CI_DEFAULT_BRANCH'] || 'master'
|
|
end
|
|
|
|
##
|
|
# Return the source ref
|
|
#
|
|
# Get source ref from CI environment variable, or default to +HEAD+.
|
|
def source_ref
|
|
ENV['CI_COMMIT_SHA'] || 'HEAD'
|
|
end
|
|
end
|
|
|
|
if $PROGRAM_NAME == __FILE__
|
|
options = {}
|
|
|
|
OptionParser.new do |opts|
|
|
opts.on("-a", "--after VALUE", String, "Start value for the timestamp") do |value|
|
|
options[:after] = value
|
|
end
|
|
|
|
opts.on("-h", "--help", "Prints this help") do
|
|
puts opts
|
|
exit
|
|
end
|
|
end.parse!
|
|
|
|
MigrationsTimestampRefresher.new(options).execute
|
|
end
|