# HG changeset patch # User Julien Jehannet # Date 1280409511 -7200 # Node ID f8c7aa251782b4957234ceed1db7d077c7a59003 # Parent 5e8076eb8ec76f9b1ee132db0fe87e953d85e4ae [migration] unify process_script command - simplify wrapper by putting the logic in the migration module - enable sql script in shell invocation - adjust cmd_process_script docstring in interactive shell diff -r 5e8076eb8ec7 -r f8c7aa251782 migration.py --- a/migration.py Tue Jul 27 19:40:57 2010 +0200 +++ b/migration.py Thu Jul 29 15:18:31 2010 +0200 @@ -24,13 +24,15 @@ import logging import tempfile from os.path import exists, join, basename, splitext +from itertools import chain +from logilab.common import IGNORED_EXTENSIONS from logilab.common.decorators import cached from logilab.common.configuration import REQUIRED, read_old_config from logilab.common.shellutils import ASK from logilab.common.changelog import Version -from cubicweb import ConfigurationError +from cubicweb import ConfigurationError, ExecutionError def filter_scripts(config, directory, fromversion, toversion, quiet=True): @@ -51,8 +53,7 @@ return [] result = [] for fname in os.listdir(directory): - if fname.endswith('.pyc') or fname.endswith('.pyo') \ - or fname.endswith('~'): + if fname.endswith(IGNORED_EXTENSIONS): continue fpath = join(directory, fname) try: @@ -75,9 +76,6 @@ return sorted(result) -IGNORED_EXTENSIONS = ('.swp', '~') - - def execscript_confirm(scriptpath): """asks for confirmation before executing a script and provides the ability to show the script's content @@ -285,6 +283,16 @@ Display the migration script path, ask for confirmation and execute it if confirmed + Allowed input file formats for migration scripts: + - `python` (.py) + - `sql` (.sql) + - `doctest` (.txt or .rst) + + .. warning:: sql migration scripts are not available in web-only instance + + You can pass script parameters with using double dash (--) in the + command line + Context environment can have these variables defined: - __name__ : will be determine by funcname parameter - __file__ : is the name of the script if it exists @@ -295,13 +303,20 @@ :params args: optional arguments for funcname :keyword scriptargs: optional arguments of the script """ + ftypes = {'python': ('.py',), + 'doctest': ('.txt', '.rst'), + 'sql': ('.sql',)} + # sql migration scripts are not available in web-only instance + if not hasattr(self, "session"): + ftypes.pop('sql') migrscript = os.path.normpath(migrscript) - if migrscript.endswith('.py'): - script_mode = 'python' - elif migrscript.endswith(('.txt', '.rst')): - script_mode = 'doctest' + for (script_mode, ftype) in ftypes.items(): + if migrscript.endswith(ftype): + break else: - raise Exception('This is not a valid cubicweb shell input') + ftypes = ', '.join(chain(*ftypes.values())) + msg = 'ignoring %s, not a valid script extension (%s)' + raise ExecutionError(msg % (migrscript, ftypes)) if not self.execscript_confirm(migrscript): return scriptlocals = self._create_context().copy() @@ -322,6 +337,9 @@ self.critical('no %s in script %s', funcname, migrscript) return None return func(*args, **kwargs) + elif script_mode == 'sql': + from cubicweb.server.sqlutils import sqlexec + sqlexec(open(migrscript).read(), self.session.system_sql) else: # script_mode == 'doctest' import doctest doctest.testfile(migrscript, module_relative=False, diff -r 5e8076eb8ec7 -r f8c7aa251782 server/migractions.py --- a/server/migractions.py Tue Jul 27 19:40:57 2010 +0200 +++ b/server/migractions.py Thu Jul 29 15:18:31 2010 +0200 @@ -49,7 +49,7 @@ from yams.constraints import SizeConstraint from yams.schema2sql import eschema2sql, rschema2sql -from cubicweb import AuthenticationError +from cubicweb import AuthenticationError, ExecutionError from cubicweb.schema import (ETYPE_NAME_MAP, META_RTYPES, VIRTUAL_RTYPES, PURE_VIRTUAL_RTYPES, CubicWebRelationSchema, order_eschemas) @@ -117,27 +117,19 @@ super(ServerMigrationHelper, self).migrate(vcconf, toupgrade, options) def cmd_process_script(self, migrscript, funcname=None, *args, **kwargs): - """execute a migration script - in interactive mode, display the migration script path, ask for - confirmation and execute it if confirmed - """ try: - if migrscript.endswith('.sql'): - if self.execscript_confirm(migrscript): - sqlexec(open(migrscript).read(), self.session.system_sql) - elif migrscript.endswith('.py') or migrscript.endswith('.txt'): - return super(ServerMigrationHelper, self).cmd_process_script( - migrscript, funcname, *args, **kwargs) - else: - print >> sys.stderr - print >> sys.stderr, ('-> ignoring %s, only .py .sql and .txt scripts are considered' % - migrscript) - print >> sys.stderr + super(ServerMigrationHelper, self).cmd_process_script( + migrscript, funcname, *args, **kwargs) self.commit() + except ExecutionError, err: + print >> sys.stderr, "-> %s" % err except: self.rollback() raise + # Adjust docstring + cmd_process_script.__doc__ = MigrationHelper.cmd_process_script.__doc__ + # server specific migration methods ######################################## def backup_database(self, backupfile=None, askconfirm=True):