diff --git a/module_auto_update/models/module.py b/module_auto_update/models/module.py index 273d72588..398809e61 100644 --- a/module_auto_update/models/module.py +++ b/module_auto_update/models/module.py @@ -41,36 +41,21 @@ class Module(models.Model): "Cannot compute dir hash for %s, module not found", r.display_name) + @api.multi def _store_checksum_installed(self, vals): - if self.env.context.get('retain_checksum_installed'): - return + """Store the right installed checksum, if addon is installed.""" if 'checksum_installed' not in vals: - if vals.get('state') == 'installed': - for r in self: - r.checksum_installed = r.checksum_dir - elif vals.get('state') == 'uninstalled': + try: + version = vals["latest_version"] + except KeyError: + return # Not [un]installing/updating any addon + if version is False: + # Uninstalling self.write({'checksum_installed': False}) - - @api.multi - def button_uninstall(self): - return super( - Module, - self.with_context(module_uninstall=True), - ).button_uninstall() - - @api.multi - def button_uninstall_cancel(self): - return super( - Module, - self.with_context(retain_checksum_installed=True), - ).button_uninstall_cancel() - - @api.multi - def button_upgrade_cancel(self): - return super( - Module, - self.with_context(retain_checksum_installed=True), - ).button_upgrade_cancel() + else: + # Installing or updating + for one in self: + one.checksum_installed = one.checksum_dir @api.model def create(self, vals): diff --git a/module_auto_update/tests/test_module.py b/module_auto_update/tests/test_module.py index bd25ed07a..f8fcf7278 100644 --- a/module_auto_update/tests/test_module.py +++ b/module_auto_update/tests/test_module.py @@ -10,6 +10,7 @@ import mock from odoo.modules import get_module_path from odoo.tests.common import TransactionCase +from odoo.tools import mute_logger from .. import post_init_hook @@ -81,24 +82,19 @@ class TestModule(TransactionCase): def test_store_checksum_installed_state_installed(self): """It should set the module's checksum_installed equal to - checksum_dir when vals contain state 'installed'""" + checksum_dir when vals contain a ``latest_version`` str.""" self.own_module.checksum_installed = 'test' - self.own_module._store_checksum_installed({'state': 'installed'}) + self.own_module._store_checksum_installed({'latest_version': '1.0'}) self.assertEqual( self.own_module.checksum_installed, self.own_module.checksum_dir, - 'Setting state to installed does not store checksum_dir ' - 'as checksum_installed', ) def test_store_checksum_installed_state_uninstalled(self): """It should clear the module's checksum_installed when vals - contain state 'uninstalled'""" + contain ``"latest_version": False``""" self.own_module.checksum_installed = 'test' - self.own_module._store_checksum_installed({'state': 'uninstalled'}) - self.assertEqual( - self.own_module.checksum_installed, False, - 'Setting state to uninstalled does not clear checksum_installed', - ) + self.own_module._store_checksum_installed({'latest_version': False}) + self.assertIs(self.own_module.checksum_installed, False) def test_store_checksum_installed_vals_contain_checksum_installed(self): """It should not set checksum_installed to False or checksum_dir when @@ -198,6 +194,7 @@ class TestModule(TransactionCase): '_store_checksum_installed', ) + @mute_logger("openerp.modules.module") @mock.patch('%s.get_module_path' % model) def test_get_module_list(self, module_path_mock): """It should change the state of modules with different diff --git a/module_auto_update/wizards/module_upgrade.py b/module_auto_update/wizards/module_upgrade.py index 188030dd8..3ab297d18 100644 --- a/module_auto_update/wizards/module_upgrade.py +++ b/module_auto_update/wizards/module_upgrade.py @@ -10,25 +10,40 @@ class ModuleUpgrade(models.TransientModel): @api.model def get_module_list(self): - if not self.env.context.get('module_uninstall'): - Module = self.env["ir.module.module"] - installed_modules = Module.search([('state', '=', 'installed')]) - upgradeable_modules = installed_modules.filtered( - lambda r: r.checksum_dir != r.checksum_installed, - ) - upgradeable_modules.button_upgrade() + """Set modules to upgrade searching by their dir checksum.""" + Module = self.env["ir.module.module"] + installed_modules = Module.search([('state', '=', 'installed')]) + upgradeable_modules = installed_modules.filtered( + lambda r: r.checksum_dir != r.checksum_installed, + ) + upgradeable_modules.button_upgrade() return super(ModuleUpgrade, self).get_module_list() - @api.multi - def upgrade_module_cancel(self): - return super( - ModuleUpgrade, - self.with_context(retain_checksum_installed=True), - ).upgrade_module_cancel() - @api.multi def upgrade_module(self): + """Make a fully automated addon upgrade.""" # Compute updates by checksum when called in @api.model fashion if not self: self.get_module_list() - return super(ModuleUpgrade, self).upgrade_module() + Module = self.env["ir.module.module"] + # Get every addon state before updating + pre_states = {addon["name"]: addon["state"] + for addon in Module.search_read([], ["name", "state"])} + # Perform upgrades, possibly in a limited graph that excludes me + result = super(ModuleUpgrade, self).upgrade_module() + # Reload environments, anything may have changed + self.env.clear() + # Update addons checksum if state changed and I wasn't uninstalled + own = Module.search_read( + [("name", "=", "module_auto_update")], + ["state"], + limit=1) + if own and own[0]["state"] != "uninstalled": + for addon in Module.search([]): + if addon.state != pre_states.get(addon.name): + # Trigger the write hook that should have been + # triggered when the module was [un]installed/updated in + # the limited module graph inside above call to super(), + # and updates its dir checksum as needed + addon.latest_version = addon.latest_version + return result