migration.py
branchstable
changeset 6035 f8c7aa251782
parent 5967 8deedfeb7846
child 6042 df9cafb8062c
--- 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,