[IMP] ORM: Add new --upgrades-paths CLI option

This commit adds a new way to use upgrades scripts folders
whithout needing to symlink them to an hardcoded path.

The folders specified in --upgrades-paths is then being used by
migration.py to find and execute migrations scripts per module
specified in the -u CLI option.

The folder needs to have the following structure:
- <upgrades_paths folder 1>
	- <module1 name>
		- <version1>
			- <script1>
			- <script2>
			- ...
			- <scriptn>
		- <version2>
			- <scripts>
	- <module2 name>
		- <versions>
			- <scripts>
	- ...
- <upgrades_paths folder 2>
	- ...

Update odoo/tools/config.py

Co-Authored-By: Olivier Dony <odony@users.noreply.github.com>
This commit is contained in:
Laurent Contzen
2019-08-05 12:21:00 +00:00
committed by Christophe Simonis
co-authored by Olivier Dony
parent 6edb18be0d
commit bbb1a8f151
3 changed files with 41 additions and 2 deletions
+2
View File
@@ -60,6 +60,8 @@ def report_configuration():
if os.path.isfile(config.rcfile):
_logger.info("Using configuration file at " + config.rcfile)
_logger.info('addons paths: %s', odoo.modules.module.ad_paths)
if config.get('upgrades_paths'):
_logger.info('upgrades path: %s', config['upgrades_paths'])
host = config['db_host'] or os.environ.get('PGHOST', 'default')
port = config['db_port'] or os.environ.get('PGPORT', 'default')
user = config['db_user'] or os.environ.get('PGUSER', 'default')
+18 -1
View File
@@ -19,7 +19,7 @@ _logger = logging.getLogger(__name__)
def load_script(path, module_name):
full_path = get_resource_path(*path.split(os.path.sep))
full_path = get_resource_path(*path.split(os.path.sep)) if not os.path.isabs(path) else path
spec = importlib.util.spec_from_file_location(module_name, full_path)
module = importlib.util.module_from_spec(spec)
spec.loader.exec_module(module)
@@ -62,6 +62,13 @@ class MigrationManager(object):
self._get_files()
def _get_files(self):
def _get_upgrades_paths(pkg):
for path in tools.config['upgrades_paths'].split(','):
upgrade_path = opj(path, pkg)
if os.path.exists(upgrade_path):
return upgrade_path
return None
def get_scripts(path):
if not path:
return {}
@@ -78,7 +85,10 @@ 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)),
}
def migrate_module(self, pkg, stage):
@@ -122,9 +132,16 @@ 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(','):
if os.path.exists(opj(path, pkg.name)):
mapping['upgrades'] = opj(path, pkg.name)
break
for x in mapping:
if version in m.get(x):
for f in m[x][version]:
+21 -1
View File
@@ -118,6 +118,9 @@ class configmanager(object):
group.add_option("--addons-path", dest="addons_path",
help="specify additional addons paths (separated by commas).",
action="callback", callback=self._check_addons_path, nargs=1, type="string")
group.add_option("--upgrades-paths", dest="upgrades_paths",
help="specify an additional upgrades path.",
action="callback", callback=self._check_upgrades_paths, nargs=1, type="string")
group.add_option("--load", dest="server_wide_modules", help="Comma-separated list of server-wide modules.", my_default='base,web')
group.add_option("-D", "--data-dir", dest="data_dir", my_default=_get_default_datadir(),
@@ -420,7 +423,7 @@ class configmanager(object):
'db_name', 'db_user', 'db_password', 'db_host', 'db_sslmode',
'db_port', 'db_template', 'logfile', 'pidfile', 'smtp_port',
'email_from', 'smtp_server', 'smtp_user', 'smtp_password',
'db_maxconn', 'import_partial', 'addons_path',
'db_maxconn', 'import_partial', 'addons_path', 'upgrades_paths',
'syslog', 'without_demo', 'screencasts', 'screenshots',
'dbfilter', 'log_level', 'log_db',
'log_db_level', 'geoip_database', 'dev_mode', 'shell_interface'
@@ -485,6 +488,13 @@ class configmanager(object):
os.path.abspath(os.path.expanduser(os.path.expandvars(x.strip())))
for x in self.options['addons_path'].split(','))
self.options['upgrades_paths'] = (
",".join(os.path.abspath(os.path.expanduser(os.path.expandvars(x.strip())))
for x in self.options['upgrades_paths'].split(','))
if self.options['upgrades_paths']
else ""
)
self.options['data_dir'] = os.path.abspath(os.path.expanduser(os.path.expandvars(self.options['data_dir'].strip())))
self.options['init'] = opt.init and dict.fromkeys(opt.init.split(','), 1) or {}
@@ -539,6 +549,16 @@ class configmanager(object):
setattr(parser.values, option.dest, ",".join(ad_paths))
def _check_upgrades_paths(self, option, opt, value, parser):
upgrades_paths = []
for path in value.split(','):
path = path.strip()
res = os.path.abspath(os.path.expanduser(os.path.expandvars(path)))
if not os.path.isdir(res):
raise optparse.OptionValueError("option %s: no such directory: %r" % (opt, path))
upgrades_paths.append(res)
setattr(parser.values, option.dest, ",".join(upgrades_paths))
def _test_enable_callback(self, option, opt, value, parser):
if not parser.values.test_tags:
parser.values.test_tags = "+standard"