8892801205
- Add PEP8 section to tox.ini - Add hacking to requirements to enforce OpenStack style requirements - Fix large number of formatting issues flagged by flake8 check - Add copyright notices to all remaining files - Fix bug in trigger_manager related to logging calls - Add .gitignore file Change-Id: I755ab9c8bcc436836f9006fcd671408cc77214c4
159 lines
6.2 KiB
Python
159 lines
6.2 KiB
Python
# Copyright (c) 2014 Dark Secret Software Inc.
|
|
# Copyright (c) 2015 Rackspace
|
|
#
|
|
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
# you may not use this file except in compliance with the License.
|
|
# You may obtain a copy of the License at
|
|
#
|
|
# http://www.apache.org/licenses/LICENSE-2.0
|
|
#
|
|
# Unless required by applicable law or agreed to in writing, software
|
|
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
|
# implied.
|
|
# See the License for the specific language governing permissions and
|
|
# limitations under the License.
|
|
|
|
from alembic import command
|
|
from alembic import config
|
|
from alembic import util
|
|
import argparse
|
|
import inspect
|
|
|
|
|
|
class AlembicCommandLine(object):
|
|
prog = None
|
|
description = None
|
|
allowed_commands = None
|
|
|
|
def __init__(self, prog=None, description=None, allowed_commands=None):
|
|
if prog is not None:
|
|
self.prog = prog
|
|
if description is not None:
|
|
self.description = description
|
|
if allowed_commands is not None:
|
|
self.allowed_commands = allowed_commands
|
|
|
|
self.parser = self.generate_options()
|
|
|
|
def add_command_options(self, parser, positional, kwargs):
|
|
if 'template' in kwargs:
|
|
parser.add_argument("-t", "--template",
|
|
default='generic',
|
|
type=str,
|
|
help="Setup template for use with 'init'")
|
|
if 'message' in kwargs:
|
|
parser.add_argument("-m", "--message",
|
|
type=str,
|
|
help="Message string to use with 'revision'")
|
|
if 'sql' in kwargs:
|
|
parser.add_argument("--sql",
|
|
action="store_true",
|
|
help="Don't emit SQL to database - dump to "
|
|
"standard output/file instead")
|
|
if 'tag' in kwargs:
|
|
parser.add_argument("--tag",
|
|
type=str,
|
|
help="Arbitrary 'tag' name - can be used by "
|
|
"custom env.py scripts.")
|
|
if 'autogenerate' in kwargs:
|
|
parser.add_argument("--autogenerate",
|
|
action="store_true",
|
|
help="Populate revision script with "
|
|
"candidate migration operations, based "
|
|
"on comparison of database to model.")
|
|
# "current" command
|
|
if 'head_only' in kwargs:
|
|
parser.add_argument("--head-only",
|
|
action="store_true",
|
|
help="Only show current version and "
|
|
"whether or not this is the head revision.")
|
|
|
|
if 'rev_range' in kwargs:
|
|
parser.add_argument("-r", "--rev-range",
|
|
action="store",
|
|
help="Specify a revision range; "
|
|
"format is [start]:[end]")
|
|
|
|
positional_help = {
|
|
'directory': "location of scripts directory",
|
|
'revision': "revision identifier"
|
|
}
|
|
for arg in positional:
|
|
parser.add_argument(arg, help=positional_help.get(arg))
|
|
|
|
def add_options(self, parser):
|
|
parser.add_argument("-c", "--config",
|
|
type=str,
|
|
default="alembic.ini",
|
|
help="Alternate config file")
|
|
parser.add_argument("-n", "--name",
|
|
type=str,
|
|
default="alembic",
|
|
help="Name of section in .ini file to "
|
|
"use for Alembic config")
|
|
parser.add_argument("-x", action="append",
|
|
help="Additional arguments consumed by "
|
|
"custom env.py scripts, e.g. -x "
|
|
"setting1=somesetting -x setting2=somesetting")
|
|
|
|
def generate_options(self):
|
|
parser = argparse.ArgumentParser(prog=self.prog)
|
|
self.add_options(parser)
|
|
subparsers = parser.add_subparsers()
|
|
|
|
for fn, name, doc, positional, kwarg in self.get_commands():
|
|
subparser = subparsers.add_parser(name, help=doc)
|
|
self.add_command_options(subparser, positional, kwarg)
|
|
subparser.set_defaults(cmd=(fn, positional, kwarg))
|
|
return parser
|
|
|
|
def get_commands(self):
|
|
cmds = []
|
|
for fn in [getattr(command, n) for n in dir(command)]:
|
|
if (inspect.isfunction(fn) and
|
|
fn.__name__[0] != '_' and
|
|
fn.__module__ == 'alembic.command'):
|
|
|
|
if (self.allowed_commands and
|
|
fn.__name__ not in self.allowed_commands):
|
|
continue
|
|
|
|
spec = inspect.getargspec(fn)
|
|
if spec[3]:
|
|
positional = spec[0][1:-len(spec[3])]
|
|
kwarg = spec[0][-len(spec[3]):]
|
|
else:
|
|
positional = spec[0][1:]
|
|
kwarg = []
|
|
cmds.append((fn, fn.__name__, fn.__doc__, positional, kwarg))
|
|
return cmds
|
|
|
|
def get_config(self, options):
|
|
return config.Config(file_=options.config,
|
|
ini_section=options.name,
|
|
cmd_opts=options)
|
|
|
|
def run_cmd(self, config, options):
|
|
fn, positional, kwarg = options.cmd
|
|
|
|
try:
|
|
fn(config, *[getattr(options, k) for k in positional],
|
|
**dict((k, getattr(options, k)) for k in kwarg))
|
|
except util.CommandError as e:
|
|
util.err(str(e))
|
|
|
|
def main(self, argv=None):
|
|
options = self.parser.parse_args(argv)
|
|
if not hasattr(options, "cmd"):
|
|
# see http://bugs.python.org/issue9253, argparse
|
|
# behavior changed incompatibly in py3.3
|
|
self.parser.error("too few arguments")
|
|
else:
|
|
self.run_cmd(self.get_config(options), options)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
cmdline = AlembicCommandLine()
|
|
cmdline.main()
|