summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--odoo/__init__.py1
-rw-r--r--odoo/modules/migration.py10
-rw-r--r--odoo/modules/module.py23
-rw-r--r--odoo/tools/config.py23
-rw-r--r--odoo/upgrades.py24
-rw-r--r--odoo/upgrades/__init__.py6
6 files changed, 48 insertions, 39 deletions
diff --git a/odoo/__init__.py b/odoo/__init__.py
index 8eb764a712d..804db5d937c 100644
--- a/odoo/__init__.py
+++ b/odoo/__init__.py
@@ -106,6 +106,7 @@ def registry(database_name=None):
#----------------------------------------------------------
# Imports
#----------------------------------------------------------
+from . import upgrades # this namespace must be imported first
from . import addons
from . import conf
from . import loglevels
diff --git a/odoo/modules/migration.py b/odoo/modules/migration.py
index 8faf8735a8d..f1b00a6def7 100644
--- a/odoo/modules/migration.py
+++ b/odoo/modules/migration.py
@@ -12,7 +12,7 @@ from os.path import join as opj
from odoo.modules.module import get_resource_path
import odoo.release as release
-import odoo.tools as tools
+import odoo.upgrades
from odoo.tools.parse_version import parse_version
_logger = logging.getLogger(__name__)
@@ -63,7 +63,7 @@ class MigrationManager(object):
def _get_files(self):
def _get_upgrades_paths(pkg):
- for path in tools.config['upgrades_paths'].split(','):
+ for path in odoo.upgrades.__path__:
upgrade_path = opj(path, pkg)
if os.path.exists(upgrade_path):
return upgrade_path
@@ -86,8 +86,6 @@ class MigrationManager(object):
self.migrations[pkg.name] = {
'module': get_scripts(get_resource_path(pkg.name, 'migrations')),
'module_upgrades': get_scripts(get_resource_path(pkg.name, 'upgrades')),
- 'maintenance': get_scripts(get_resource_path('base', 'maintenance', 'migrations', pkg.name)),
- 'maintenance_upgrades': get_scripts(get_resource_path('base', 'maintenance', 'upgrades', pkg.name)),
'upgrades': get_scripts(_get_upgrades_paths(pkg.name)),
}
@@ -133,11 +131,9 @@ class MigrationManager(object):
mapping = {
'module': opj(pkg.name, 'migrations'),
'module_upgrades': opj(pkg.name, 'upgrades'),
- 'maintenance': opj('base', 'maintenance', 'migrations', pkg.name),
- 'maintenance_upgrades': opj('base', 'maintenance', 'upgrades', pkg.name),
}
- for path in tools.config['upgrades_paths'].split(','):
+ for path in odoo.upgrades.__path__:
if os.path.exists(opj(path, pkg.name)):
mapping['upgrades'] = opj(path, pkg.name)
break
diff --git a/odoo/modules/module.py b/odoo/modules/module.py
index 851395ba280..dd8fde100f2 100644
--- a/odoo/modules/module.py
+++ b/odoo/modules/module.py
@@ -39,20 +39,41 @@ def initialize_sys_path():
and explicit directories.
"""
+ # hook odoo.addons on data dir
dd = os.path.normcase(tools.config.addons_data_dir)
if os.access(dd, os.R_OK) and dd not in odoo.addons.__path__:
odoo.addons.__path__.append(dd)
+ # hook odoo.addons on addons paths
for ad in tools.config['addons_path'].split(','):
ad = os.path.normcase(os.path.abspath(tools.ustr(ad.strip())))
if ad not in odoo.addons.__path__:
odoo.addons.__path__.append(ad)
- # add base module path
+ # hook odoo.addons on base module path
base_path = os.path.normcase(os.path.abspath(os.path.join(os.path.dirname(os.path.dirname(__file__)), 'addons')))
if base_path not in odoo.addons.__path__ and os.path.isdir(base_path):
odoo.addons.__path__.append(base_path)
+ # hook odoo.upgrades on upgrades paths
+ from odoo import upgrades
+ for up in tools.config['upgrades_paths'].split(','):
+ up = os.path.normcase(os.path.abspath(tools.ustr(up.strip())))
+ if up not in upgrades.__path__:
+ upgrades.__path__.append(up)
+
+ # hook odoo.upgrades on legacy odoo/addons/base/maintenance/migrations symlink
+ if not tools.config['upgrades_paths']:
+ upgrades.__path__.append(os.path.join(
+ base_path, 'base', 'maintenance', 'migrations'))
+
+ # create decrecated module alias from odoo.addons.base.maintenance.migrations to odoo.upgrades
+ spec = importlib.machinery.ModuleSpec("odoo.addons.base.maintenance", None, is_package=True)
+ maintenance_pkg = importlib.util.module_from_spec(spec)
+ maintenance_pkg.migrations = upgrades
+ sys.modules["odoo.addons.base.maintenance"] = maintenance_pkg
+ sys.modules["odoo.addons.base.maintenance.migrations"] = upgrades
+
def get_module_path(module, downloaded=False, display_warning=True):
"""Return the path of the given module.
diff --git a/odoo/tools/config.py b/odoo/tools/config.py
index 194da756ef8..81d1f448f7e 100644
--- a/odoo/tools/config.py
+++ b/odoo/tools/config.py
@@ -9,10 +9,12 @@ except ImportError:
import errno
import logging
import optparse
+import glob
import os
import sys
import tempfile
import odoo
+from os.path import expandvars, expanduser, abspath, realpath
from .. import release, conf, loglevels
from . import appdirs
@@ -488,7 +490,7 @@ class configmanager(object):
self._normalize(x)
for x in self.options['addons_path'].split(','))
- self.options['upgrades_paths'] = (
+ self.options["upgrades_paths"] = (
",".join(self._normalize(x)
for x in self.options['upgrades_paths'].split(','))
if self.options['upgrades_paths']
@@ -546,7 +548,7 @@ class configmanager(object):
if not os.path.isdir(res):
raise optparse.OptionValueError("option %s: no such directory: %r" % (opt, path))
if not self._is_addons_path(res):
- raise optparse.OptionValueError("option %s: The addons-path %r does not seem to a be a valid Addons Directory!" % (opt, path))
+ raise optparse.OptionValueError("option %s: the path %r is not a valid addons directory" % (opt, path))
ad_paths.append(res)
setattr(parser.values, option.dest, ",".join(ad_paths))
@@ -558,9 +560,18 @@ class configmanager(object):
res = self._normalize(path)
if not os.path.isdir(res):
raise optparse.OptionValueError("option %s: no such directory: %r" % (opt, path))
- upgrades_paths.append(res)
+ if not self._is_upgrades_path(res):
+ raise optparse.OptionValueError("option %s: the path %r is not a valid upgrade directory" % (opt, path))
+ if res not in upgrades_paths:
+ upgrades_paths.append(res)
setattr(parser.values, option.dest, ",".join(upgrades_paths))
+ def _is_upgrades_path(self, res):
+ return any(
+ glob.glob(os.path.join(res, f"*/*/{prefix}-*.py"))
+ for prefix in ["pre", "post", "end"]
+ )
+
def _test_enable_callback(self, option, opt, value, parser):
if not parser.values.test_tags:
parser.values.test_tags = "+standard"
@@ -700,9 +711,7 @@ class configmanager(object):
def _normalize(self, path):
if not path:
return path
- return os.path.abspath(
- os.path.expanduser(
- os.path.expandvars(
- path.strip())))
+ return realpath(abspath(expanduser(expandvars(path.strip()))))
+
config = configmanager()
diff --git a/odoo/upgrades.py b/odoo/upgrades.py
deleted file mode 100644
index c83dae7b2e5..00000000000
--- a/odoo/upgrades.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# -*- coding: utf-8 -*-
-import importlib.util
-import os
-import sys
-
-from odoo.tools import config
-from odoo.modules.module import get_resource_path
-
-for path in config.get("upgrades_paths", "").split(","):
- if os.path.exists(os.path.join(path, "__init__.py")):
- break
-else:
- # failback to legacy "maintenance/migrations" package
- path = get_resource_path("base", "maintenance", "migrations")
-
-if not path:
- raise ImportError("No package found in `upgrades_paths`")
-
-spec = importlib.util.spec_from_file_location("odoo.upgrades", os.path.join(path, "__init__.py"))
-module = importlib.util.module_from_spec(spec)
-spec.loader.exec_module(module)
-
-# shadow module and register under legacy name
-sys.modules["odoo.upgrades"] = sys.modules["odoo.addons.base.maintenance.migrations"] = module
diff --git a/odoo/upgrades/__init__.py b/odoo/upgrades/__init__.py
new file mode 100644
index 00000000000..5fb18447da2
--- /dev/null
+++ b/odoo/upgrades/__init__.py
@@ -0,0 +1,6 @@
+import pkgutil
+import os.path
+__path__ = [
+ os.path.abspath(path)
+ for path in pkgutil.extend_path(__path__, __name__)
+]