From ecb509aee4a2ae18e40ed948b185db2fe8a81184 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Rapha=C3=ABl=20Valyi?= Date: Sat, 23 May 2026 12:30:06 -0300 Subject: [PATCH] feat: add --odoo-root option and AK_ODOO_ROOT env var for custom addons path prefix The hardcoded '/odoo/' prefix in ak build output is inconvenient for installations using virtualenvs or non-standard paths (e.g. ~/DEV/odoo18). Changes: - Add --odoo-root CLI option to ak build - Add AK_ODOO_ROOT environment variable support - Priority: CLI option > env var > default '/odoo/' - Rename PREFIX constant to DEFAULT_PREFIX for clarity - Add tests covering all three scenarios Usage examples: ak build --odoo-root ~/DEV/odoo18/ AK_ODOO_ROOT=~/DEV/odoo18/ ak build --- ak/ak_build.py | 23 ++++++++- tests/build/test_odoo_root.py | 90 +++++++++++++++++++++++++++++++++++ 2 files changed, 111 insertions(+), 2 deletions(-) create mode 100644 tests/build/test_odoo_root.py diff --git a/ak/ak_build.py b/ak/ak_build.py index 662c848..58baefe 100644 --- a/ak/ak_build.py +++ b/ak/ak_build.py @@ -18,7 +18,7 @@ LOCAL_FOLDER = 'local-src' LINK_FOLDER = 'links' ODOO_FOLDER = 'src' -PREFIX = '/odoo/' +DEFAULT_PREFIX = '/odoo/' JOBS = 2 logger = logging.getLogger(__name__) @@ -94,6 +94,24 @@ class AkBuild(AkSub): ['j', 'jobs'], int, default=JOBS, help="Number of concurrent jobs") + odoo_root = cli.SwitchAttr( + ['--odoo-root'], + default=None, + help="Prefix for the addons path output. " + "Defaults to the AK_ODOO_ROOT environment variable " + "or '/odoo/' if not set.") + + def _get_prefix(self): + """Return the Odoo root prefix. + + Priority: + 1. --odoo-root CLI option + 2. AK_ODOO_ROOT environment variable + 3. DEFAULT_PREFIX ('/odoo/') + """ + if self.odoo_root is not None: + return self.odoo_root + return os.environ.get('AK_ODOO_ROOT', DEFAULT_PREFIX) def _convert_repo(self, repo, frozen): if not is_spec_simplified_format(repo): @@ -214,7 +232,8 @@ def _print_addons_path(self, config): paths.append('%s/%s' % (VENDOR_FOLDER, repo_path)) # Construct absolute path, better for odoo config file. - abs_path = ",".join([PREFIX + repo_path for repo_path in paths]) + prefix = self._get_prefix() + abs_path = ",".join([prefix + repo_path for repo_path in paths]) print('Addons path for your config file: ', abs_path) def _ensure_viable_installation(self, config): diff --git a/tests/build/test_odoo_root.py b/tests/build/test_odoo_root.py new file mode 100644 index 0000000..e6d7049 --- /dev/null +++ b/tests/build/test_odoo_root.py @@ -0,0 +1,90 @@ +# coding: utf-8 +"""Test the --odoo-root CLI option and AK_ODOO_ROOT env var.""" +import os +import sys +from plumbum import local +from plumbum.commands.modifiers import TF + +import yaml + +# Use the local ak package, not any system-installed binary +sys.path.insert(0, str(local.cwd)) +from ak.main import main as ak_main + +cp = local['cp'] + +test = '/tests/build/' +spec = local.cwd + test + 'short.yaml' + + +def _run_ak_build(*args, env=None): + """Run ak build with given args, returning stdout.""" + import io + from contextlib import redirect_stdout + + old_argv = sys.argv[:] + old_env = {} + try: + sys.argv = ['ak', 'build'] + list(args) + if env: + for k, v in env.items(): + old_env[k] = os.environ.get(k) + if v is None: + os.environ.pop(k, None) + else: + os.environ[k] = v + + f = io.StringIO() + with redirect_stdout(f): + try: + ak_main() + except SystemExit: + pass + return f.getvalue() + finally: + sys.argv = old_argv + for k, v in old_env.items(): + if v is None: + os.environ.pop(k, None) + else: + os.environ[k] = v + + +def test_default_prefix(): + """Ensure default prefix is '/odoo/'.""" + with local.tempdir() as tmp: + with local.cwd(tmp): + cp[spec]['spec.yaml']() + output = _run_ak_build('--links', env={'AK_ODOO_ROOT': None}) + assert "Addons path for your config file: /odoo/" in output + + +def test_env_var_prefix(): + """Ensure AK_ODOO_ROOT env var is used.""" + with local.tempdir() as tmp: + with local.cwd(tmp): + cp[spec]['spec.yaml']() + output = _run_ak_build( + '--links', env={'AK_ODOO_ROOT': '/custom/path/'}) + assert "Addons path for your config file: /custom/path/" in output + + +def test_cli_option_prefix(): + """Ensure --odoo-root CLI option overrides env var.""" + with local.tempdir() as tmp: + with local.cwd(tmp): + cp[spec]['spec.yaml']() + output = _run_ak_build( + '--links', '--odoo-root', '/from/cli/', + env={'AK_ODOO_ROOT': '/from/env/'}) + assert "Addons path for your config file: /from/cli/" in output + + +def test_cli_option_without_trailing_slash(): + """Ensure prefix without trailing slash works (user responsibility).""" + with local.tempdir() as tmp: + with local.cwd(tmp): + cp[spec]['spec.yaml']() + output = _run_ak_build( + '--links', '--odoo-root', '~/DEV/odoo18') + assert "Addons path for your config file: ~/DEV/odoo18" in output