From 6e1e045fd53218b16ef09d98f107e1b61eeca716 Mon Sep 17 00:00:00 2001 From: Raghav Jajodia Date: Thu, 30 Mar 2017 23:32:21 +0530 Subject: [PATCH] tooling: Add script to automatically renumber migrations. Previously, if you have a branch with a new migration, and you rebase onto master past someone else's migration, you have to manually renumber your migration. Add a script that automatically renumbers the migrations. Fix #4257. --- tools/renumber-migrations | 80 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) create mode 100644 tools/renumber-migrations diff --git a/tools/renumber-migrations b/tools/renumber-migrations new file mode 100644 index 0000000000..9e5d53bdcc --- /dev/null +++ b/tools/renumber-migrations @@ -0,0 +1,80 @@ +#!/usr/bin/env python + +from __future__ import absolute_import +from __future__ import print_function +from six.moves import input, map, range +import glob +import os +import sys +import fileinput +import re + +from typing import List + +def validate_order(order, length): + # type: (List[int], int) -> None + if len(order) != length: + print("Please enter the sequence of all the conflicting files at once") + sys.exit(1) + + for i in order: + if i > length or i < 1 or order.count(i) > 1: + print("Incorrect input") + sys.exit(1) + +def renumber_migration(conflicts, order, last_correct_migration): + # type: (List[str], List[int], str) -> None + stack = [] # type: List[str] + for i in order: + if conflicts[i-1][0:4] not in stack: + stack.append(conflicts[i-1][0:4]) + else: + # Replace dependencies with the last correct migration + file = fileinput.FileInput('zerver/migrations/' + conflicts[i-1], inplace=True) + for line in file: + print(re.sub(r'[\d]+(_[a-z0-9]+)+', last_correct_migration, line), end='') + + # Rename the migration indexing at the end + new_name = conflicts[i-1].replace(conflicts[i-1][0:4], '00' + str(int(last_correct_migration[0:4]) + 1)) + os.rename('zerver/migrations/' + conflicts[i-1], 'zerver/migrations/' + new_name) + + last_correct_migration = new_name + +def resolve_conflicts(conflicts, files_list): + # type: (List[str], List[str]) -> None + print("Conflicting migrations:") + for i in range(0, len(conflicts)): + print(str(i+1) + '. ' + conflicts[i]) + + order_input = input("Enter the order in which these migrations should be arranged: ") + order = list(map(int, order_input.split())) + validate_order(order, len(conflicts)) + + last_correct_migration = str(input('Enter the name of last correct migration file: ')) + if last_correct_migration not in files_list: + print("File not found!") + sys.exit(1) + + last_correct_migration = last_correct_migration.replace('.py', '') + renumber_migration(conflicts, order, last_correct_migration) + +if __name__ == '__main__': + + while True: + conflicts = [] # type: list[str] + stack = [] # type: list[str] + files_list = [os.path.basename(path) for path in glob.glob("zerver/migrations/????_*.py")] + file_index = [file[0:4] for file in files_list] + + for file in file_index: + counter = file_index.count(file[0:4]) + if counter > 1 and file[0:4] not in stack: + conflicts += [file_name for file_name in files_list if file[0:4] in file_name] + stack.append(file[0:4]) + + if len(conflicts) > 0: + resolve_conflicts(conflicts, files_list) + else: + break + + print("All conflicts resolved")