Skip to content

Commit

Permalink
[IMP] ORM: Add new --upgrades-paths CLI option
Browse files Browse the repository at this point in the history
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>
	- ...
  • Loading branch information
Laurent Contzen committed May 10, 2019
1 parent 6d9862f commit 43243c8
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 2 deletions.
2 changes: 2 additions & 0 deletions odoo/cli/server.py
Expand Up @@ -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')
Expand Down
19 changes: 18 additions & 1 deletion odoo/modules/migration.py
Expand Up @@ -19,7 +19,7 @@


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)
Expand Down Expand Up @@ -58,6 +58,13 @@ def __init__(self, cr, graph):
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 {}
Expand All @@ -74,7 +81,10 @@ def get_scripts(path):

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):
Expand Down Expand Up @@ -111,9 +121,16 @@ def _get_migration_files(pkg, version, stage):

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]:
Expand Down
22 changes: 21 additions & 1 deletion odoo/tools/config.py
Expand Up @@ -117,6 +117,9 @@ def __init__(self, fname=None):
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-path", 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(),
Expand Down Expand Up @@ -405,7 +408,7 @@ def die(cond, msg):
'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',
'dbfilter', 'log_level', 'log_db',
'log_db_level', 'geoip_database', 'dev_mode', 'shell_interface'
Expand Down Expand Up @@ -470,6 +473,13 @@ def die(cond, msg):
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 {}
Expand Down Expand Up @@ -524,6 +534,16 @@ def _check_addons_path(self, option, opt, value, parser):

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"
Expand Down

0 comments on commit 43243c8

Please sign in to comment.