summaryrefslogtreecommitdiff
path: root/odoo/addons/base/models/ir_module.py
diff options
context:
space:
mode:
authorXavier Morel <xmo@odoo.com>2018-12-11 13:57:49 +0000
committerXavier Morel <xmo@odoo.com>2019-05-07 11:44:26 +0000
commit2cc7f0dd49a6be1920cef232e6c010fbafa68270 (patch)
treee62d6e2fac0f0bc24ffb3e8a58f90368462fa0c7 /odoo/addons/base/models/ir_module.py
parentb9ec98357159621f8f8152c23025d1120cde2013 (diff)
[IMP] core: allow auto_install restriction on a subset of dependencies
Currently, auto_install is triggered when all dependencies get installed, but there are cases where one would want such trigger on only a subset thereof. e.g. we want `website_sale_dashboard` to auto-install when `website_sale` is installed. Currently, it requires `web_dashboard` to also be auto-installed otherwise `website_sale_dashboard` would "wait" for both dependencies to be explicitly installed before the auto-install triggers. That's despite `web_dashboard` not being very useful on its own. More generally this is an issue with technical modules which need to be marked as auto_install so as not to block e.g. bridge modules from automatically installing. This change allows setting `auto_install` to a subset of `depends`: * if auto_install is set to `False`, the module does not get automatically installed (no change in semantics) * if auto_install is set to `True`, the module gets automatically installed if and only if all its dependencies are installed (also no change in semantics) * if auto_install is set to a list of dependencies, the module will be installed when all *these* dependencies are installed, other dependencies (excluded from auto_install) will be installed alongside as a consequence * auto_install can be set to an empty list, in this case the module will always be automatically installed regardless of its dependencies (and will force their installation). So after this change, `web_dashboard`'s auto_install can be set to `False` (such that it's not installed if no module defining dashboards is installed) and `website_sale_dashboard`'s manifest can be edited to: 'auto_install': ['website_sale'] possibilities: # no automatic installation 'depends': ['a', 'b'], 'auto_install': False # automatic installation if both a and b are installed 'depends': ['a', 'b'], 'auto_install': True # automatic installation if both a and b are installed (explicit) 'depends': ['a', 'b'], 'auto_install': ['a', 'b'] # automatic installation if b is installed, a will get forcefully # installed if it isn't yet 'depends': ['a', 'b'], 'auto_install': ['b'] # always automatically installed, will cause the installation of # its dependencies even if they're not marked explicitly 'depends': ['a', 'b'], 'auto_install': [] Task 1851328 closes odoo/odoo#29431 Signed-off-by: Xavier Morel (xmo) <xmo@odoo.com>
Diffstat (limited to 'odoo/addons/base/models/ir_module.py')
-rw-r--r--odoo/addons/base/models/ir_module.py18
1 files changed, 12 insertions, 6 deletions
diff --git a/odoo/addons/base/models/ir_module.py b/odoo/addons/base/models/ir_module.py
index de11d836010..e2870d74b3c 100644
--- a/odoo/addons/base/models/ir_module.py
+++ b/odoo/addons/base/models/ir_module.py
@@ -382,7 +382,7 @@ class Module(models.Model):
# - at least one dependency is 'to install'
install_states = frozenset(('installed', 'to install', 'to upgrade'))
def must_install(module):
- states = set(dep.state for dep in module.dependencies_id)
+ states = {dep.state for dep in module.dependencies_id if dep.auto_install_required}
return states <= install_states and 'to install' in states
modules = self
@@ -667,7 +667,7 @@ class Module(models.Model):
'license': terp.get('license', 'LGPL-3'),
'sequence': terp.get('sequence', 100),
'application': terp.get('application', False),
- 'auto_install': terp.get('auto_install', False),
+ 'auto_install': terp.get('auto_install', False) is not False,
'icon': terp.get('icon', False),
'summary': terp.get('summary', ''),
'url': terp.get('url') or terp.get('live_test_url', ''),
@@ -707,8 +707,7 @@ class Module(models.Model):
updated_values = {}
for key in values:
old = getattr(mod, key)
- updated = tools.ustr(values[key]) if isinstance(values[key], str) else values[key]
- if (old or updated) and updated != old:
+ if (old or values[key]) and values[key] != old:
updated_values[key] = values[key]
if terp.get('installable', True) and mod.state == 'uninstallable':
updated_values['state'] = 'uninstalled'
@@ -724,7 +723,7 @@ class Module(models.Model):
mod = self.create(dict(name=mod_name, state=state, **values))
res[1] += 1
- mod._update_dependencies(terp.get('depends', []))
+ mod._update_dependencies(terp.get('depends', []), terp.get('auto_install'))
mod._update_exclusions(terp.get('excludes', []))
mod._update_category(terp.get('category', 'Uncategorized'))
@@ -835,13 +834,15 @@ class Module(models.Model):
def get_apps_server(self):
return tools.config.get('apps_server', 'https://apps.odoo.com/apps')
- def _update_dependencies(self, depends=None):
+ def _update_dependencies(self, depends=None, auto_install_requirements=()):
existing = set(dep.name for dep in self.dependencies_id)
needed = set(depends or [])
for dep in (needed - existing):
self._cr.execute('INSERT INTO ir_module_module_dependency (module_id, name) values (%s, %s)', (self.id, dep))
for dep in (existing - needed):
self._cr.execute('DELETE FROM ir_module_module_dependency WHERE module_id = %s and name = %s', (self.id, dep))
+ self._cr.execute('UPDATE ir_module_module_dependency SET auto_install_required = (name = any(%s)) WHERE module_id = %s',
+ (list(auto_install_requirements or ()), self.id))
self.invalidate_cache(['dependencies_id'], self.ids)
def _update_exclusions(self, excludes=None):
@@ -913,6 +914,11 @@ class ModuleDependency(models.Model):
depend_id = fields.Many2one('ir.module.module', 'Dependency', compute='_compute_depend')
state = fields.Selection(DEP_STATES, string='Status', compute='_compute_state')
+ auto_install_required = fields.Boolean(
+ default=True,
+ help="Whether this dependency blocks automatic installation "
+ "of the dependent")
+
@api.multi
@api.depends('name')
def _compute_depend(self):