Browse Source
Merge pull request #1382 from acsone/12.0-mig-module_auto_update
Merge pull request #1382 from acsone/12.0-mig-module_auto_update
[MIG][12.0] module auto update from 11 to 12pull/1376/merge
Stéphane Bidoul (ACSONE)
6 years ago
committed by
GitHub
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
47 changed files with 1890 additions and 21 deletions
-
25.travis.yml
-
2README.md
-
144module_auto_update/README.rst
-
4module_auto_update/__init__.py
-
23module_auto_update/__manifest__.py
-
44module_auto_update/addon_hash.py
-
11module_auto_update/hooks.py
-
46module_auto_update/i18n/ca.po
-
59module_auto_update/i18n/cs_CZ.po
-
47module_auto_update/i18n/de.po
-
56module_auto_update/i18n/es.po
-
47module_auto_update/i18n/es_MX.po
-
58module_auto_update/i18n/fr.po
-
47module_auto_update/i18n/hr.po
-
46module_auto_update/i18n/it.po
-
42module_auto_update/i18n/module_auto_update.pot
-
47module_auto_update/i18n/nl_NL.po
-
47module_auto_update/i18n/pt_BR.po
-
47module_auto_update/i18n/sl.po
-
46module_auto_update/i18n/tr.po
-
3module_auto_update/models/__init__.py
-
174module_auto_update/models/module.py
-
9module_auto_update/readme/CONFIGURE.rst
-
4module_auto_update/readme/CONTRIBUTORS.rst
-
4module_auto_update/readme/DESCRIPTION.rst
-
18module_auto_update/readme/USAGE.rst
-
483module_auto_update/static/description/index.html
-
4module_auto_update/tests/__init__.py
-
1module_auto_update/tests/sample_module/README.rst
-
1module_auto_update/tests/sample_module/data/f1.xml
-
1module_auto_update/tests/sample_module/data/f2.xml
-
1module_auto_update/tests/sample_module/i18n/en.po
-
1module_auto_update/tests/sample_module/i18n/en_US.po
-
1module_auto_update/tests/sample_module/i18n/fr.po
-
1module_auto_update/tests/sample_module/i18n/fr_BE.po
-
1module_auto_update/tests/sample_module/i18n/test.pot
-
1module_auto_update/tests/sample_module/i18n_extra/en.po
-
1module_auto_update/tests/sample_module/i18n_extra/fr.po
-
1module_auto_update/tests/sample_module/i18n_extra/nl_NL.po
-
1module_auto_update/tests/sample_module/models/stuff.py
-
BINmodule_auto_update/tests/sample_module/models/stuff.pyc
-
BINmodule_auto_update/tests/sample_module/models/stuff.pyo
-
1module_auto_update/tests/sample_module/static/src/some.js
-
67module_auto_update/tests/test_addon_hash.py
-
237module_auto_update/tests/test_module.py
-
1setup/module_auto_update/odoo/addons/module_auto_update
-
6setup/module_auto_update/setup.py
@ -0,0 +1,144 @@ |
|||
================== |
|||
Module Auto Update |
|||
================== |
|||
|
|||
.. !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
|||
!! This file is generated by oca-gen-addon-readme !! |
|||
!! changes will be overwritten. !! |
|||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
|||
|
|||
.. |badge1| image:: https://img.shields.io/badge/maturity-Production%2FStable-green.png |
|||
:target: https://odoo-community.org/page/development-status |
|||
:alt: Production/Stable |
|||
.. |badge2| image:: https://img.shields.io/badge/licence-LGPL--3-blue.png |
|||
:target: http://www.gnu.org/licenses/lgpl-3.0-standalone.html |
|||
:alt: License: LGPL-3 |
|||
.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github |
|||
:target: https://github.com/OCA/server-tools/tree/11.0/module_auto_update |
|||
:alt: OCA/server-tools |
|||
.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png |
|||
:target: https://translation.odoo-community.org/projects/server-tools-11-0/server-tools-11-0-module_auto_update |
|||
:alt: Translate me on Weblate |
|||
.. |badge5| image:: https://img.shields.io/badge/runbot-Try%20me-875A7B.png |
|||
:target: https://runbot.odoo-community.org/runbot/149/11.0 |
|||
:alt: Try me on Runbot |
|||
|
|||
|badge1| |badge2| |badge3| |badge4| |badge5| |
|||
|
|||
This addon provides mechanisms to compute sha1 hashes of installed addons, |
|||
and save them in the database. It also provides a method that exploits these |
|||
mechanisms to update a database by upgrading only the modules for which the |
|||
hash has changed since the last successful upgrade. |
|||
|
|||
**Table of contents** |
|||
|
|||
.. contents:: |
|||
:local: |
|||
|
|||
Configuration |
|||
============= |
|||
|
|||
This module supports the following system parameters: |
|||
|
|||
* ``module_auto_update.exclude_patterns``: comma-separated list of file |
|||
name patterns to ignore when computing addon checksums. Defaults to |
|||
``*.pyc,*.pyo,i18n/*.pot,i18n_extra/*.pot,static/*``. |
|||
Filename patterns must be compatible with the python ``fnmatch`` function. |
|||
|
|||
In addition to the above pattern, .po files corresponding to languages that |
|||
are not installed in the Odoo database are ignored when computing checksums. |
|||
|
|||
Usage |
|||
===== |
|||
|
|||
The main method provided by this module is ``upgrade_changed_checksum`` |
|||
on ``ir.module.module``. It runs a database upgrade for all installed |
|||
modules for which the hash has changed since the last successful |
|||
run of this method. On success it saves the hashes in the database. |
|||
|
|||
The first time this method is invoked after installing the module, it |
|||
runs an upgrade of all modules, because it has not saved the hashes yet. |
|||
This is by design, priviledging safety. Should this be an issue, |
|||
the method ``_save_installed_checksums`` can be invoked in a situation |
|||
where one is sure all modules on disk are installed and up-to-date in the |
|||
database. |
|||
|
|||
An easy way to invoke this upgrade mechanism is by issuing the following |
|||
in an Odoo shell session:: |
|||
|
|||
env['ir.module.module'].upgrade_changed_checksum() |
|||
|
|||
Known issues / Roadmap |
|||
====================== |
|||
|
|||
* Since version ``2.0.0``, some features have been deprecated. |
|||
When you upgrade from previous versions, these features will be kept for |
|||
backwards compatibility, but beware! They are buggy! |
|||
|
|||
If you install this addon from scratch, these features are disabled by |
|||
default. |
|||
|
|||
To force enabling or disabling the deprecated features, set a configuration |
|||
parameter called ``module_auto_update.enable_deprecated`` to either ``1`` |
|||
or ``0``. It is recommended that you disable them. |
|||
|
|||
Keep in mind that from this version, all upgrades are assumed to run in a |
|||
separate odoo instance, dedicated exclusively to upgrade Odoo. |
|||
|
|||
* When migrating the addon to new versions, the deprecated features should be |
|||
removed. To make it simple all deprecated features are found in files |
|||
suffixed with ``_deprecated``. |
|||
|
|||
Bug Tracker |
|||
=========== |
|||
|
|||
Bugs are tracked on `GitHub Issues <https://github.com/OCA/server-tools/issues>`_. |
|||
In case of trouble, please check there if your issue has already been reported. |
|||
If you spotted it first, help us smashing it by providing a detailed and welcomed |
|||
`feedback <https://github.com/OCA/server-tools/issues/new?body=module:%20module_auto_update%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**>`_. |
|||
|
|||
Do not contact contributors directly about support or help with technical issues. |
|||
|
|||
Credits |
|||
======= |
|||
|
|||
Authors |
|||
~~~~~~~ |
|||
|
|||
* LasLabs |
|||
* Juan José Scarafía |
|||
* Tecnativa |
|||
* ACSONE SA/NV |
|||
|
|||
Contributors |
|||
~~~~~~~~~~~~ |
|||
|
|||
* Brent Hughes <brent.hughes@laslabs.com> |
|||
* Juan José Scarafía <jjs@adhoc.com.ar> |
|||
* Jairo Llopis <jairo.llopis@tecnativa.com> |
|||
* Stéphane Bidoul <stephane.bidoul@acsone.eu> (https://acsone.eu) |
|||
|
|||
Maintainers |
|||
~~~~~~~~~~~ |
|||
|
|||
This module is maintained by the OCA. |
|||
|
|||
.. image:: https://odoo-community.org/logo.png |
|||
:alt: Odoo Community Association |
|||
:target: https://odoo-community.org |
|||
|
|||
OCA, or the Odoo Community Association, is a nonprofit organization whose |
|||
mission is to support the collaborative development of Odoo features and |
|||
promote its widespread use. |
|||
|
|||
.. |maintainer-sbidoul| image:: https://github.com/sbidoul.png?size=40px |
|||
:target: https://github.com/sbidoul |
|||
:alt: sbidoul |
|||
|
|||
Current `maintainer <https://odoo-community.org/page/maintainer-role>`__: |
|||
|
|||
|maintainer-sbidoul| |
|||
|
|||
This module is part of the `OCA/server-tools <https://github.com/OCA/server-tools/tree/11.0/module_auto_update>`_ project on GitHub. |
|||
|
|||
You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. |
@ -0,0 +1,4 @@ |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
|
|||
from . import models |
|||
from .hooks import uninstall_hook |
@ -0,0 +1,23 @@ |
|||
# Copyright 2017 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
|
|||
{ |
|||
'name': 'Module Auto Update', |
|||
'summary': 'Automatically update Odoo modules', |
|||
'version': '12.0.2.0.4', |
|||
'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', |
|||
], |
|||
'development_status': 'Production/Stable', |
|||
'maintainers': ['sbidoul'], |
|||
} |
@ -0,0 +1,44 @@ |
|||
# Copyright 2018 ACSONE SA/NV. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
|
|||
from fnmatch import fnmatch |
|||
import hashlib |
|||
import os |
|||
|
|||
|
|||
def _fnmatch(filename, patterns): |
|||
for pattern in patterns: |
|||
if fnmatch(filename, pattern): |
|||
return True |
|||
return False |
|||
|
|||
|
|||
def _walk(top, exclude_patterns, 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 = '' |
|||
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'}: |
|||
basename, ext = os.path.splitext(filename) |
|||
if ext == '.po': |
|||
if basename.split('_')[0] not in keep_langs: |
|||
continue |
|||
yield filepath |
|||
|
|||
|
|||
def addon_hash(top, exclude_patterns, keep_langs): |
|||
"""Compute a sha1 digest of file contents.""" |
|||
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')) |
|||
# hash file content |
|||
with open(os.path.join(top, filepath), 'rb') as f: |
|||
m.update(f.read()) |
|||
return m.hexdigest() |
@ -0,0 +1,11 @@ |
|||
# Copyright 2017 LasLabs Inc. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
|
|||
from odoo import SUPERUSER_ID, api |
|||
|
|||
from .models.module import PARAM_INSTALLED_CHECKSUMS |
|||
|
|||
|
|||
def uninstall_hook(cr, registry): |
|||
env = api.Environment(cr, SUPERUSER_ID, {}) |
|||
env["ir.config_parameter"].set_param(PARAM_INSTALLED_CHECKSUMS, False) |
@ -0,0 +1,46 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * module_auto_update |
|||
# |
|||
# Translators: |
|||
# OCA Transbot <transbot@odoo-community.org>, 2017 |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 10.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2017-07-21 02:43+0000\n" |
|||
"PO-Revision-Date: 2017-07-21 02:43+0000\n" |
|||
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
|||
"Language-Team: Catalan (https://www.transifex.com/oca/teams/23907/ca/)\n" |
|||
"Language: ca\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_dir |
|||
msgid "Checksum Dir" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_installed |
|||
msgid "Checksum Installed" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_ir_module_module |
|||
msgid "Module" |
|||
msgstr "Mòdul" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_base_module_upgrade |
|||
msgid "Module Upgrade" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.actions.server,name:module_auto_update.module_check_upgrades_cron_ir_actions_server |
|||
#: model:ir.cron,cron_name:module_auto_update.module_check_upgrades_cron |
|||
#: model:ir.cron,name:module_auto_update.module_check_upgrades_cron |
|||
msgid "Perform Module Upgrades" |
|||
msgstr "" |
@ -0,0 +1,59 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * module_auto_update |
|||
# |
|||
# Translators: |
|||
# Lukáš Spurný <lukasspurny8@gmail.com>, 2018 |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 11.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2018-03-03 10:08+0000\n" |
|||
"PO-Revision-Date: 2018-03-03 10:08+0000\n" |
|||
"Last-Translator: Lukáš Spurný <lukasspurny8@gmail.com>, 2018\n" |
|||
"Language-Team: Czech (Czech Republic) (https://www.transifex.com/oca/" |
|||
"teams/23907/cs_CZ/)\n" |
|||
"Language: cs_CZ\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: nplurals=3; plural=(n==1) ? 0 : (n>=2 && n<=4) ? 1 : 2;\n" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_dir |
|||
msgid "Checksum Dir" |
|||
msgstr "Kontrolní součet Dir" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_installed |
|||
msgid "Checksum Installed" |
|||
msgstr "Kontrolní součet je nainstalován" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_ir_module_module |
|||
msgid "Module" |
|||
msgstr "Modul" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_base_module_upgrade |
|||
msgid "Module Upgrade" |
|||
msgstr "Aktualizace modulů" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.actions.server,name:module_auto_update.module_check_upgrades_cron_ir_actions_server |
|||
#: model:ir.cron,cron_name:module_auto_update.module_check_upgrades_cron |
|||
#: model:ir.cron,name:module_auto_update.module_check_upgrades_cron |
|||
msgid "Perform Module Upgrades" |
|||
msgstr "Provést aktualizaci modulů" |
|||
|
|||
#~ msgid "Modules" |
|||
#~ msgstr "Moduly" |
|||
|
|||
#~ msgid "Open Updates and Update Apps List Server Action" |
|||
#~ msgstr "Otevřít aktualizaci a aktualizovat seznam serverových akcí" |
|||
|
|||
#~ msgid "Scheduled Upgrades" |
|||
#~ msgstr "Plánované aktualizace" |
|||
|
|||
#~ msgid "Updates" |
|||
#~ msgstr "Aktualizace" |
@ -0,0 +1,47 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * module_auto_update |
|||
# |
|||
# Translators: |
|||
# Niki Waibel <niki.waibel@gmail.com>, 2017 |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 10.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2017-07-21 02:43+0000\n" |
|||
"PO-Revision-Date: 2017-07-21 02:43+0000\n" |
|||
"Last-Translator: Niki Waibel <niki.waibel@gmail.com>, 2017\n" |
|||
"Language-Team: German (https://www.transifex.com/oca/teams/23907/de/)\n" |
|||
"Language: de\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_dir |
|||
msgid "Checksum Dir" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_installed |
|||
msgid "Checksum Installed" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_ir_module_module |
|||
msgid "Module" |
|||
msgstr "Modul" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_base_module_upgrade |
|||
msgid "Module Upgrade" |
|||
msgstr "Modul aktualisieren" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.actions.server,name:module_auto_update.module_check_upgrades_cron_ir_actions_server |
|||
#: model:ir.cron,cron_name:module_auto_update.module_check_upgrades_cron |
|||
#: model:ir.cron,name:module_auto_update.module_check_upgrades_cron |
|||
#, fuzzy |
|||
msgid "Perform Module Upgrades" |
|||
msgstr "Modul aktualisieren" |
@ -0,0 +1,56 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * module_auto_update |
|||
# |
|||
# Translators: |
|||
# OCA Transbot <transbot@odoo-community.org>, 2018 |
|||
# enjolras <yo@miguelrevilla.com>, 2018 |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 11.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2018-03-03 10:08+0000\n" |
|||
"PO-Revision-Date: 2018-03-03 10:08+0000\n" |
|||
"Last-Translator: enjolras <yo@miguelrevilla.com>, 2018\n" |
|||
"Language-Team: Spanish (https://www.transifex.com/oca/teams/23907/es/)\n" |
|||
"Language: es\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_dir |
|||
msgid "Checksum Dir" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_installed |
|||
msgid "Checksum Installed" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_ir_module_module |
|||
msgid "Module" |
|||
msgstr "Módulo" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_base_module_upgrade |
|||
msgid "Module Upgrade" |
|||
msgstr "Actualización de módulo" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.actions.server,name:module_auto_update.module_check_upgrades_cron_ir_actions_server |
|||
#: model:ir.cron,cron_name:module_auto_update.module_check_upgrades_cron |
|||
#: model:ir.cron,name:module_auto_update.module_check_upgrades_cron |
|||
msgid "Perform Module Upgrades" |
|||
msgstr "" |
|||
|
|||
#~ msgid "Modules" |
|||
#~ msgstr "Módulos" |
|||
|
|||
#~ msgid "Scheduled Upgrades" |
|||
#~ msgstr "Actualizaciones programadas" |
|||
|
|||
#~ msgid "Updates" |
|||
#~ msgstr "Actualizaciones" |
@ -0,0 +1,47 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * module_auto_update |
|||
# |
|||
# Translators: |
|||
# OCA Transbot <transbot@odoo-community.org>, 2017 |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 10.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2017-07-21 02:43+0000\n" |
|||
"PO-Revision-Date: 2017-07-21 02:43+0000\n" |
|||
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
|||
"Language-Team: Spanish (Mexico) (https://www.transifex.com/oca/teams/23907/" |
|||
"es_MX/)\n" |
|||
"Language: es_MX\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_dir |
|||
msgid "Checksum Dir" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_installed |
|||
msgid "Checksum Installed" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_ir_module_module |
|||
msgid "Module" |
|||
msgstr "Módulo" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_base_module_upgrade |
|||
msgid "Module Upgrade" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.actions.server,name:module_auto_update.module_check_upgrades_cron_ir_actions_server |
|||
#: model:ir.cron,cron_name:module_auto_update.module_check_upgrades_cron |
|||
#: model:ir.cron,name:module_auto_update.module_check_upgrades_cron |
|||
msgid "Perform Module Upgrades" |
|||
msgstr "" |
@ -0,0 +1,58 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * module_auto_update |
|||
# |
|||
# Translators: |
|||
# Nicolas JEUDY <njeudy@panda-chi.io>, 2018 |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 11.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2018-03-03 10:08+0000\n" |
|||
"PO-Revision-Date: 2018-03-03 10:08+0000\n" |
|||
"Last-Translator: Nicolas JEUDY <njeudy@panda-chi.io>, 2018\n" |
|||
"Language-Team: French (https://www.transifex.com/oca/teams/23907/fr/)\n" |
|||
"Language: fr\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: nplurals=2; plural=(n > 1);\n" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_dir |
|||
msgid "Checksum Dir" |
|||
msgstr "Somme de contrôle du dossier" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_installed |
|||
msgid "Checksum Installed" |
|||
msgstr "Somme de contrôle installée" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_ir_module_module |
|||
msgid "Module" |
|||
msgstr "Module" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_base_module_upgrade |
|||
msgid "Module Upgrade" |
|||
msgstr "Mise à niveau du module" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.actions.server,name:module_auto_update.module_check_upgrades_cron_ir_actions_server |
|||
#: model:ir.cron,cron_name:module_auto_update.module_check_upgrades_cron |
|||
#: model:ir.cron,name:module_auto_update.module_check_upgrades_cron |
|||
msgid "Perform Module Upgrades" |
|||
msgstr "Appliquer les mise à jour de modules" |
|||
|
|||
#~ msgid "Modules" |
|||
#~ msgstr "Modules" |
|||
|
|||
#~ msgid "Open Updates and Update Apps List Server Action" |
|||
#~ msgstr "Afficher les mises à jour" |
|||
|
|||
#~ msgid "Scheduled Upgrades" |
|||
#~ msgstr "Planifier les mises à jour" |
|||
|
|||
#~ msgid "Updates" |
|||
#~ msgstr "Mises à jour" |
@ -0,0 +1,47 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * module_auto_update |
|||
# |
|||
# Translators: |
|||
# Bole <bole@dajmi5.com>, 2017 |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 10.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2017-07-21 02:43+0000\n" |
|||
"PO-Revision-Date: 2017-07-21 02:43+0000\n" |
|||
"Last-Translator: Bole <bole@dajmi5.com>, 2017\n" |
|||
"Language-Team: Croatian (https://www.transifex.com/oca/teams/23907/hr/)\n" |
|||
"Language: hr\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: nplurals=3; plural=n%10==1 && n%100!=11 ? 0 : n%10>=2 && n" |
|||
"%10<=4 && (n%100<10 || n%100>=20) ? 1 : 2;\n" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_dir |
|||
msgid "Checksum Dir" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_installed |
|||
msgid "Checksum Installed" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_ir_module_module |
|||
msgid "Module" |
|||
msgstr "Modul" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_base_module_upgrade |
|||
msgid "Module Upgrade" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.actions.server,name:module_auto_update.module_check_upgrades_cron_ir_actions_server |
|||
#: model:ir.cron,cron_name:module_auto_update.module_check_upgrades_cron |
|||
#: model:ir.cron,name:module_auto_update.module_check_upgrades_cron |
|||
msgid "Perform Module Upgrades" |
|||
msgstr "" |
@ -0,0 +1,46 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * module_auto_update |
|||
# |
|||
# Translators: |
|||
# OCA Transbot <transbot@odoo-community.org>, 2017 |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 10.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2017-07-21 02:43+0000\n" |
|||
"PO-Revision-Date: 2017-07-21 02:43+0000\n" |
|||
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
|||
"Language-Team: Italian (https://www.transifex.com/oca/teams/23907/it/)\n" |
|||
"Language: it\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_dir |
|||
msgid "Checksum Dir" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_installed |
|||
msgid "Checksum Installed" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_ir_module_module |
|||
msgid "Module" |
|||
msgstr "Modulo" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_base_module_upgrade |
|||
msgid "Module Upgrade" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.actions.server,name:module_auto_update.module_check_upgrades_cron_ir_actions_server |
|||
#: model:ir.cron,cron_name:module_auto_update.module_check_upgrades_cron |
|||
#: model:ir.cron,name:module_auto_update.module_check_upgrades_cron |
|||
msgid "Perform Module Upgrades" |
|||
msgstr "" |
@ -0,0 +1,42 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * module_auto_update |
|||
# |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 11.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"Last-Translator: <>\n" |
|||
"Language-Team: \n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: \n" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_dir |
|||
msgid "Checksum Dir" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_installed |
|||
msgid "Checksum Installed" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_ir_module_module |
|||
msgid "Module" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_base_module_upgrade |
|||
msgid "Module Upgrade" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.actions.server,name:module_auto_update.module_check_upgrades_cron_ir_actions_server |
|||
#: model:ir.cron,cron_name:module_auto_update.module_check_upgrades_cron |
|||
#: model:ir.cron,name:module_auto_update.module_check_upgrades_cron |
|||
msgid "Perform Module Upgrades" |
|||
msgstr "" |
|||
|
@ -0,0 +1,47 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * module_auto_update |
|||
# |
|||
# Translators: |
|||
# Peter Hageman <hageman.p@gmail.com>, 2017 |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 10.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2017-07-21 02:43+0000\n" |
|||
"PO-Revision-Date: 2017-07-21 02:43+0000\n" |
|||
"Last-Translator: Peter Hageman <hageman.p@gmail.com>, 2017\n" |
|||
"Language-Team: Dutch (Netherlands) (https://www.transifex.com/oca/" |
|||
"teams/23907/nl_NL/)\n" |
|||
"Language: nl_NL\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: nplurals=2; plural=(n != 1);\n" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_dir |
|||
msgid "Checksum Dir" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_installed |
|||
msgid "Checksum Installed" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_ir_module_module |
|||
msgid "Module" |
|||
msgstr "Module" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_base_module_upgrade |
|||
msgid "Module Upgrade" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.actions.server,name:module_auto_update.module_check_upgrades_cron_ir_actions_server |
|||
#: model:ir.cron,cron_name:module_auto_update.module_check_upgrades_cron |
|||
#: model:ir.cron,name:module_auto_update.module_check_upgrades_cron |
|||
msgid "Perform Module Upgrades" |
|||
msgstr "" |
@ -0,0 +1,47 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * module_auto_update |
|||
# |
|||
# Translators: |
|||
# OCA Transbot <transbot@odoo-community.org>, 2017 |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 10.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2017-07-21 02:43+0000\n" |
|||
"PO-Revision-Date: 2017-07-21 02:43+0000\n" |
|||
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
|||
"Language-Team: Portuguese (Brazil) (https://www.transifex.com/oca/" |
|||
"teams/23907/pt_BR/)\n" |
|||
"Language: pt_BR\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: nplurals=2; plural=(n > 1);\n" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_dir |
|||
msgid "Checksum Dir" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_installed |
|||
msgid "Checksum Installed" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_ir_module_module |
|||
msgid "Module" |
|||
msgstr "Módulo" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_base_module_upgrade |
|||
msgid "Module Upgrade" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.actions.server,name:module_auto_update.module_check_upgrades_cron_ir_actions_server |
|||
#: model:ir.cron,cron_name:module_auto_update.module_check_upgrades_cron |
|||
#: model:ir.cron,name:module_auto_update.module_check_upgrades_cron |
|||
msgid "Perform Module Upgrades" |
|||
msgstr "" |
@ -0,0 +1,47 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * module_auto_update |
|||
# |
|||
# Translators: |
|||
# OCA Transbot <transbot@odoo-community.org>, 2017 |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 10.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2017-07-21 02:43+0000\n" |
|||
"PO-Revision-Date: 2017-07-21 02:43+0000\n" |
|||
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
|||
"Language-Team: Slovenian (https://www.transifex.com/oca/teams/23907/sl/)\n" |
|||
"Language: sl\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: nplurals=4; plural=(n%100==1 ? 0 : n%100==2 ? 1 : n%100==3 || n" |
|||
"%100==4 ? 2 : 3);\n" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_dir |
|||
msgid "Checksum Dir" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_installed |
|||
msgid "Checksum Installed" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_ir_module_module |
|||
msgid "Module" |
|||
msgstr "Modul" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_base_module_upgrade |
|||
msgid "Module Upgrade" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.actions.server,name:module_auto_update.module_check_upgrades_cron_ir_actions_server |
|||
#: model:ir.cron,cron_name:module_auto_update.module_check_upgrades_cron |
|||
#: model:ir.cron,name:module_auto_update.module_check_upgrades_cron |
|||
msgid "Perform Module Upgrades" |
|||
msgstr "" |
@ -0,0 +1,46 @@ |
|||
# Translation of Odoo Server. |
|||
# This file contains the translation of the following modules: |
|||
# * module_auto_update |
|||
# |
|||
# Translators: |
|||
# OCA Transbot <transbot@odoo-community.org>, 2017 |
|||
msgid "" |
|||
msgstr "" |
|||
"Project-Id-Version: Odoo Server 10.0\n" |
|||
"Report-Msgid-Bugs-To: \n" |
|||
"POT-Creation-Date: 2017-07-21 02:43+0000\n" |
|||
"PO-Revision-Date: 2017-07-21 02:43+0000\n" |
|||
"Last-Translator: OCA Transbot <transbot@odoo-community.org>, 2017\n" |
|||
"Language-Team: Turkish (https://www.transifex.com/oca/teams/23907/tr/)\n" |
|||
"Language: tr\n" |
|||
"MIME-Version: 1.0\n" |
|||
"Content-Type: text/plain; charset=UTF-8\n" |
|||
"Content-Transfer-Encoding: \n" |
|||
"Plural-Forms: nplurals=2; plural=(n > 1);\n" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_dir |
|||
msgid "Checksum Dir" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model.fields,field_description:module_auto_update.field_ir_module_module_checksum_installed |
|||
msgid "Checksum Installed" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_ir_module_module |
|||
msgid "Module" |
|||
msgstr "Modül" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.model,name:module_auto_update.model_base_module_upgrade |
|||
msgid "Module Upgrade" |
|||
msgstr "" |
|||
|
|||
#. module: module_auto_update |
|||
#: model:ir.actions.server,name:module_auto_update.module_check_upgrades_cron_ir_actions_server |
|||
#: model:ir.cron,cron_name:module_auto_update.module_check_upgrades_cron |
|||
#: model:ir.cron,name:module_auto_update.module_check_upgrades_cron |
|||
msgid "Perform Module Upgrades" |
|||
msgstr "" |
@ -0,0 +1,3 @@ |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
|
|||
from . import module |
@ -0,0 +1,174 @@ |
|||
# Copyright 2017 LasLabs Inc. |
|||
# Copyright 2018 ACSONE SA/NV. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
|
|||
import json |
|||
import logging |
|||
import os |
|||
|
|||
from odoo import api, exceptions, models, tools |
|||
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/*' |
|||
|
|||
_logger = logging.getLogger(__name__) |
|||
|
|||
|
|||
class FailedUpgradeError(exceptions.UserError): |
|||
pass |
|||
|
|||
|
|||
class IncompleteUpgradeError(exceptions.UserError): |
|||
pass |
|||
|
|||
|
|||
def ensure_module_state(env, modules, state): |
|||
# read module states, bypassing any Odoo cache |
|||
if not modules: |
|||
return |
|||
env.cr.execute( |
|||
"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), ), |
|||
) |
|||
|
|||
|
|||
class Module(models.Model): |
|||
_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, |
|||
) |
|||
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, |
|||
) |
|||
else: |
|||
checksum_dir = False |
|||
|
|||
return checksum_dir |
|||
|
|||
@api.model |
|||
def _get_saved_checksums(self): |
|||
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.set_param(PARAM_INSTALLED_CHECKSUMS, json.dumps(checksums)) |
|||
|
|||
@api.model |
|||
def _save_installed_checksums(self): |
|||
checksums = {} |
|||
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')), |
|||
]) |
|||
|
|||
@api.model |
|||
def _get_modules_with_changed_checksum(self): |
|||
saved_checksums = self._get_saved_checksums() |
|||
installed_modules = self.search([('state', '=', 'installed')]) |
|||
return installed_modules.filtered( |
|||
lambda r: r._get_checksum_dir() != saved_checksums.get(r.name), |
|||
) |
|||
|
|||
@api.model |
|||
def upgrade_changed_checksum(self, overwrite_existing_translations=False): |
|||
"""Run an upgrade of the database, upgrading only changed modules. |
|||
|
|||
Installed modules for which the checksum has changed since the |
|||
last successful run of this method are marked "to upgrade", |
|||
then the normal Odoo scheduled upgrade process |
|||
is launched. |
|||
|
|||
If there is no module with a changed checksum, and no module in state |
|||
other than installed, uninstalled, uninstallable, this method does |
|||
nothing, otherwise the normal Odoo upgrade process is launched. |
|||
|
|||
After a successful upgrade, the checksums of installed modules are |
|||
saved. |
|||
|
|||
In case of error during the upgrade, an exception is raised. |
|||
If any module remains to upgrade or to uninstall after the upgrade |
|||
process, an exception is raised as well. |
|||
|
|||
Note: this method commits the current transaction at each important |
|||
step, it is therefore not intended to be run as part of a |
|||
larger transaction. |
|||
""" |
|||
_logger.info( |
|||
"Checksum upgrade starting (i18n-overwrite=%s)...", |
|||
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.") |
|||
return |
|||
_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') |
|||
|
|||
_logger.info("Upgrading...") |
|||
self.env['base.module.upgrade'].upgrade_module() |
|||
self.env.cr.commit() # pylint: disable=invalid-commit |
|||
|
|||
_logger.info("Upgrade successful, updating checksums...") |
|||
self._save_installed_checksums() |
|||
self.env.cr.commit() # pylint: disable=invalid-commit |
|||
|
|||
partial_modules = self._get_modules_partially_installed() |
|||
if partial_modules: |
|||
raise IncompleteUpgradeError( |
|||
"Checksum upgrade successful " |
|||
"but incomplete for the following modules: %s" % |
|||
','.join(partial_modules.mapped('name')) |
|||
) |
|||
|
|||
_logger.info("Checksum upgrade complete.") |
@ -0,0 +1,9 @@ |
|||
This module supports the following system parameters: |
|||
|
|||
* ``module_auto_update.exclude_patterns``: comma-separated list of file |
|||
name patterns to ignore when computing addon checksums. Defaults to |
|||
``*.pyc,*.pyo,i18n/*.pot,i18n_extra/*.pot,static/*``. |
|||
Filename patterns must be compatible with the python ``fnmatch`` function. |
|||
|
|||
In addition to the above pattern, .po files corresponding to languages that |
|||
are not installed in the Odoo database are ignored when computing checksums. |
@ -0,0 +1,4 @@ |
|||
* Brent Hughes <brent.hughes@laslabs.com> |
|||
* Juan José Scarafía <jjs@adhoc.com.ar> |
|||
* Jairo Llopis <jairo.llopis@tecnativa.com> |
|||
* Stéphane Bidoul <stephane.bidoul@acsone.eu> (https://acsone.eu) |
@ -0,0 +1,4 @@ |
|||
This addon provides mechanisms to compute sha1 hashes of installed addons, |
|||
and save them in the database. It also provides a method that exploits these |
|||
mechanisms to update a database by upgrading only the modules for which the |
|||
hash has changed since the last successful upgrade. |
@ -0,0 +1,18 @@ |
|||
The main method provided by this module is ``upgrade_changed_checksum`` |
|||
on ``ir.module.module``. It runs a database upgrade for all installed |
|||
modules for which the hash has changed since the last successful |
|||
run of this method. On success it saves the hashes in the database. |
|||
|
|||
The first time this method is invoked after installing the module, it |
|||
runs an upgrade of all modules, because it has not saved the hashes yet. |
|||
This is by design, priviledging safety. Should this be an issue, |
|||
the method ``_save_installed_checksums`` can be invoked in a situation |
|||
where one is sure all modules on disk are installed and up-to-date in the |
|||
database. |
|||
|
|||
An easy way to invoke this upgrade mechanism is by issuing the following |
|||
in an Odoo shell session: |
|||
|
|||
.. code-block:: python |
|||
|
|||
env['ir.module.module'].upgrade_changed_checksum() |
@ -0,0 +1,483 @@ |
|||
<?xml version="1.0" encoding="utf-8" ?> |
|||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> |
|||
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en"> |
|||
<head> |
|||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> |
|||
<meta name="generator" content="Docutils 0.14: http://docutils.sourceforge.net/" /> |
|||
<title>Module Auto Update</title> |
|||
<style type="text/css"> |
|||
|
|||
/* |
|||
:Author: David Goodger (goodger@python.org) |
|||
:Id: $Id: html4css1.css 7952 2016-07-26 18:15:59Z milde $ |
|||
:Copyright: This stylesheet has been placed in the public domain. |
|||
|
|||
Default cascading style sheet for the HTML output of Docutils. |
|||
|
|||
See http://docutils.sf.net/docs/howto/html-stylesheets.html for how to |
|||
customize this style sheet. |
|||
*/ |
|||
|
|||
/* used to remove borders from tables and images */ |
|||
.borderless, table.borderless td, table.borderless th { |
|||
border: 0 } |
|||
|
|||
table.borderless td, table.borderless th { |
|||
/* Override padding for "table.docutils td" with "! important". |
|||
The right padding separates the table cells. */ |
|||
padding: 0 0.5em 0 0 ! important } |
|||
|
|||
.first { |
|||
/* Override more specific margin styles with "! important". */ |
|||
margin-top: 0 ! important } |
|||
|
|||
.last, .with-subtitle { |
|||
margin-bottom: 0 ! important } |
|||
|
|||
.hidden { |
|||
display: none } |
|||
|
|||
.subscript { |
|||
vertical-align: sub; |
|||
font-size: smaller } |
|||
|
|||
.superscript { |
|||
vertical-align: super; |
|||
font-size: smaller } |
|||
|
|||
a.toc-backref { |
|||
text-decoration: none ; |
|||
color: black } |
|||
|
|||
blockquote.epigraph { |
|||
margin: 2em 5em ; } |
|||
|
|||
dl.docutils dd { |
|||
margin-bottom: 0.5em } |
|||
|
|||
object[type="image/svg+xml"], object[type="application/x-shockwave-flash"] { |
|||
overflow: hidden; |
|||
} |
|||
|
|||
/* Uncomment (and remove this text!) to get bold-faced definition list terms |
|||
dl.docutils dt { |
|||
font-weight: bold } |
|||
*/ |
|||
|
|||
div.abstract { |
|||
margin: 2em 5em } |
|||
|
|||
div.abstract p.topic-title { |
|||
font-weight: bold ; |
|||
text-align: center } |
|||
|
|||
div.admonition, div.attention, div.caution, div.danger, div.error, |
|||
div.hint, div.important, div.note, div.tip, div.warning { |
|||
margin: 2em ; |
|||
border: medium outset ; |
|||
padding: 1em } |
|||
|
|||
div.admonition p.admonition-title, div.hint p.admonition-title, |
|||
div.important p.admonition-title, div.note p.admonition-title, |
|||
div.tip p.admonition-title { |
|||
font-weight: bold ; |
|||
font-family: sans-serif } |
|||
|
|||
div.attention p.admonition-title, div.caution p.admonition-title, |
|||
div.danger p.admonition-title, div.error p.admonition-title, |
|||
div.warning p.admonition-title, .code .error { |
|||
color: red ; |
|||
font-weight: bold ; |
|||
font-family: sans-serif } |
|||
|
|||
/* Uncomment (and remove this text!) to get reduced vertical space in |
|||
compound paragraphs. |
|||
div.compound .compound-first, div.compound .compound-middle { |
|||
margin-bottom: 0.5em } |
|||
|
|||
div.compound .compound-last, div.compound .compound-middle { |
|||
margin-top: 0.5em } |
|||
*/ |
|||
|
|||
div.dedication { |
|||
margin: 2em 5em ; |
|||
text-align: center ; |
|||
font-style: italic } |
|||
|
|||
div.dedication p.topic-title { |
|||
font-weight: bold ; |
|||
font-style: normal } |
|||
|
|||
div.figure { |
|||
margin-left: 2em ; |
|||
margin-right: 2em } |
|||
|
|||
div.footer, div.header { |
|||
clear: both; |
|||
font-size: smaller } |
|||
|
|||
div.line-block { |
|||
display: block ; |
|||
margin-top: 1em ; |
|||
margin-bottom: 1em } |
|||
|
|||
div.line-block div.line-block { |
|||
margin-top: 0 ; |
|||
margin-bottom: 0 ; |
|||
margin-left: 1.5em } |
|||
|
|||
div.sidebar { |
|||
margin: 0 0 0.5em 1em ; |
|||
border: medium outset ; |
|||
padding: 1em ; |
|||
background-color: #ffffee ; |
|||
width: 40% ; |
|||
float: right ; |
|||
clear: right } |
|||
|
|||
div.sidebar p.rubric { |
|||
font-family: sans-serif ; |
|||
font-size: medium } |
|||
|
|||
div.system-messages { |
|||
margin: 5em } |
|||
|
|||
div.system-messages h1 { |
|||
color: red } |
|||
|
|||
div.system-message { |
|||
border: medium outset ; |
|||
padding: 1em } |
|||
|
|||
div.system-message p.system-message-title { |
|||
color: red ; |
|||
font-weight: bold } |
|||
|
|||
div.topic { |
|||
margin: 2em } |
|||
|
|||
h1.section-subtitle, h2.section-subtitle, h3.section-subtitle, |
|||
h4.section-subtitle, h5.section-subtitle, h6.section-subtitle { |
|||
margin-top: 0.4em } |
|||
|
|||
h1.title { |
|||
text-align: center } |
|||
|
|||
h2.subtitle { |
|||
text-align: center } |
|||
|
|||
hr.docutils { |
|||
width: 75% } |
|||
|
|||
img.align-left, .figure.align-left, object.align-left, table.align-left { |
|||
clear: left ; |
|||
float: left ; |
|||
margin-right: 1em } |
|||
|
|||
img.align-right, .figure.align-right, object.align-right, table.align-right { |
|||
clear: right ; |
|||
float: right ; |
|||
margin-left: 1em } |
|||
|
|||
img.align-center, .figure.align-center, object.align-center { |
|||
display: block; |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
} |
|||
|
|||
table.align-center { |
|||
margin-left: auto; |
|||
margin-right: auto; |
|||
} |
|||
|
|||
.align-left { |
|||
text-align: left } |
|||
|
|||
.align-center { |
|||
clear: both ; |
|||
text-align: center } |
|||
|
|||
.align-right { |
|||
text-align: right } |
|||
|
|||
/* reset inner alignment in figures */ |
|||
div.align-right { |
|||
text-align: inherit } |
|||
|
|||
/* div.align-center * { */ |
|||
/* text-align: left } */ |
|||
|
|||
.align-top { |
|||
vertical-align: top } |
|||
|
|||
.align-middle { |
|||
vertical-align: middle } |
|||
|
|||
.align-bottom { |
|||
vertical-align: bottom } |
|||
|
|||
ol.simple, ul.simple { |
|||
margin-bottom: 1em } |
|||
|
|||
ol.arabic { |
|||
list-style: decimal } |
|||
|
|||
ol.loweralpha { |
|||
list-style: lower-alpha } |
|||
|
|||
ol.upperalpha { |
|||
list-style: upper-alpha } |
|||
|
|||
ol.lowerroman { |
|||
list-style: lower-roman } |
|||
|
|||
ol.upperroman { |
|||
list-style: upper-roman } |
|||
|
|||
p.attribution { |
|||
text-align: right ; |
|||
margin-left: 50% } |
|||
|
|||
p.caption { |
|||
font-style: italic } |
|||
|
|||
p.credits { |
|||
font-style: italic ; |
|||
font-size: smaller } |
|||
|
|||
p.label { |
|||
white-space: nowrap } |
|||
|
|||
p.rubric { |
|||
font-weight: bold ; |
|||
font-size: larger ; |
|||
color: maroon ; |
|||
text-align: center } |
|||
|
|||
p.sidebar-title { |
|||
font-family: sans-serif ; |
|||
font-weight: bold ; |
|||
font-size: larger } |
|||
|
|||
p.sidebar-subtitle { |
|||
font-family: sans-serif ; |
|||
font-weight: bold } |
|||
|
|||
p.topic-title { |
|||
font-weight: bold } |
|||
|
|||
pre.address { |
|||
margin-bottom: 0 ; |
|||
margin-top: 0 ; |
|||
font: inherit } |
|||
|
|||
pre.literal-block, pre.doctest-block, pre.math, pre.code { |
|||
margin-left: 2em ; |
|||
margin-right: 2em } |
|||
|
|||
pre.code .ln { color: grey; } /* line numbers */ |
|||
pre.code, code { background-color: #eeeeee } |
|||
pre.code .comment, code .comment { color: #5C6576 } |
|||
pre.code .keyword, code .keyword { color: #3B0D06; font-weight: bold } |
|||
pre.code .literal.string, code .literal.string { color: #0C5404 } |
|||
pre.code .name.builtin, code .name.builtin { color: #352B84 } |
|||
pre.code .deleted, code .deleted { background-color: #DEB0A1} |
|||
pre.code .inserted, code .inserted { background-color: #A3D289} |
|||
|
|||
span.classifier { |
|||
font-family: sans-serif ; |
|||
font-style: oblique } |
|||
|
|||
span.classifier-delimiter { |
|||
font-family: sans-serif ; |
|||
font-weight: bold } |
|||
|
|||
span.interpreted { |
|||
font-family: sans-serif } |
|||
|
|||
span.option { |
|||
white-space: nowrap } |
|||
|
|||
span.pre { |
|||
white-space: pre } |
|||
|
|||
span.problematic { |
|||
color: red } |
|||
|
|||
span.section-subtitle { |
|||
/* font-size relative to parent (h1..h6 element) */ |
|||
font-size: 80% } |
|||
|
|||
table.citation { |
|||
border-left: solid 1px gray; |
|||
margin-left: 1px } |
|||
|
|||
table.docinfo { |
|||
margin: 2em 4em } |
|||
|
|||
table.docutils { |
|||
margin-top: 0.5em ; |
|||
margin-bottom: 0.5em } |
|||
|
|||
table.footnote { |
|||
border-left: solid 1px black; |
|||
margin-left: 1px } |
|||
|
|||
table.docutils td, table.docutils th, |
|||
table.docinfo td, table.docinfo th { |
|||
padding-left: 0.5em ; |
|||
padding-right: 0.5em ; |
|||
vertical-align: top } |
|||
|
|||
table.docutils th.field-name, table.docinfo th.docinfo-name { |
|||
font-weight: bold ; |
|||
text-align: left ; |
|||
white-space: nowrap ; |
|||
padding-left: 0 } |
|||
|
|||
/* "booktabs" style (no vertical lines) */ |
|||
table.docutils.booktabs { |
|||
border: 0px; |
|||
border-top: 2px solid; |
|||
border-bottom: 2px solid; |
|||
border-collapse: collapse; |
|||
} |
|||
table.docutils.booktabs * { |
|||
border: 0px; |
|||
} |
|||
table.docutils.booktabs th { |
|||
border-bottom: thin solid; |
|||
text-align: left; |
|||
} |
|||
|
|||
h1 tt.docutils, h2 tt.docutils, h3 tt.docutils, |
|||
h4 tt.docutils, h5 tt.docutils, h6 tt.docutils { |
|||
font-size: 100% } |
|||
|
|||
ul.auto-toc { |
|||
list-style-type: none } |
|||
|
|||
</style> |
|||
</head> |
|||
<body> |
|||
<div class="document" id="module-auto-update"> |
|||
<h1 class="title">Module Auto Update</h1> |
|||
|
|||
<!-- !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! |
|||
!! This file is generated by oca-gen-addon-readme !! |
|||
!! changes will be overwritten. !! |
|||
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> |
|||
<p><a class="reference external" href="https://odoo-community.org/page/development-status"><img alt="Production/Stable" src="https://img.shields.io/badge/maturity-Production%2FStable-green.png" /></a> <a class="reference external" href="http://www.gnu.org/licenses/lgpl-3.0-standalone.html"><img alt="License: LGPL-3" src="https://img.shields.io/badge/licence-LGPL--3-blue.png" /></a> <a class="reference external" href="https://github.com/OCA/server-tools/tree/11.0/module_auto_update"><img alt="OCA/server-tools" src="https://img.shields.io/badge/github-OCA%2Fserver--tools-lightgray.png?logo=github" /></a> <a class="reference external" href="https://translation.odoo-community.org/projects/server-tools-11-0/server-tools-11-0-module_auto_update"><img alt="Translate me on Weblate" src="https://img.shields.io/badge/weblate-Translate%20me-F47D42.png" /></a> <a class="reference external" href="https://runbot.odoo-community.org/runbot/149/11.0"><img alt="Try me on Runbot" src="https://img.shields.io/badge/runbot-Try%20me-875A7B.png" /></a></p> |
|||
<p>This addon provides mechanisms to compute sha1 hashes of installed addons, |
|||
and save them in the database. It also provides a method that exploits these |
|||
mechanisms to update a database by upgrading only the modules for which the |
|||
hash has changed since the last successful upgrade.</p> |
|||
<p><strong>Table of contents</strong></p> |
|||
<div class="contents local topic" id="contents"> |
|||
<ul class="simple"> |
|||
<li><a class="reference internal" href="#configuration" id="id1">Configuration</a></li> |
|||
<li><a class="reference internal" href="#usage" id="id2">Usage</a></li> |
|||
<li><a class="reference internal" href="#known-issues-roadmap" id="id3">Known issues / Roadmap</a></li> |
|||
<li><a class="reference internal" href="#bug-tracker" id="id4">Bug Tracker</a></li> |
|||
<li><a class="reference internal" href="#credits" id="id5">Credits</a><ul> |
|||
<li><a class="reference internal" href="#authors" id="id6">Authors</a></li> |
|||
<li><a class="reference internal" href="#contributors" id="id7">Contributors</a></li> |
|||
<li><a class="reference internal" href="#maintainers" id="id8">Maintainers</a></li> |
|||
</ul> |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
<div class="section" id="configuration"> |
|||
<h1><a class="toc-backref" href="#id1">Configuration</a></h1> |
|||
<p>This module supports the following system parameters:</p> |
|||
<ul class="simple"> |
|||
<li><tt class="docutils literal">module_auto_update.exclude_patterns</tt>: comma-separated list of file |
|||
name patterns to ignore when computing addon checksums. Defaults to |
|||
<tt class="docutils literal"><span class="pre">*.pyc,*.pyo,i18n/*.pot,i18n_extra/*.pot,static/*</span></tt>. |
|||
Filename patterns must be compatible with the python <tt class="docutils literal">fnmatch</tt> function.</li> |
|||
</ul> |
|||
<p>In addition to the above pattern, .po files corresponding to languages that |
|||
are not installed in the Odoo database are ignored when computing checksums.</p> |
|||
</div> |
|||
<div class="section" id="usage"> |
|||
<h1><a class="toc-backref" href="#id2">Usage</a></h1> |
|||
<p>The main method provided by this module is <tt class="docutils literal">upgrade_changed_checksum</tt> |
|||
on <tt class="docutils literal">ir.module.module</tt>. It runs a database upgrade for all installed |
|||
modules for which the hash has changed since the last successful |
|||
run of this method. On success it saves the hashes in the database.</p> |
|||
<p>The first time this method is invoked after installing the module, it |
|||
runs an upgrade of all modules, because it has not saved the hashes yet. |
|||
This is by design, priviledging safety. Should this be an issue, |
|||
the method <tt class="docutils literal">_save_installed_checksums</tt> can be invoked in a situation |
|||
where one is sure all modules on disk are installed and up-to-date in the |
|||
database.</p> |
|||
<p>An easy way to invoke this upgrade mechanism is by issuing the following |
|||
in an Odoo shell session:</p> |
|||
<pre class="literal-block"> |
|||
env['ir.module.module'].upgrade_changed_checksum() |
|||
</pre> |
|||
</div> |
|||
<div class="section" id="known-issues-roadmap"> |
|||
<h1><a class="toc-backref" href="#id3">Known issues / Roadmap</a></h1> |
|||
<ul> |
|||
<li><p class="first">Since version <tt class="docutils literal">2.0.0</tt>, some features have been deprecated. |
|||
When you upgrade from previous versions, these features will be kept for |
|||
backwards compatibility, but beware! They are buggy!</p> |
|||
<p>If you install this addon from scratch, these features are disabled by |
|||
default.</p> |
|||
<p>To force enabling or disabling the deprecated features, set a configuration |
|||
parameter called <tt class="docutils literal">module_auto_update.enable_deprecated</tt> to either <tt class="docutils literal">1</tt> |
|||
or <tt class="docutils literal">0</tt>. It is recommended that you disable them.</p> |
|||
<p>Keep in mind that from this version, all upgrades are assumed to run in a |
|||
separate odoo instance, dedicated exclusively to upgrade Odoo.</p> |
|||
</li> |
|||
<li><p class="first">When migrating the addon to new versions, the deprecated features should be |
|||
removed. To make it simple all deprecated features are found in files |
|||
suffixed with <tt class="docutils literal">_deprecated</tt>.</p> |
|||
</li> |
|||
</ul> |
|||
</div> |
|||
<div class="section" id="bug-tracker"> |
|||
<h1><a class="toc-backref" href="#id4">Bug Tracker</a></h1> |
|||
<p>Bugs are tracked on <a class="reference external" href="https://github.com/OCA/server-tools/issues">GitHub Issues</a>. |
|||
In case of trouble, please check there if your issue has already been reported. |
|||
If you spotted it first, help us smashing it by providing a detailed and welcomed |
|||
<a class="reference external" href="https://github.com/OCA/server-tools/issues/new?body=module:%20module_auto_update%0Aversion:%2011.0%0A%0A**Steps%20to%20reproduce**%0A-%20...%0A%0A**Current%20behavior**%0A%0A**Expected%20behavior**">feedback</a>.</p> |
|||
<p>Do not contact contributors directly about support or help with technical issues.</p> |
|||
</div> |
|||
<div class="section" id="credits"> |
|||
<h1><a class="toc-backref" href="#id5">Credits</a></h1> |
|||
<div class="section" id="authors"> |
|||
<h2><a class="toc-backref" href="#id6">Authors</a></h2> |
|||
<ul class="simple"> |
|||
<li>LasLabs</li> |
|||
<li>Juan José Scarafía</li> |
|||
<li>Tecnativa</li> |
|||
<li>ACSONE SA/NV</li> |
|||
</ul> |
|||
</div> |
|||
<div class="section" id="contributors"> |
|||
<h2><a class="toc-backref" href="#id7">Contributors</a></h2> |
|||
<ul class="simple"> |
|||
<li>Brent Hughes <<a class="reference external" href="mailto:brent.hughes@laslabs.com">brent.hughes@laslabs.com</a>></li> |
|||
<li>Juan José Scarafía <<a class="reference external" href="mailto:jjs@adhoc.com.ar">jjs@adhoc.com.ar</a>></li> |
|||
<li>Jairo Llopis <<a class="reference external" href="mailto:jairo.llopis@tecnativa.com">jairo.llopis@tecnativa.com</a>></li> |
|||
<li>Stéphane Bidoul <<a class="reference external" href="mailto:stephane.bidoul@acsone.eu">stephane.bidoul@acsone.eu</a>> (<a class="reference external" href="https://acsone.eu">https://acsone.eu</a>)</li> |
|||
</ul> |
|||
</div> |
|||
<div class="section" id="maintainers"> |
|||
<h2><a class="toc-backref" href="#id8">Maintainers</a></h2> |
|||
<p>This module is maintained by the OCA.</p> |
|||
<a class="reference external image-reference" href="https://odoo-community.org"><img alt="Odoo Community Association" src="https://odoo-community.org/logo.png" /></a> |
|||
<p>OCA, or the Odoo Community Association, is a nonprofit organization whose |
|||
mission is to support the collaborative development of Odoo features and |
|||
promote its widespread use.</p> |
|||
<p>Current <a class="reference external" href="https://odoo-community.org/page/maintainer-role">maintainer</a>:</p> |
|||
<p><a class="reference external" href="https://github.com/sbidoul"><img alt="sbidoul" src="https://github.com/sbidoul.png?size=40px" /></a></p> |
|||
<p>This module is part of the <a class="reference external" href="https://github.com/OCA/server-tools/tree/11.0/module_auto_update">OCA/server-tools</a> project on GitHub.</p> |
|||
<p>You are welcome to contribute. To learn how please visit <a class="reference external" href="https://odoo-community.org/page/Contribute">https://odoo-community.org/page/Contribute</a>.</p> |
|||
</div> |
|||
</div> |
|||
</div> |
|||
</body> |
|||
</html> |
@ -0,0 +1,4 @@ |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
|
|||
from . import test_addon_hash |
|||
from . import test_module |
@ -0,0 +1 @@ |
|||
Test data for addon_hash module. |
@ -0,0 +1 @@ |
|||
<odoo/> |
@ -0,0 +1 @@ |
|||
<odoo/> |
@ -0,0 +1 @@ |
|||
en text |
@ -0,0 +1 @@ |
|||
en_US |
@ -0,0 +1 @@ |
|||
fr |
@ -0,0 +1 @@ |
|||
fr_BE |
@ -0,0 +1 @@ |
|||
... |
@ -0,0 +1 @@ |
|||
en |
@ -0,0 +1 @@ |
|||
fr |
@ -0,0 +1 @@ |
|||
nl_NL |
@ -0,0 +1 @@ |
|||
1+1 |
@ -0,0 +1 @@ |
|||
/* Javascript */ |
@ -0,0 +1,67 @@ |
|||
# Copyright 2018 ACSONE SA/NV. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
|
|||
import os |
|||
import unittest |
|||
|
|||
from .. import addon_hash |
|||
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', |
|||
) |
|||
|
|||
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', |
|||
]) |
|||
|
|||
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', |
|||
]) |
|||
|
|||
def test2(self): |
|||
checksum = addon_hash.addon_hash( |
|||
self.sample_dir, |
|||
exclude_patterns=['*.pyc', '*.pyo', '*.pot', 'static/*'], |
|||
keep_langs=['fr_FR', 'nl'], |
|||
) |
|||
self.assertEqual(checksum, 'fecb89486c8a29d1f760cbd01c1950f6e8421b14') |
@ -0,0 +1,237 @@ |
|||
# Copyright 2017 LasLabs Inc. |
|||
# Copyright 2018 ACSONE SA/NV. |
|||
# License LGPL-3.0 or later (http://www.gnu.org/licenses/lgpl). |
|||
|
|||
import os |
|||
import tempfile |
|||
|
|||
import mock |
|||
|
|||
import odoo |
|||
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 |
|||
|
|||
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_dir_path = get_module_path(MODULE_NAME) |
|||
keep_langs = self.env['res.lang'].search([]).mapped('code') |
|||
self.own_checksum = addon_hash( |
|||
self.own_dir_path, |
|||
exclude_patterns=DEFAULT_EXCLUDE_PATTERNS.split(','), |
|||
keep_langs=keep_langs, |
|||
) |
|||
self.own_writeable = os.access(self.own_dir_path, os.W_OK) |
|||
|
|||
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', |
|||
) |
|||
|
|||
def test_compute_checksum_dir_ignore_excluded(self): |
|||
"""It should exclude .pyc/.pyo extensions from checksum |
|||
calculations""" |
|||
if not self.own_writeable: |
|||
self.skipTest("Own directory not writeable") |
|||
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', |
|||
) |
|||
|
|||
def test_compute_checksum_dir_recomputes_when_file_added(self): |
|||
"""It should return a different value when a non-.pyc/.pyo file is |
|||
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): |
|||
self.assertNotEqual( |
|||
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') |
|||
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']) |
|||
|
|||
def test_get_modules_with_changed_checksum(self): |
|||
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') |
|||
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')]) |
|||
|
|||
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()) |
|||
self.own_module.button_upgrade() |
|||
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()) |
|||
|
|||
def test_upgrade_changed_checksum(self): |
|||
Imm = self.env['ir.module.module'] |
|||
Bmu = self.env['base.module.upgrade'] |
|||
|
|||
# check modules are in installed state |
|||
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 |
|||
Imm._save_checksums(saved_checksums) |
|||
changed_modules = Imm._get_modules_with_changed_checksum() |
|||
self.assertEqual(len(changed_modules), 1) |
|||
self.assertTrue(self.base_module in changed_modules) |
|||
|
|||
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'}) |
|||
|
|||
upgrade_module_mock.call_count = 0 |
|||
|
|||
# upgrade_changed_checksum commits, so mock that |
|||
with mock.patch.object(self.env.cr, 'commit'): |
|||
|
|||
# we simulate an install by setting module states |
|||
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') |
|||
saved_checksums = Imm._get_saved_checksums() |
|||
self.assertTrue(saved_checksums['base']) |
|||
self.assertTrue(saved_checksums[MODULE_NAME]) |
|||
finally: |
|||
Bmu._revert_method('upgrade_module') |
|||
|
|||
def test_incomplete_upgrade(self): |
|||
Imm = self.env['ir.module.module'] |
|||
Bmu = self.env['base.module.upgrade'] |
|||
|
|||
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 |
|||
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'}) |
|||
# simulate partial 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'): |
|||
|
|||
# we simulate an install by setting module states |
|||
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') |
|||
|
|||
def test_incomplete_upgrade_no_checkusm(self): |
|||
Imm = self.env['ir.module.module'] |
|||
Bmu = self.env['base.module.upgrade'] |
|||
|
|||
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'}) |
|||
|
|||
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'}) |
|||
|
|||
upgrade_module_mock.call_count = 0 |
|||
|
|||
# upgrade_changed_checksum commits, so mock that |
|||
with mock.patch.object(self.env.cr, 'commit'): |
|||
|
|||
# we simulate an install by setting module states |
|||
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') |
|||
|
|||
def test_nothing_to_upgrade(self): |
|||
Imm = self.env['ir.module.module'] |
|||
Bmu = self.env['base.module.upgrade'] |
|||
|
|||
Imm._save_installed_checksums() |
|||
|
|||
def upgrade_module_mock(self_model): |
|||
upgrade_module_mock.call_count += 1 |
|||
|
|||
upgrade_module_mock.call_count = 0 |
|||
|
|||
# upgrade_changed_checksum commits, so mock that |
|||
with mock.patch.object(self.env.cr, 'commit'): |
|||
|
|||
# we simulate an install by setting module states |
|||
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') |
@ -0,0 +1 @@ |
|||
../../../../module_auto_update |
@ -0,0 +1,6 @@ |
|||
import setuptools |
|||
|
|||
setuptools.setup( |
|||
setup_requires=['setuptools-odoo'], |
|||
odoo_addon=True, |
|||
) |
Write
Preview
Loading…
Cancel
Save
Reference in new issue