diff --git a/module_auto_update/__manifest__.py b/module_auto_update/__manifest__.py index e748bc045..6545c217e 100644 --- a/module_auto_update/__manifest__.py +++ b/module_auto_update/__manifest__.py @@ -3,24 +3,20 @@ # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). { - 'name': 'Module Auto Update', - 'summary': 'Automatically update Odoo modules', - 'version': '12.0.2.0.5', - 'category': 'Extra Tools', - 'website': 'https://github.com/OCA/server-tools', - 'author': 'LasLabs, ' - 'Juan José Scarafía, ' - 'Tecnativa, ' - 'ACSONE SA/NV, ' - 'Odoo Community Association (OCA)', - 'license': 'LGPL-3', - 'installable': True, - 'uninstall_hook': 'uninstall_hook', - 'depends': [ - 'base', - ], - 'data': [ - 'views/ir_module_module.xml', - ], - 'development_status': 'Production/Stable', + "name": "Module Auto Update", + "summary": "Automatically update Odoo modules", + "version": "12.0.2.0.5", + "category": "Extra Tools", + "website": "https://github.com/OCA/server-tools", + "author": "LasLabs, " + "Juan José Scarafía, " + "Tecnativa, " + "ACSONE SA/NV, " + "Odoo Community Association (OCA)", + "license": "LGPL-3", + "installable": True, + "uninstall_hook": "uninstall_hook", + "depends": ["base"], + "data": ["views/ir_module_module.xml"], + "development_status": "Production/Stable", } diff --git a/module_auto_update/addon_hash.py b/module_auto_update/addon_hash.py index d2140af33..c9c240b5d 100644 --- a/module_auto_update/addon_hash.py +++ b/module_auto_update/addon_hash.py @@ -1,9 +1,9 @@ # Copyright 2018 ACSONE SA/NV. # License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). -from fnmatch import fnmatch import hashlib import os +from fnmatch import fnmatch def _fnmatch(filename, patterns): @@ -14,20 +14,20 @@ def _fnmatch(filename, patterns): def _walk(top, exclude_patterns, keep_langs): - keep_langs = {l.split('_')[0] for l in keep_langs} + keep_langs = {l.split("_")[0] for l in keep_langs} for dirpath, dirnames, filenames in os.walk(top): dirnames.sort() reldir = os.path.relpath(dirpath, top) - if reldir == '.': - reldir = '' + if reldir == ".": + reldir = "" for filename in sorted(filenames): filepath = os.path.join(reldir, filename) if _fnmatch(filepath, exclude_patterns): continue - if keep_langs and reldir in {'i18n', 'i18n_extra'}: + if keep_langs and reldir in {"i18n", "i18n_extra"}: basename, ext = os.path.splitext(filename) - if ext == '.po': - if basename.split('_')[0] not in keep_langs: + if ext == ".po": + if basename.split("_")[0] not in keep_langs: continue yield filepath @@ -37,8 +37,8 @@ def addon_hash(top, exclude_patterns, keep_langs): m = hashlib.sha1() for filepath in _walk(top, exclude_patterns, keep_langs): # hash filename so empty files influence the hash - m.update(filepath.encode('utf-8')) + m.update(filepath.encode("utf-8")) # hash file content - with open(os.path.join(top, filepath), 'rb') as f: + with open(os.path.join(top, filepath), "rb") as f: m.update(f.read()) return m.hexdigest() diff --git a/module_auto_update/migrations/12.0.2.0.5/post-migration.py b/module_auto_update/migrations/12.0.2.0.5/post-migration.py index 7a5fe2743..67a957858 100644 --- a/module_auto_update/migrations/12.0.2.0.5/post-migration.py +++ b/module_auto_update/migrations/12.0.2.0.5/post-migration.py @@ -6,7 +6,5 @@ from openupgradelib import openupgrade @openupgrade.migrate() def migrate(env, version): openupgrade.delete_records_safely_by_xml_id( - env, [ - 'module_auto_update.module_check_upgrades_cron', - ], + env, ["module_auto_update.module_check_upgrades_cron"], ) diff --git a/module_auto_update/models/module.py b/module_auto_update/models/module.py index ac510e6f8..8caf3ad48 100644 --- a/module_auto_update/models/module.py +++ b/module_auto_update/models/module.py @@ -11,12 +11,9 @@ from odoo.modules.module import get_module_path from ..addon_hash import addon_hash -PARAM_INSTALLED_CHECKSUMS = \ - 'module_auto_update.installed_checksums' -PARAM_EXCLUDE_PATTERNS = \ - 'module_auto_update.exclude_patterns' -DEFAULT_EXCLUDE_PATTERNS = \ - '*.pyc,*.pyo,i18n/*.pot,i18n_extra/*.pot,static/*' +PARAM_INSTALLED_CHECKSUMS = "module_auto_update.installed_checksums" +PARAM_EXCLUDE_PATTERNS = "module_auto_update.exclude_patterns" +DEFAULT_EXCLUDE_PATTERNS = "*.pyc,*.pyo,i18n/*.pot,i18n_extra/*.pot,static/*" _logger = logging.getLogger(__name__) @@ -34,40 +31,33 @@ def ensure_module_state(env, modules, state): if not modules: return env.cr.execute( - "SELECT name FROM ir_module_module " - "WHERE id IN %s AND state != %s", + "SELECT name FROM ir_module_module " "WHERE id IN %s AND state != %s", (tuple(modules.ids), state), ) names = [r[0] for r in env.cr.fetchall()] if names: raise FailedUpgradeError( "The following modules should be in state '%s' " - "at this stage: %s. Bailing out for safety." % - (state, ','.join(names), ), + "at this stage: %s. Bailing out for safety." % (state, ",".join(names),), ) class Module(models.Model): - _inherit = 'ir.module.module' + _inherit = "ir.module.module" @api.multi def _get_checksum_dir(self): self.ensure_one() exclude_patterns = self.env["ir.config_parameter"].get_param( - PARAM_EXCLUDE_PATTERNS, - DEFAULT_EXCLUDE_PATTERNS, + PARAM_EXCLUDE_PATTERNS, DEFAULT_EXCLUDE_PATTERNS, ) - exclude_patterns = [p.strip() for p in exclude_patterns.split(',')] - keep_langs = self.env['res.lang'].search([]).mapped('code') + exclude_patterns = [p.strip() for p in exclude_patterns.split(",")] + keep_langs = self.env["res.lang"].search([]).mapped("code") module_path = get_module_path(self.name) if module_path and os.path.isdir(module_path): - checksum_dir = addon_hash( - module_path, - exclude_patterns, - keep_langs, - ) + checksum_dir = addon_hash(module_path, exclude_patterns, keep_langs,) else: checksum_dir = False @@ -75,32 +65,30 @@ class Module(models.Model): @api.model def _get_saved_checksums(self): - Icp = self.env['ir.config_parameter'] - return json.loads(Icp.get_param(PARAM_INSTALLED_CHECKSUMS, '{}')) + Icp = self.env["ir.config_parameter"] + return json.loads(Icp.get_param(PARAM_INSTALLED_CHECKSUMS, "{}")) @api.model def _save_checksums(self, checksums): - Icp = self.env['ir.config_parameter'] + Icp = self.env["ir.config_parameter"] Icp.set_param(PARAM_INSTALLED_CHECKSUMS, json.dumps(checksums)) @api.model def _save_installed_checksums(self): checksums = {} - installed_modules = self.search([('state', '=', 'installed')]) + installed_modules = self.search([("state", "=", "installed")]) for module in installed_modules: checksums[module.name] = module._get_checksum_dir() self._save_checksums(checksums) @api.model def _get_modules_partially_installed(self): - return self.search([ - ('state', 'in', ('to install', 'to remove', 'to upgrade')), - ]) + return self.search([("state", "in", ("to install", "to remove", "to upgrade"))]) @api.model def _get_modules_with_changed_checksum(self): saved_checksums = self._get_saved_checksums() - installed_modules = self.search([('state', '=', 'installed')]) + installed_modules = self.search([("state", "=", "installed")]) return installed_modules.filtered( lambda r: r._get_checksum_dir() != saved_checksums.get(r.name), ) @@ -131,32 +119,37 @@ class Module(models.Model): """ _logger.info( "Checksum upgrade starting (i18n-overwrite=%s)...", - overwrite_existing_translations + overwrite_existing_translations, ) - tools.config['overwrite_existing_translations'] = \ - overwrite_existing_translations + tools.config[ + "overwrite_existing_translations" + ] = overwrite_existing_translations _logger.info("Updating modules list...") self.update_list() changed_modules = self._get_modules_with_changed_checksum() if not changed_modules and not self._get_modules_partially_installed(): - _logger.info("No checksum change detected in installed modules " - "and all modules installed, nothing to do.") + _logger.info( + "No checksum change detected in installed modules " + "and all modules installed, nothing to do." + ) return - _logger.info("Marking the following modules to upgrade, " - "for their checksums changed: %s...", - ','.join(changed_modules.mapped('name'))) + _logger.info( + "Marking the following modules to upgrade, " + "for their checksums changed: %s...", + ",".join(changed_modules.mapped("name")), + ) changed_modules.button_upgrade() self.env.cr.commit() # pylint: disable=invalid-commit # in rare situations, button_upgrade may fail without # exception, this would lead to corruption because # no upgrade would be performed and save_installed_checksums # would update cheksums for modules that have not been upgraded - ensure_module_state(self.env, changed_modules, 'to upgrade') + ensure_module_state(self.env, changed_modules, "to upgrade") _logger.info("Upgrading...") - self.env['base.module.upgrade'].upgrade_module() + self.env["base.module.upgrade"].upgrade_module() self.env.cr.commit() # pylint: disable=invalid-commit _logger.info("Upgrade successful, updating checksums...") @@ -167,8 +160,8 @@ class Module(models.Model): if partial_modules: raise IncompleteUpgradeError( "Checksum upgrade successful " - "but incomplete for the following modules: %s" % - ','.join(partial_modules.mapped('name')) + "but incomplete for the following modules: %s" + % ",".join(partial_modules.mapped("name")) ) _logger.info("Checksum upgrade complete.") diff --git a/module_auto_update/tests/sample_module/data/f1.xml b/module_auto_update/tests/sample_module/data/f1.xml index 77a8d9d78..238507479 100644 --- a/module_auto_update/tests/sample_module/data/f1.xml +++ b/module_auto_update/tests/sample_module/data/f1.xml @@ -1 +1 @@ - + diff --git a/module_auto_update/tests/sample_module/data/f2.xml b/module_auto_update/tests/sample_module/data/f2.xml index 77a8d9d78..238507479 100644 --- a/module_auto_update/tests/sample_module/data/f2.xml +++ b/module_auto_update/tests/sample_module/data/f2.xml @@ -1 +1 @@ - + diff --git a/module_auto_update/tests/sample_module/models/stuff.py b/module_auto_update/tests/sample_module/models/stuff.py index c040fa67d..911c43ed1 100644 --- a/module_auto_update/tests/sample_module/models/stuff.py +++ b/module_auto_update/tests/sample_module/models/stuff.py @@ -1 +1 @@ -1+1 +_ = 1 + 1 diff --git a/module_auto_update/tests/test_addon_hash.py b/module_auto_update/tests/test_addon_hash.py index ffcee3f16..05836334a 100644 --- a/module_auto_update/tests/test_addon_hash.py +++ b/module_auto_update/tests/test_addon_hash.py @@ -9,59 +9,63 @@ from ..models.module import DEFAULT_EXCLUDE_PATTERNS class TestAddonHash(unittest.TestCase): - def setUp(self): super(TestAddonHash, self).setUp() - self.sample_dir = os.path.join( - os.path.dirname(__file__), - 'sample_module', - ) + self.sample_dir = os.path.join(os.path.dirname(__file__), "sample_module",) def test_basic(self): - files = list(addon_hash._walk( - self.sample_dir, - exclude_patterns=["*/__pycache__/*"], - keep_langs=[], - )) - self.assertEqual(files, [ - 'README.rst', - 'data/f1.xml', - 'data/f2.xml', - 'i18n/en.po', - 'i18n/en_US.po', - 'i18n/fr.po', - 'i18n/fr_BE.po', - 'i18n/test.pot', - 'i18n_extra/en.po', - 'i18n_extra/fr.po', - 'i18n_extra/nl_NL.po', - 'models/stuff.py', - 'models/stuff.pyc', - 'models/stuff.pyo', - 'static/src/some.js', - ]) + files = list( + addon_hash._walk( + self.sample_dir, exclude_patterns=["*/__pycache__/*"], keep_langs=[], + ) + ) + self.assertEqual( + files, + [ + "README.rst", + "data/f1.xml", + "data/f2.xml", + "i18n/en.po", + "i18n/en_US.po", + "i18n/fr.po", + "i18n/fr_BE.po", + "i18n/test.pot", + "i18n_extra/en.po", + "i18n_extra/fr.po", + "i18n_extra/nl_NL.po", + "models/stuff.py", + "models/stuff.pyc", + "models/stuff.pyo", + "static/src/some.js", + ], + ) def test_exclude(self): - files = list(addon_hash._walk( - self.sample_dir, - exclude_patterns=DEFAULT_EXCLUDE_PATTERNS.split(','), - keep_langs=['fr_FR', 'nl'], - )) - self.assertEqual(files, [ - 'README.rst', - 'data/f1.xml', - 'data/f2.xml', - 'i18n/fr.po', - 'i18n/fr_BE.po', - 'i18n_extra/fr.po', - 'i18n_extra/nl_NL.po', - 'models/stuff.py', - ]) + files = list( + addon_hash._walk( + self.sample_dir, + exclude_patterns=DEFAULT_EXCLUDE_PATTERNS.split(","), + keep_langs=["fr_FR", "nl"], + ) + ) + self.assertEqual( + files, + [ + "README.rst", + "data/f1.xml", + "data/f2.xml", + "i18n/fr.po", + "i18n/fr_BE.po", + "i18n_extra/fr.po", + "i18n_extra/nl_NL.po", + "models/stuff.py", + ], + ) def test2(self): checksum = addon_hash.addon_hash( self.sample_dir, - exclude_patterns=['*.pyc', '*.pyo', '*.pot', 'static/*'], - keep_langs=['fr_FR', 'nl'], + exclude_patterns=["*.pyc", "*.pyo", "*.pot", "static/*"], + keep_langs=["fr_FR", "nl"], ) - self.assertEqual(checksum, 'fecb89486c8a29d1f760cbd01c1950f6e8421b14') + self.assertEqual(checksum, "fecb89486c8a29d1f760cbd01c1950f6e8421b14") diff --git a/module_auto_update/tests/test_module.py b/module_auto_update/tests/test_module.py index a3ada72ba..f05b26164 100644 --- a/module_auto_update/tests/test_module.py +++ b/module_auto_update/tests/test_module.py @@ -12,23 +12,22 @@ from odoo.modules import get_module_path from odoo.tests import TransactionCase from ..addon_hash import addon_hash -from ..models.module import IncompleteUpgradeError, DEFAULT_EXCLUDE_PATTERNS +from ..models.module import DEFAULT_EXCLUDE_PATTERNS, IncompleteUpgradeError -MODULE_NAME = 'module_auto_update' +MODULE_NAME = "module_auto_update" class TestModule(TransactionCase): - def setUp(self): super(TestModule, self).setUp() - self.own_module = self.env['ir.module.module'].search([ - ('name', '=', MODULE_NAME), - ]) + self.own_module = self.env["ir.module.module"].search( + [("name", "=", MODULE_NAME)] + ) self.own_dir_path = get_module_path(MODULE_NAME) - keep_langs = self.env['res.lang'].search([]).mapped('code') + keep_langs = self.env["res.lang"].search([]).mapped("code") self.own_checksum = addon_hash( self.own_dir_path, - exclude_patterns=DEFAULT_EXCLUDE_PATTERNS.split(','), + exclude_patterns=DEFAULT_EXCLUDE_PATTERNS.split(","), keep_langs=keep_langs, ) self.own_writeable = os.access(self.own_dir_path, os.W_OK) @@ -36,8 +35,9 @@ class TestModule(TransactionCase): def test_compute_checksum_dir(self): """It should compute the directory's SHA-1 hash""" self.assertEqual( - self.own_module._get_checksum_dir(), self.own_checksum, - 'Module directory checksum not computed properly', + self.own_module._get_checksum_dir(), + self.own_checksum, + "Module directory checksum not computed properly", ) def test_compute_checksum_dir_ignore_excluded(self): @@ -45,10 +45,11 @@ class TestModule(TransactionCase): calculations""" if not self.own_writeable: self.skipTest("Own directory not writeable") - with tempfile.NamedTemporaryFile(suffix='.pyc', dir=self.own_dir_path): + with tempfile.NamedTemporaryFile(suffix=".pyc", dir=self.own_dir_path): self.assertEqual( - self.own_module._get_checksum_dir(), self.own_checksum, - 'SHA1 checksum does not ignore excluded extensions', + self.own_module._get_checksum_dir(), + self.own_checksum, + "SHA1 checksum does not ignore excluded extensions", ) def test_compute_checksum_dir_recomputes_when_file_added(self): @@ -56,62 +57,59 @@ class TestModule(TransactionCase): added to the module directory""" if not self.own_writeable: self.skipTest("Own directory not writeable") - with tempfile.NamedTemporaryFile(suffix='.py', dir=self.own_dir_path): + with tempfile.NamedTemporaryFile(suffix=".py", dir=self.own_dir_path): self.assertNotEqual( - self.own_module._get_checksum_dir(), self.own_checksum, - 'SHA1 checksum not recomputed', + self.own_module._get_checksum_dir(), + self.own_checksum, + "SHA1 checksum not recomputed", ) def test_saved_checksums(self): - Imm = self.env['ir.module.module'] - base_module = Imm.search([('name', '=', 'base')]) - self.assertEqual(base_module.state, 'installed') + Imm = self.env["ir.module.module"] + base_module = Imm.search([("name", "=", "base")]) + self.assertEqual(base_module.state, "installed") self.assertFalse(Imm._get_saved_checksums()) Imm._save_installed_checksums() saved_checksums = Imm._get_saved_checksums() self.assertTrue(saved_checksums) - self.assertTrue(saved_checksums['base']) + self.assertTrue(saved_checksums["base"]) def test_get_modules_with_changed_checksum(self): - Imm = self.env['ir.module.module'] + Imm = self.env["ir.module.module"] self.assertTrue(Imm._get_modules_with_changed_checksum()) Imm._save_installed_checksums() self.assertFalse(Imm._get_modules_with_changed_checksum()) -@odoo.tests.tagged('post_install', '-at_install') +@odoo.tests.tagged("post_install", "-at_install") class TestModuleAfterInstall(TransactionCase): - def setUp(self): super(TestModuleAfterInstall, self).setUp() - Imm = self.env['ir.module.module'] - self.own_module = Imm.search([('name', '=', MODULE_NAME)]) - self.base_module = Imm.search([('name', '=', 'base')]) + Imm = self.env["ir.module.module"] + self.own_module = Imm.search([("name", "=", MODULE_NAME)]) + self.base_module = Imm.search([("name", "=", "base")]) def test_get_modules_partially_installed(self): - Imm = self.env['ir.module.module'] - self.assertTrue( - self.own_module not in Imm._get_modules_partially_installed()) + Imm = self.env["ir.module.module"] + self.assertTrue(self.own_module not in Imm._get_modules_partially_installed()) self.own_module.button_upgrade() - self.assertTrue( - self.own_module in Imm._get_modules_partially_installed()) + self.assertTrue(self.own_module in Imm._get_modules_partially_installed()) self.own_module.button_upgrade_cancel() - self.assertTrue( - self.own_module not in Imm._get_modules_partially_installed()) + self.assertTrue(self.own_module not in Imm._get_modules_partially_installed()) def test_upgrade_changed_checksum(self): - Imm = self.env['ir.module.module'] - Bmu = self.env['base.module.upgrade'] + Imm = self.env["ir.module.module"] + Bmu = self.env["base.module.upgrade"] # check modules are in installed state - installed_modules = Imm.search([('state', '=', 'installed')]) + installed_modules = Imm.search([("state", "=", "installed")]) self.assertTrue(self.own_module in installed_modules) self.assertTrue(self.base_module in installed_modules) self.assertTrue(len(installed_modules) > 2) # change the checksum of 'base' Imm._save_installed_checksums() saved_checksums = Imm._get_saved_checksums() - saved_checksums['base'] = False + saved_checksums["base"] = False Imm._save_checksums(saved_checksums) changed_modules = Imm._get_modules_with_changed_checksum() self.assertEqual(len(changed_modules), 1) @@ -121,102 +119,100 @@ class TestModuleAfterInstall(TransactionCase): upgrade_module_mock.call_count += 1 # since we are upgrading base, all installed module # must have been marked to upgrade at this stage - self.assertEqual(self.base_module.state, 'to upgrade') - self.assertEqual(self.own_module.state, 'to upgrade') - installed_modules.write({'state': 'installed'}) + self.assertEqual(self.base_module.state, "to upgrade") + self.assertEqual(self.own_module.state, "to upgrade") + installed_modules.write({"state": "installed"}) upgrade_module_mock.call_count = 0 # upgrade_changed_checksum commits, so mock that - with mock.patch.object(self.env.cr, 'commit'): + with mock.patch.object(self.env.cr, "commit"): # we simulate an install by setting module states - Bmu._patch_method('upgrade_module', upgrade_module_mock) + Bmu._patch_method("upgrade_module", upgrade_module_mock) try: Imm.upgrade_changed_checksum() self.assertEqual(upgrade_module_mock.call_count, 1) - self.assertEqual(self.base_module.state, 'installed') - self.assertEqual(self.own_module.state, 'installed') + self.assertEqual(self.base_module.state, "installed") + self.assertEqual(self.own_module.state, "installed") saved_checksums = Imm._get_saved_checksums() - self.assertTrue(saved_checksums['base']) + self.assertTrue(saved_checksums["base"]) self.assertTrue(saved_checksums[MODULE_NAME]) finally: - Bmu._revert_method('upgrade_module') + Bmu._revert_method("upgrade_module") def test_incomplete_upgrade(self): - Imm = self.env['ir.module.module'] - Bmu = self.env['base.module.upgrade'] + Imm = self.env["ir.module.module"] + Bmu = self.env["base.module.upgrade"] - installed_modules = Imm.search([('state', '=', 'installed')]) + installed_modules = Imm.search([("state", "=", "installed")]) # change the checksum of 'base' Imm._save_installed_checksums() saved_checksums = Imm._get_saved_checksums() - saved_checksums['base'] = False + saved_checksums["base"] = False Imm._save_checksums(saved_checksums) def upgrade_module_mock(self_model): upgrade_module_mock.call_count += 1 # since we are upgrading base, all installed module # must have been marked to upgrade at this stage - self.assertEqual(self.base_module.state, 'to upgrade') - self.assertEqual(self.own_module.state, 'to upgrade') - installed_modules.write({'state': 'installed'}) + self.assertEqual(self.base_module.state, "to upgrade") + self.assertEqual(self.own_module.state, "to upgrade") + installed_modules.write({"state": "installed"}) # simulate partial upgrade - self.own_module.write({'state': 'to upgrade'}) + self.own_module.write({"state": "to upgrade"}) upgrade_module_mock.call_count = 0 # upgrade_changed_checksum commits, so mock that - with mock.patch.object(self.env.cr, 'commit'): + with mock.patch.object(self.env.cr, "commit"): # we simulate an install by setting module states - Bmu._patch_method('upgrade_module', upgrade_module_mock) + Bmu._patch_method("upgrade_module", upgrade_module_mock) try: with self.assertRaises(IncompleteUpgradeError): Imm.upgrade_changed_checksum() self.assertEqual(upgrade_module_mock.call_count, 1) finally: - Bmu._revert_method('upgrade_module') + Bmu._revert_method("upgrade_module") def test_incomplete_upgrade_no_checkusm(self): - Imm = self.env['ir.module.module'] - Bmu = self.env['base.module.upgrade'] + Imm = self.env["ir.module.module"] + Bmu = self.env["base.module.upgrade"] - installed_modules = Imm.search( - [('state', '=', 'installed')]) + installed_modules = Imm.search([("state", "=", "installed")]) # change the checksum of 'base' Imm._save_installed_checksums() saved_checksums = Imm._get_saved_checksums() Imm._save_checksums(saved_checksums) - self.base_module.write({'state': 'to upgrade'}) + self.base_module.write({"state": "to upgrade"}) def upgrade_module_mock(self_model): upgrade_module_mock.call_count += 1 # since we are upgrading base, all installed module # must have been marked to upgrade at this stage - self.assertEqual(self.base_module.state, 'to upgrade') - self.assertEqual(self.own_module.state, 'installed') - installed_modules.write({'state': 'installed'}) + self.assertEqual(self.base_module.state, "to upgrade") + self.assertEqual(self.own_module.state, "installed") + installed_modules.write({"state": "installed"}) upgrade_module_mock.call_count = 0 # upgrade_changed_checksum commits, so mock that - with mock.patch.object(self.env.cr, 'commit'): + with mock.patch.object(self.env.cr, "commit"): # we simulate an install by setting module states - Bmu._patch_method('upgrade_module', - upgrade_module_mock) + Bmu._patch_method("upgrade_module", upgrade_module_mock) # got just other modules to_upgrade and no checksum ones try: Imm.upgrade_changed_checksum() self.assertEqual(upgrade_module_mock.call_count, 1) finally: - Bmu._revert_method('upgrade_module') + Bmu._revert_method("upgrade_module") def test_nothing_to_upgrade(self): - Imm = self.env['ir.module.module'] - Bmu = self.env['base.module.upgrade'] + Imm = self.env["ir.module.module"] + Bmu = self.env["base.module.upgrade"] Imm._save_installed_checksums() @@ -226,12 +222,12 @@ class TestModuleAfterInstall(TransactionCase): upgrade_module_mock.call_count = 0 # upgrade_changed_checksum commits, so mock that - with mock.patch.object(self.env.cr, 'commit'): + with mock.patch.object(self.env.cr, "commit"): # we simulate an install by setting module states - Bmu._patch_method('upgrade_module', upgrade_module_mock) + Bmu._patch_method("upgrade_module", upgrade_module_mock) try: Imm.upgrade_changed_checksum() self.assertEqual(upgrade_module_mock.call_count, 0) finally: - Bmu._revert_method('upgrade_module') + Bmu._revert_method("upgrade_module") diff --git a/module_auto_update/views/ir_module_module.xml b/module_auto_update/views/ir_module_module.xml index e7a8ce9f6..fcd80d31a 100644 --- a/module_auto_update/views/ir_module_module.xml +++ b/module_auto_update/views/ir_module_module.xml @@ -4,17 +4,15 @@ Copyright 2018 Brainbean Apps (https://brainbeanapps.com) License LGPL-3.0 or later (https://www.gnu.org/licenses/lgpl). --> - Auto-Upgrade Modules ir.actions.server - + code action = model.upgrade_changed_checksum() - - + icon="fa-exchange" + />