Created
July 29, 2014 00:14
-
-
Save nvbn/3be2dc0ad8ec7780177c to your computer and use it in GitHub Desktop.
order south migration
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
from argparse import ArgumentParser | |
from contextlib import contextmanager | |
from subprocess import Popen, PIPE | |
import sys | |
import os | |
import re | |
def git(*args): | |
resp = Popen(['git'] + list(args), stdout=PIPE, stderr=PIPE) | |
return resp.stdout.readline()[:-1] | |
@contextmanager | |
def branch(dest, current): | |
try: | |
yield git('checkout', dest) | |
finally: | |
git('checkout', current) | |
def get_opts(): | |
parser = ArgumentParser() | |
parser.add_argument( | |
'--to-branch', type=unicode, default='master') | |
parser.add_argument( | |
'--path', type=unicode, required=True) | |
return parser.parse_args(sys.argv[1:]) | |
def get_migrations(path): | |
return [x for x in os.listdir(path) | |
if not x.endswith('.pyc') | |
and not x == '__init__.py'] | |
def to_pairs(migrations): | |
pairs = [ | |
(int(re.match(r'^(\d+).*', m).group(1)), m) | |
for m in migrations] | |
return sorted(pairs, key=lambda m: m[0]) | |
def last_number(migrations): | |
return to_pairs(migrations)[-1][0] | |
def replace_number(migration, number): | |
rest = re.match(r'^\d+(.*)', migration).group(1) | |
return '{0:04d}{rest}'.format(number, rest=rest) | |
def get_replacements(number, new_migrations): | |
return [ | |
(name, replace_number(name, n)) | |
for n, (_, name) in enumerate(to_pairs(new_migrations), | |
start=number)] | |
def is_replacements_confirmed(replacements): | |
print 'Are you sure want to rename migrations:' | |
for orig, new in replacements: | |
print '{} -> {}'.format(orig, new) | |
return raw_input('Y/N: ') in ('y', 'Y') | |
def perform_replacements(replacements, path): | |
for orig, new in replacements: | |
new_path = os.path.join(path, new) | |
os.rename(os.path.join(path, orig), | |
new_path) | |
git('add', new_path) | |
def main(): | |
opts = get_opts() | |
current_branch = git('rev-parse', '--abbrev-ref', 'HEAD') | |
current_migrations = get_migrations(opts.path) | |
with branch(opts.to_branch, current_branch): | |
dest_migrations = get_migrations(opts.path) | |
new_migrations = set(current_migrations).difference(dest_migrations) | |
number = last_number(dest_migrations) + 1 | |
replacements = get_replacements(number, new_migrations) | |
if is_replacements_confirmed(replacements): | |
perform_replacements(replacements, opts.path) | |
print 'All migrations renamed!' | |
else: | |
print 'Abort.' | |
if __name__ == '__main__': | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment