From f76ed740e518959b5fd4d51d9e8c6a7a40b5e72e Mon Sep 17 00:00:00 2001
From: Sylvain LE GAL
Date: Sat, 7 Nov 2020 00:35:37 +0100
Subject: [PATCH] [IMP] upgrade_analysis: improve install wizard to have the
possibility to select some modules, and improve filters, regarding test
module with startswith and endswith pattern
---
upgrade_analysis/__init__.py | 1 +
upgrade_analysis/blacklist.py | 17 +--
upgrade_analysis/models/__init__.py | 1 +
upgrade_analysis/models/ir_module_module.py | 35 ++++++
upgrade_analysis/tests/__init__.py | 1 +
upgrade_analysis/tests/test_module.py | 46 ++++++++
upgrade_analysis/views/menu.xml | 3 +-
.../wizards/upgrade_generate_record_wizard.py | 2 +-
.../wizards/upgrade_install_wizard.py | 103 +++++++++++++-----
.../view_upgrade_generate_record_wizard.xml | 4 +-
.../wizards/view_upgrade_install_wizard.xml | 63 +++++++++--
11 files changed, 227 insertions(+), 49 deletions(-)
create mode 100644 upgrade_analysis/models/ir_module_module.py
create mode 100644 upgrade_analysis/tests/__init__.py
create mode 100644 upgrade_analysis/tests/test_module.py
diff --git a/upgrade_analysis/__init__.py b/upgrade_analysis/__init__.py
index abe0f8c3c..338ffe995 100644
--- a/upgrade_analysis/__init__.py
+++ b/upgrade_analysis/__init__.py
@@ -1,3 +1,4 @@
+from . import odoo_patch
from . import models
from . import wizards
from . import blacklist
diff --git a/upgrade_analysis/blacklist.py b/upgrade_analysis/blacklist.py
index 814396ad6..41943d6fb 100644
--- a/upgrade_analysis/blacklist.py
+++ b/upgrade_analysis/blacklist.py
@@ -1,7 +1,10 @@
-BLACKLIST_MODULES = [
- # the hw_* modules are not affected by a migration as they don't
- # contain any ORM functionality, but they do start up threads that
- # delay the process and spit out annoying log messages continously.
- "hw_escpos",
- "hw_proxy",
-]
+BLACKLIST_MODULES = []
+
+# the hw_* modules are not affected by a migration as they don't
+# contain any ORM functionality, but they do start up threads that
+# delay the process and spit out annoying log messages continously.
+
+# We also don't want to analyze tests modules
+BLACKLIST_MODULES_STARTS_WITH = ["hw_", "test_"]
+
+BLACKLIST_MODULES_ENDS_WITH = ["_test"]
diff --git a/upgrade_analysis/models/__init__.py b/upgrade_analysis/models/__init__.py
index 748d5aee0..e0245a184 100644
--- a/upgrade_analysis/models/__init__.py
+++ b/upgrade_analysis/models/__init__.py
@@ -1,3 +1,4 @@
+from . import ir_module_module
from . import upgrade_comparison_config
from . import upgrade_attribute
from . import upgrade_record
diff --git a/upgrade_analysis/models/ir_module_module.py b/upgrade_analysis/models/ir_module_module.py
new file mode 100644
index 000000000..9456af708
--- /dev/null
+++ b/upgrade_analysis/models/ir_module_module.py
@@ -0,0 +1,35 @@
+# Copyright 2011-2015 Therp BV
+# Copyright 2016 Opener B.V.
+# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl).
+
+import os
+
+from odoo import fields, models
+from odoo.modules import get_module_path
+
+
+class UpgradeAttribute(models.Model):
+ _inherit = "ir.module.module"
+
+ is_odoo_module = fields.Boolean(
+ compute="_compute_is_odoo_module",
+ )
+
+ is_oca_module = fields.Boolean(compute="_compute_is_oca_module")
+
+ def _compute_is_oca_module(self):
+ for module in self:
+ if "/OCA/" in module.website:
+ module.is_oca_module = True
+ else:
+ module.is_oca_module = False
+
+ def _compute_is_odoo_module(self):
+ for module in self:
+ module_path = get_module_path(module.name)
+ absolute_repo_path = os.path.split(module_path)[0]
+ x, relative_repo_path = os.path.split(absolute_repo_path)
+ if relative_repo_path == "addons":
+ module.is_odoo_module = True
+ else:
+ module.is_odoo_module = False
diff --git a/upgrade_analysis/tests/__init__.py b/upgrade_analysis/tests/__init__.py
new file mode 100644
index 000000000..d9b96c4fa
--- /dev/null
+++ b/upgrade_analysis/tests/__init__.py
@@ -0,0 +1 @@
+from . import test_module
diff --git a/upgrade_analysis/tests/test_module.py b/upgrade_analysis/tests/test_module.py
new file mode 100644
index 000000000..85a66d9b7
--- /dev/null
+++ b/upgrade_analysis/tests/test_module.py
@@ -0,0 +1,46 @@
+from odoo.tests import common, tagged
+
+
+@tagged("post_install", "-at_install")
+class TestUpgradeAnalysis(common.TransactionCase):
+ def setUp(self):
+ super().setUp()
+ self.IrModuleModule = self.env["ir.module.module"]
+ self.product_module = self.IrModuleModule.search([("name", "=", "product")])
+ self.sale_module = self.IrModuleModule.search([("name", "=", "sale")])
+ self.upgrade_analysis = self.IrModuleModule.search(
+ [("name", "=", "upgrade_analysis")]
+ )
+
+ def test_upgrade_install_wizard(self):
+ InstallWizard = self.env["upgrade.install.wizard"]
+ wizard = InstallWizard.create({})
+
+ wizard.select_odoo_modules()
+ self.assertTrue(
+ self.product_module.id in wizard.module_ids.ids,
+ "Select Odoo module should select 'product' module",
+ )
+
+ wizard.select_oca_modules()
+ self.assertTrue(
+ self.upgrade_analysis.id in wizard.module_ids.ids,
+ "Select OCA module should select 'upgrade_analysis' module",
+ )
+
+ wizard.select_other_modules()
+ self.assertTrue(
+ self.product_module.id not in wizard.module_ids.ids,
+ "Select Other module should not select 'product' module",
+ )
+
+ wizard.unselect_modules()
+ self.assertEqual(
+ wizard.module_ids.ids, [], "Unselect module should clear the selection"
+ )
+ # For the time being, tests doens't call install_modules() function
+ # because installing module in a test context will execute the test
+ # of the installed modules, raising finally an error:
+
+ # TypeError: Many2many fields ir.actions.server.partner_ids and
+ # ir.actions.server.partner_ids use the same table and columns
diff --git a/upgrade_analysis/views/menu.xml b/upgrade_analysis/views/menu.xml
index 12d44779d..e12c75236 100644
--- a/upgrade_analysis/views/menu.xml
+++ b/upgrade_analysis/views/menu.xml
@@ -1,10 +1,9 @@
-
diff --git a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
index fc7f6c02f..439f6b2c2 100644
--- a/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_generate_record_wizard.py
@@ -95,7 +95,7 @@ class GenerateWizard(models.TransientModel):
)
self.env.cache.invalidate(
[
- (self.env["openupgrade.record"]._fields["noupdate"], None),
+ (self.env["upgrade.record"]._fields["noupdate"], None),
]
)
diff --git a/upgrade_analysis/wizards/upgrade_install_wizard.py b/upgrade_analysis/wizards/upgrade_install_wizard.py
index 4ea1d36b9..d91232867 100644
--- a/upgrade_analysis/wizards/upgrade_install_wizard.py
+++ b/upgrade_analysis/wizards/upgrade_install_wizard.py
@@ -6,7 +6,11 @@ from odoo import api, fields, models
from odoo.modules.registry import Registry
from odoo.osv.expression import AND
-from ..blacklist import BLACKLIST_MODULES
+from ..blacklist import (
+ BLACKLIST_MODULES,
+ BLACKLIST_MODULES_ENDS_WITH,
+ BLACKLIST_MODULES_STARTS_WITH,
+)
class UpgradeInstallWizard(models.TransientModel):
@@ -14,38 +18,87 @@ class UpgradeInstallWizard(models.TransientModel):
_description = "Upgrade Install Wizard"
state = fields.Selection(
- [("init", "init"), ("ready", "ready")], readonly=True, default="init"
+ [("draft", "Draft"), ("done", "Done")], readonly=True, default="draft"
+ )
+
+ module_ids = fields.Many2many(
+ comodel_name="ir.module.module",
+ domain=lambda x: x._module_ids_domain(),
+ )
+
+ module_qty = fields.Integer(
+ string="Modules Quantity", compute="_compute_module_qty"
)
- to_install = fields.Integer("Number of modules to install", readonly=True)
@api.model
- def default_get(self, fields):
- """Update module list and retrieve the number
- of installable modules"""
- res = super().default_get(fields)
- update, add = self.env["ir.module.module"].update_list()
- modules = self.env["ir.module.module"].search(
- [("state", "not in", ["uninstallable", "unknown"])]
- )
- res["to_install"] = len(modules)
- return res
-
- def install_all(self, extra_domain=None):
- """Main wizard step. Set all installable modules to install
- and actually install them. Exclude testing modules."""
+ def _module_ids_domain(self, extra_domain=None):
domain = [
- "&",
"&",
("state", "not in", ["uninstallable", "unknown"]),
- ("category_id.name", "!=", "Tests"),
("name", "not in", BLACKLIST_MODULES),
]
if extra_domain:
domain = AND([domain, extra_domain])
modules = self.env["ir.module.module"].search(domain)
- if modules:
- modules.write({"state": "to install"})
- self.env.cr.commit() # pylint: disable=invalid-commit
- Registry.new(self.env.cr.dbname, update_module=True)
- self.write({"state": "ready"})
- return True
+
+ for start_pattern in BLACKLIST_MODULES_STARTS_WITH:
+ modules = modules.filtered(lambda x: not x.name.startswith(start_pattern))
+ for end_pattern in BLACKLIST_MODULES_ENDS_WITH:
+ modules = modules.filtered(lambda x: not x.name.endswith(end_pattern))
+ return [("id", "in", modules.ids)]
+
+ @api.depends("module_ids")
+ def _compute_module_qty(self):
+ for wizard in self:
+ wizard.module_qty = len(wizard.module_ids)
+
+ def select_odoo_modules(self):
+ self.ensure_one()
+ modules = self.env["ir.module.module"].search(self._module_ids_domain())
+ modules = modules.filtered(lambda x: x.is_odoo_module)
+ self.module_ids = modules
+ return self.return_same_form_view()
+
+ def select_oca_modules(self):
+ self.ensure_one()
+ modules = self.env["ir.module.module"].search(self._module_ids_domain())
+ modules = modules.filtered(lambda x: x.is_oca_module)
+ self.module_ids = modules
+ return self.return_same_form_view()
+
+ def select_other_modules(self):
+ self.ensure_one()
+ modules = self.env["ir.module.module"].search(self._module_ids_domain())
+ modules = modules.filtered(lambda x: not (x.is_oca_module or x.is_odoo_module))
+ self.module_ids = modules
+ return self.return_same_form_view()
+
+ def select_installable_modules(self):
+ self.ensure_one()
+ self.module_ids = self.env["ir.module.module"].search(self._module_ids_domain())
+ return self.return_same_form_view()
+
+ def unselect_modules(self):
+ self.ensure_one()
+ self.module_ids = False
+ return self.return_same_form_view()
+
+ def install_modules(self):
+ """Set all selected modules and actually install them."""
+ self.ensure_one()
+ self.module_ids.write({"state": "to install"})
+ self.env.cr.commit() # pylint: disable=invalid-commit
+ Registry.new(self.env.cr.dbname, update_module=True)
+ self.write({"state": "done"})
+ return self.return_same_form_view()
+
+ def return_same_form_view(self):
+ return {
+ "type": "ir.actions.act_window",
+ "res_model": "upgrade.install.wizard",
+ "view_mode": "form",
+ "view_type": "form",
+ "res_id": self.id,
+ "views": [(False, "form")],
+ "target": "new",
+ }
diff --git a/upgrade_analysis/wizards/view_upgrade_generate_record_wizard.xml b/upgrade_analysis/wizards/view_upgrade_generate_record_wizard.xml
index 86c620179..a0a310e74 100644
--- a/upgrade_analysis/wizards/view_upgrade_generate_record_wizard.xml
+++ b/upgrade_analysis/wizards/view_upgrade_generate_record_wizard.xml
@@ -28,7 +28,7 @@
- Generate Records
+ Generate Records Wizard
ir.actions.act_window
upgrade.generate.record.wizard
form,tree
@@ -36,7 +36,7 @@
-
- Modules installed
+
+ The modules have been installed successfuly
+
+
+
+
+
+
+
+
+
+
+
@@ -29,7 +68,7 @@
- Install Modules
+ Install Modules Wizard
ir.actions.act_window
upgrade.install.wizard
form,tree
@@ -37,7 +76,7 @@