Mini Shell
"""The ``celery upgrade`` command, used to upgrade from previous versions."""
import codecs
import sys
import click
from celery.app import defaults
from celery.bin.base import CeleryCommand, CeleryOption, handle_preload_options
from celery.utils.functional import pass1
@click.group()
@click.pass_context
@handle_preload_options
def upgrade(ctx):
"""Perform upgrade between versions."""
def _slurp(filename):
# TODO: Handle case when file does not exist
with codecs.open(filename, 'r', 'utf-8') as read_fh:
return [line for line in read_fh]
def _compat_key(key, namespace='CELERY'):
key = key.upper()
if not key.startswith(namespace):
key = '_'.join([namespace, key])
return key
def _backup(filename, suffix='.orig'):
lines = []
backup_filename = ''.join([filename, suffix])
print(f'writing backup to {backup_filename}...',
file=sys.stderr)
with codecs.open(filename, 'r', 'utf-8') as read_fh:
with codecs.open(backup_filename, 'w', 'utf-8') as backup_fh:
for line in read_fh:
backup_fh.write(line)
lines.append(line)
return lines
def _to_new_key(line, keyfilter=pass1, source=defaults._TO_NEW_KEY):
# sort by length to avoid, for example, broker_transport overriding
# broker_transport_options.
for old_key in reversed(sorted(source, key=lambda x: len(x))):
new_line = line.replace(old_key, keyfilter(source[old_key]))
if line != new_line and 'CELERY_CELERY' not in new_line:
return 1, new_line # only one match per line.
return 0, line
@upgrade.command(cls=CeleryCommand)
@click.argument('filename')
@click.option('--django',
cls=CeleryOption,
is_flag=True,
help_group='Upgrading Options',
help='Upgrade Django project.')
@click.option('--compat',
cls=CeleryOption,
is_flag=True,
help_group='Upgrading Options',
help='Maintain backwards compatibility.')
@click.option('--no-backup',
cls=CeleryOption,
is_flag=True,
help_group='Upgrading Options',
help="Don't backup original files.")
def settings(filename, django, compat, no_backup):
"""Migrate settings from Celery 3.x to Celery 4.x."""
lines = _slurp(filename)
keyfilter = _compat_key if django or compat else pass1
print(f'processing {filename}...', file=sys.stderr)
# gives list of tuples: ``(did_change, line_contents)``
new_lines = [
_to_new_key(line, keyfilter) for line in lines
]
if any(n[0] for n in new_lines): # did have changes
if not no_backup:
_backup(filename)
with codecs.open(filename, 'w', 'utf-8') as write_fh:
for _, line in new_lines:
write_fh.write(line)
print('Changes to your setting have been made!',
file=sys.stdout)
else:
print('Does not seem to require any changes :-)',
file=sys.stdout)
Zerion Mini Shell 1.0