common/migration.py
branchtls-sprint
changeset 1802 d628defebc17
parent 676 270eb87a768a
child 1977 606923dff11b
equal deleted inserted replaced
1801:672acc730ce5 1802:d628defebc17
     1 """utility to ease migration of application version to newly installed
     1 """utility to ease migration of application version to newly installed
     2 version
     2 version
     3 
     3 
     4 :organization: Logilab
     4 :organization: Logilab
     5 :copyright: 2001-2008 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     5 :copyright: 2001-2009 LOGILAB S.A. (Paris, FRANCE), all rights reserved.
     6 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     6 :contact: http://www.logilab.fr/ -- mailto:contact@logilab.fr
     7 """
     7 """
     8 __docformat__ = "restructuredtext en"
     8 __docformat__ = "restructuredtext en"
     9 
     9 
    10 import sys
    10 import sys
   123                           'interactive_mode': interactive,
   123                           'interactive_mode': interactive,
   124                           }
   124                           }
   125 
   125 
   126     def repo_connect(self):
   126     def repo_connect(self):
   127         return self.config.repository()
   127         return self.config.repository()
   128         
   128 
   129     def migrate(self, vcconf, toupgrade, options):
   129     def migrate(self, vcconf, toupgrade, options):
   130         """upgrade the given set of cubes
   130         """upgrade the given set of cubes
   131         
   131 
   132         `cubes` is an ordered list of 3-uple:
   132         `cubes` is an ordered list of 3-uple:
   133         (cube, fromversion, toversion)
   133         (cube, fromversion, toversion)
   134         """
   134         """
   135         if options.fs_only:
   135         if options.fs_only:
   136             # monkey path configuration.accept_mode so database mode (e.g. Any)
   136             # monkey path configuration.accept_mode so database mode (e.g. Any)
   147             self.__context.update({'applcubicwebversion': vcconf['cubicweb'],
   147             self.__context.update({'applcubicwebversion': vcconf['cubicweb'],
   148                                    'cubicwebversion': self.config.cubicweb_version(),
   148                                    'cubicwebversion': self.config.cubicweb_version(),
   149                                    'versions_map': vmap})
   149                                    'versions_map': vmap})
   150             self.scripts_session(scripts)
   150             self.scripts_session(scripts)
   151         else:
   151         else:
   152             print 'no migration script to execute'            
   152             print 'no migration script to execute'
   153 
   153 
   154     def shutdown(self):
   154     def shutdown(self):
   155         pass
   155         pass
   156     
   156 
   157     def __getattribute__(self, name):
   157     def __getattribute__(self, name):
   158         try:
   158         try:
   159             return object.__getattribute__(self, name)
   159             return object.__getattribute__(self, name)
   160         except AttributeError:
   160         except AttributeError:
   161             cmd = 'cmd_%s' % name
   161             cmd = 'cmd_%s' % name
   162             if hasattr(self, cmd):
   162             if hasattr(self, cmd):
   163                 meth = getattr(self, cmd) 
   163                 meth = getattr(self, cmd)
   164                 return lambda *args, **kwargs: self.interact(args, kwargs,
   164                 return lambda *args, **kwargs: self.interact(args, kwargs,
   165                                                              meth=meth)
   165                                                              meth=meth)
   166             raise
   166             raise
   167         raise AttributeError(name)
   167         raise AttributeError(name)
   168             
   168 
   169     def interact(self, args, kwargs, meth):
   169     def interact(self, args, kwargs, meth):
   170         """execute the given method according to user's confirmation"""
   170         """execute the given method according to user's confirmation"""
   171         msg = 'execute command: %s(%s) ?' % (
   171         msg = 'execute command: %s(%s) ?' % (
   172             meth.__name__[4:],
   172             meth.__name__[4:],
   173             ', '.join([repr(arg) for arg in args] +
   173             ', '.join([repr(arg) for arg in args] +
   222             import readline
   222             import readline
   223             from rlcompleter import Completer
   223             from rlcompleter import Completer
   224         except ImportError:
   224         except ImportError:
   225             # readline not available
   225             # readline not available
   226             pass
   226             pass
   227         else:        
   227         else:
   228             readline.set_completer(Completer(local_ctx).complete)
   228             readline.set_completer(Completer(local_ctx).complete)
   229             readline.parse_and_bind('tab: complete')
   229             readline.parse_and_bind('tab: complete')
   230             histfile = os.path.join(os.environ["HOME"], ".eshellhist")
   230             histfile = os.path.join(os.environ["HOME"], ".eshellhist")
   231             try:
   231             try:
   232                 readline.read_history_file(histfile)
   232                 readline.read_history_file(histfile)
   254                 if self.need_wrap:
   254                 if self.need_wrap:
   255                     context[attr[4:]] = getattr(self, attr[4:])
   255                     context[attr[4:]] = getattr(self, attr[4:])
   256                 else:
   256                 else:
   257                     context[attr[4:]] = getattr(self, attr)
   257                     context[attr[4:]] = getattr(self, attr)
   258         return context
   258         return context
   259     
   259 
   260     def process_script(self, migrscript, funcname=None, *args, **kwargs):
   260     def process_script(self, migrscript, funcname=None, *args, **kwargs):
   261         """execute a migration script
   261         """execute a migration script
   262         in interactive mode,  display the migration script path, ask for
   262         in interactive mode,  display the migration script path, ask for
   263         confirmation and execute it if confirmed
   263         confirmation and execute it if confirmed
   264         """
   264         """
   278                     assert callable(func), '%s (%s) is not callable' % (func, funcname)
   278                     assert callable(func), '%s (%s) is not callable' % (func, funcname)
   279                 except KeyError:
   279                 except KeyError:
   280                     self.critical('no %s in script %s', funcname, migrscript)
   280                     self.critical('no %s in script %s', funcname, migrscript)
   281                     return None
   281                     return None
   282                 return func(*args, **kwargs)
   282                 return func(*args, **kwargs)
   283                     
   283 
   284     def scripts_session(self, migrscripts):
   284     def scripts_session(self, migrscripts):
   285         """execute some scripts in a transaction"""
   285         """execute some scripts in a transaction"""
   286         try:
   286         try:
   287             for migrscript in migrscripts:
   287             for migrscript in migrscripts:
   288                 self.process_script(migrscript)
   288                 self.process_script(migrscript)
   309         #self._option_changes.append(('removed', optname))
   309         #self._option_changes.append(('removed', optname))
   310 
   310 
   311     def cmd_option_type_changed(self, optname, oldtype, newvalue):
   311     def cmd_option_type_changed(self, optname, oldtype, newvalue):
   312         """a configuration option's type has changed"""
   312         """a configuration option's type has changed"""
   313         self._option_changes.append(('typechanged', optname, oldtype, newvalue))
   313         self._option_changes.append(('typechanged', optname, oldtype, newvalue))
   314         
   314 
   315     def cmd_add_cubes(self, cubes):
   315     def cmd_add_cubes(self, cubes):
   316         """modify the list of used cubes in the in-memory config
   316         """modify the list of used cubes in the in-memory config
   317         returns newly inserted cubes, including dependencies
   317         returns newly inserted cubes, including dependencies
   318         """
   318         """
   319         if isinstance(cubes, basestring):
   319         if isinstance(cubes, basestring):
   320             cubes = (cubes,)
   320             cubes = (cubes,)
   321         origcubes = self.config.cubes()
   321         origcubes = self.config.cubes()
   322         newcubes = [p for p in self.config.expand_cubes(cubes) 
   322         newcubes = [p for p in self.config.expand_cubes(cubes)
   323                        if not p in origcubes]
   323                        if not p in origcubes]
   324         if newcubes:
   324         if newcubes:
   325             for cube in cubes:
   325             for cube in cubes:
   326                 assert cube in newcubes
   326                 assert cube in newcubes
   327             self.config.add_cubes(newcubes)
   327             self.config.add_cubes(newcubes)
   338         self.config._cubes = tuple(self.config.expand_cubes(basecubes))
   338         self.config._cubes = tuple(self.config.expand_cubes(basecubes))
   339         removed = [p for p in origcubes if not p in self.config._cubes]
   339         removed = [p for p in origcubes if not p in self.config._cubes]
   340         assert cube in removed, \
   340         assert cube in removed, \
   341                "can't remove cube %s, used as a dependancy" % cube
   341                "can't remove cube %s, used as a dependancy" % cube
   342         return removed
   342         return removed
   343     
   343 
   344     def rewrite_configuration(self):
   344     def rewrite_configuration(self):
   345         # import locally, show_diffs unavailable in gae environment
   345         # import locally, show_diffs unavailable in gae environment
   346         from cubicweb.toolsutils import show_diffs
   346         from cubicweb.toolsutils import show_diffs
   347         configfile = self.config.main_config_file()
   347         configfile = self.config.main_config_file()
   348         if self._option_changes:
   348         if self._option_changes: