django-orchestra/orchestra/management/commands/upgradeorchestra.py

106 lines
4.3 KiB
Python

import functools
import os
import random
import string
from distutils.sysconfig import get_python_lib
from django.core.management import call_command
from django.core.management.base import BaseCommand, CommandError
from orchestra import get_version
from orchestra.utils.sys import run, check_root
r = functools.partial(run, silent=False)
def get_existing_pip_installation():
""" returns current pip installation path """
if run("pip freeze|grep django-orchestra", valid_codes=(0,1)).exit_code == 0:
for lib_path in get_python_lib(), get_python_lib(prefix="/usr/local"):
existing_path = os.path.abspath(os.path.join(lib_path, "orchestra"))
if os.path.exists(existing_path):
return existing_path
return None
class Command(BaseCommand):
help = "Upgrading Orchestra's installation. Desired version is accepted as argument"
can_import_settings = False
leave_locale_alone = True
def __init__(self, *args, **kwargs):
super(Command, self).__init__(*args, **kwargs)
def add_arguments(self, parser):
parser.add_argument(
'--pip_only',
action='store_true',
dest='pip_only',
default=False,
help='Only run "pip install django-orchestra --upgrade"'
)
parser.add_argument(
'--orchestra_version',
dest='version',
default=False,
help='Specifies what version of the Orchestra you want to install'
)
@check_root
def handle(self, *args, **options):
current_version = get_version()
current_path = get_existing_pip_installation()
if current_path is not None:
desired_version = options.get('version')
if args:
desired_version = args[0]
if current_version == desired_version:
msg = "Not upgrading, you already have version %s installed"
raise CommandError(msg % desired_version)
# Create a backup of current installation
base_path = os.path.abspath(os.path.join(current_path, '..'))
char_set = string.ascii_uppercase + string.digits
rand_name = ''.join(random.sample(char_set, 6))
backup = os.path.join(base_path, 'orchestra.' + rand_name)
run("mv %s %s" % (current_path, backup))
# collect existing eggs previous to the installation
eggs_regex = os.path.join(base_path, 'django_orchestra-*.egg-info')
eggs = run('ls -d %s' % eggs_regex)
eggs = eggs.stdout.splitlines()
try:
if desired_version:
r('pip install django-orchestra==%s' % desired_version)
else:
# Did I mentioned how I hate PIP?
if run('pip --version|cut -d" " -f2').stdout == '1.0':
r('pip install django-orchestra --upgrade')
else:
# (Fucking pip)^2, it returns exit code 0 even when fails
# because requirement already up-to-date
r('pip install django-orchestra --upgrade --force')
except CommandError:
# Restore backup
run('rm -rf %s' % current_path)
run('mv %s %s' % (backup, current_path))
raise CommandError("Problem runing pip upgrade, aborting...")
else:
# Some old versions of pip do not performe this cleaning ...
# Remove all backups
run('rm -fr %s' % os.path.join(base_path, 'orchestra\.*'))
# Clean old egg files, yeah, cleaning PIP shit :P
c_version = 'from orchestra import get_version; print get_version()'
version = run('python -c "%s;"' % c_version).stdout
for egg in eggs:
# Do not remove the actual egg file when upgrading twice the same version
if egg.split('/')[-1] != "django_orchestra-%s.egg-info" % version:
run('rm -fr %s' % egg)
else:
raise CommandError("You don't seem to have any previous PIP installation")
# version specific upgrade operations
if not options.get('pip_only'):
call_command("postupgradeorchestra", version=current_version)