Skip to content

Instantly share code, notes, and snippets.

@nvbn
Created July 29, 2014 00:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save nvbn/3be2dc0ad8ec7780177c to your computer and use it in GitHub Desktop.
Save nvbn/3be2dc0ad8ec7780177c to your computer and use it in GitHub Desktop.
order south migration
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