[ADD] module install/uninstall hooks.
Since 4ec71c74d1
, migration scripts
are not executed at module install anymore.
As this behavior was missused as "init" scripts (see [1]), this
commit re-add this possiblity via hooks.
There are 3 hooks that can be declared in the manifest file:
- pre_init_hook: called before module installation
- post_init_hook: called after module installation
- uninstall_hook: called before module uninstallation
Like the "post_load" manifest option, the values for these hooks
must be a string containing the name of a method available at the
module root.
The signatures of these functions are:
- (cr) for pre_init_hook
- (cr, registry) for post_init_hook and uninstall_hook
[1] https://bugs.launchpad.net/openobject-server/+bug/1314680
This commit is contained in:
parent
bd51bf1e35
commit
4105b5f028
|
@ -3,7 +3,7 @@
|
|||
#
|
||||
# OpenERP, Open Source Management Solution
|
||||
# Copyright (C) 2004-2009 Tiny SPRL (<http://tiny.be>).
|
||||
# Copyright (C) 2010-2011 OpenERP s.a. (<http://openerp.com>).
|
||||
# Copyright (C) 2010-2014 OpenERP s.a. (<http://openerp.com>).
|
||||
#
|
||||
# This program is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Affero General Public License as
|
||||
|
@ -149,7 +149,14 @@ class Graph(dict):
|
|||
level += 1
|
||||
|
||||
|
||||
class Singleton(object):
|
||||
class Node(object):
|
||||
""" One module in the modules dependency graph.
|
||||
|
||||
Node acts as a per-module singleton. A node is constructed via
|
||||
Graph.add_module() or Graph.add_modules(). Some of its fields are from
|
||||
ir_module_module (setted by Graph.update_from_db()).
|
||||
|
||||
"""
|
||||
def __new__(cls, name, graph, info):
|
||||
if name in graph:
|
||||
inst = graph[name]
|
||||
|
@ -160,22 +167,13 @@ class Singleton(object):
|
|||
graph[name] = inst
|
||||
return inst
|
||||
|
||||
|
||||
class Node(Singleton):
|
||||
""" One module in the modules dependency graph.
|
||||
|
||||
Node acts as a per-module singleton. A node is constructed via
|
||||
Graph.add_module() or Graph.add_modules(). Some of its fields are from
|
||||
ir_module_module (setted by Graph.update_from_db()).
|
||||
|
||||
"""
|
||||
|
||||
def __init__(self, name, graph, info):
|
||||
self.graph = graph
|
||||
if not hasattr(self, 'children'):
|
||||
self.children = []
|
||||
if not hasattr(self, 'depth'):
|
||||
self.depth = 0
|
||||
self.info = info or {}
|
||||
|
||||
def add_child(self, name, info):
|
||||
node = Node(name, self.graph, info)
|
||||
|
@ -189,7 +187,7 @@ class Node(Singleton):
|
|||
return node
|
||||
|
||||
def __setattr__(self, name, value):
|
||||
super(Singleton, self).__setattr__(name, value)
|
||||
super(Node, self).__setattr__(name, value)
|
||||
if name in ('init', 'update', 'demo'):
|
||||
tools.config[name][self.name] = 1
|
||||
for child in self.children:
|
||||
|
|
|
@ -148,6 +148,13 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
|
|||
migrations.migrate_module(package, 'pre')
|
||||
load_openerp_module(package.name)
|
||||
|
||||
new_install = package.installed_version is None
|
||||
if new_install:
|
||||
py_module = sys.modules['openerp.addons.%s' % (module_name,)]
|
||||
pre_init = package.info.get('pre_init_hook')
|
||||
if pre_init:
|
||||
getattr(py_module, pre_init)(cr)
|
||||
|
||||
models = registry.load(cr, package)
|
||||
|
||||
loaded_modules.append(package.name)
|
||||
|
@ -181,6 +188,11 @@ def load_module_graph(cr, graph, status=None, perform_checks=True, skip_modules=
|
|||
|
||||
migrations.migrate_module(package, 'post')
|
||||
|
||||
if new_install:
|
||||
post_init = package.info.get('post_init_hook')
|
||||
if post_init:
|
||||
getattr(py_module, post_init)(cr, registry)
|
||||
|
||||
registry._init_modules.add(package.name)
|
||||
# validate all the views at a whole
|
||||
registry['ir.ui.view']._validate_module_views(cr, SUPERUSER_ID, module_name)
|
||||
|
@ -401,10 +413,17 @@ def load_modules(db, force_demo=False, status=None, update_module=False):
|
|||
if update_module:
|
||||
# Remove records referenced from ir_model_data for modules to be
|
||||
# removed (and removed the references from ir_model_data).
|
||||
cr.execute("SELECT id FROM ir_module_module WHERE state=%s", ('to remove',))
|
||||
mod_ids_to_remove = [x[0] for x in cr.fetchall()]
|
||||
if mod_ids_to_remove:
|
||||
registry['ir.module.module'].module_uninstall(cr, SUPERUSER_ID, mod_ids_to_remove)
|
||||
cr.execute("SELECT name, id FROM ir_module_module WHERE state=%s", ('to remove',))
|
||||
modules_to_remove = dict(cr.fetchall())
|
||||
if modules_to_remove:
|
||||
pkgs = reversed([p for p in graph if p.name in modules_to_remove])
|
||||
for pkg in pkgs:
|
||||
uninstall_hook = pkg.info.get('uninstall_hook')
|
||||
if uninstall_hook:
|
||||
py_module = sys.modules['openerp.addons.%s' % (pkg.name,)]
|
||||
getattr(py_module, uninstall_hook)(cr, registry)
|
||||
|
||||
registry['ir.module.module'].module_uninstall(cr, SUPERUSER_ID, modules_to_remove.values())
|
||||
# Recursive reload, should only happen once, because there should be no
|
||||
# modules to remove next time
|
||||
cr.commit()
|
||||
|
|
Loading…
Reference in New Issue