Skip to content

Commit

Permalink
Merge pull request #72 from sbidoul/ref-oca_list_addons_to_test_as_reqs
Browse files Browse the repository at this point in the history
Avoid conflict between addons in test-requirements.txt and local repo
  • Loading branch information
sbidoul authored Mar 17, 2024
2 parents e78d8e1 + f250258 commit f641d25
Show file tree
Hide file tree
Showing 4 changed files with 92 additions and 8 deletions.
4 changes: 2 additions & 2 deletions bin/oca_install_addons__deps_and_addons_path
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
#

set -ex
shopt -s nullglob # in case there is setup.py nor pyproject.toml
shopt -s nullglob # in case there is no setup.py nor pyproject.toml

# Compute and install direct dependencies of installable addons in $ADDONS_DIR
# (this includes addons, python external dependencies and odoo itself).
Expand All @@ -31,7 +31,7 @@ cat test-requirements.txt
# we create a constraints file with local directory references to the addons to test.
if python -c 'import sys; sys.exit(sys.version_info < (3,6))' ; then
# python >= 3.6
oca_list_addons_to_test_as_reqs >> test-constraints.txt
oca_list_addons_to_test_as_url_reqs >> test-constraints.txt
else
# old python where pip does not support URL constraints
touch test-constraints.txt
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
#!/usr/bin/env python

#
# Print addons to test as pip requirements pointing to local directories.
# There is an option to make them editable or file URLs.
#
"""Print addons to test as pip requirements pointing to local directories.
Addons that are referenced as direct URLs in test-requirements.txt are ignored
because they are going to be installed from there, as test-requirements.txt
must have priority over the local repo, when there are PR references in it.
"""

import argparse
import os
import re
import subprocess
from pathlib import Path

Expand Down Expand Up @@ -39,7 +40,21 @@ def _list_addons_to_test():
)


parser = argparse.ArgumentParser()
def _addons_in_test_requirements(addons_dir):
"""Return a set of addon names that have direct URL requirements in test-requirements.txt."""
test_requirements_path = addons_dir / "test-requirements.txt"
if not test_requirements_path.exists():
return set()
url_addon_regex = re.compile(r"^odoo\d*-addon-(?P<addon_name>[a-zA-Z0-9_-]+) *@")
res = set()
for line in test_requirements_path.read_text().splitlines():
match = url_addon_regex.match(line)
if match:
res.add(match.group("addon_name").replace("-", "_"))
return res


parser = argparse.ArgumentParser(description=__doc__)
parser.add_argument(
"--editable",
action="store_true",
Expand All @@ -48,7 +63,10 @@ parser.add_argument(
args = parser.parse_args()

addons_dir = Path(os.getenv("ADDONS_DIR", "."))
addons_to_skip = _addons_in_test_requirements(addons_dir)
for addon_name in _list_addons_to_test():
if addon_name in addons_to_skip:
continue
pyproject_path = addons_dir / addon_name / "pyproject.toml"
if pyproject_path.exists():
print(_make_addon_req(pyproject_path.parent, args.editable))
Expand Down
8 changes: 8 additions & 0 deletions tests/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -87,3 +87,11 @@ def did_run_test_module(output, test_module):
test_module is the full name of the test (addon_name.tests.test_module).
"""
return "odoo.addons." + test_module in output


def make_addon_dist_name(addon_name):
odoo_series = int(os.getenv("ODOO_VERSION").partition(".")[0])
return "odoo{odoo_series}-addon-{name}".format(
name=addon_name,
odoo_series=odoo_series if odoo_series < 15 else "",
)
58 changes: 58 additions & 0 deletions tests/test_list_addons_to_test_as_url_reqs.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
import subprocess
import textwrap

from .common import make_addons_dir, make_addon_dist_name


def test_oca_list_addons_to_test_as_url_reqs__basic():
"""Basic successful test."""
with make_addons_dir(
["addon_success", "addon_with_deb_dep", "uninstallable_addon"]
) as addons_dir:
result = subprocess.check_output(
["oca_list_addons_to_test_as_url_reqs"], cwd=addons_dir, text=True
)
assert result == textwrap.dedent(
f"""\
{make_addon_dist_name('addon_success')} @ {addons_dir.as_uri()}/addon_success
{make_addon_dist_name('addon_with_deb_dep')} @ {addons_dir.as_uri()}/addon_with_deb_dep
"""
)


def test_oca_list_addons_to_test_as_url_reqs__editable():
"""Basic successful test with editables."""
with make_addons_dir(
["addon_success", "addon_with_deb_dep", "uninstallable_addon"]
) as addons_dir:
result = subprocess.check_output(
["oca_list_addons_to_test_as_url_reqs", "--editable"],
cwd=addons_dir,
text=True,
)
assert result == textwrap.dedent(
f"""\
-e {addons_dir.as_uri()}/addon_success#egg={make_addon_dist_name('addon_success')}
-e {addons_dir.as_uri()}/addon_with_deb_dep#egg={make_addon_dist_name('addon_with_deb_dep')}
"""
)


def test_oca_list_addons_to_test_as_url_reqs__skip_test_requirement():
"""Basic successful test."""
with make_addons_dir(
["addon_success", "addon_with_deb_dep", "uninstallable_addon"]
) as addons_dir:
# add URL reference to addon_success
addons_dir.joinpath("test-requirements.txt").write_text(
f"{make_addon_dist_name('addon_success')} @ git+https://github.com/oca/dummy@refs/pull/123/head"
)
result = subprocess.check_output(
["oca_list_addons_to_test_as_url_reqs"], cwd=addons_dir, text=True
)
# addon_success should not be in result because it is already in test-requirements.txt
assert result == textwrap.dedent(
f"""\
{make_addon_dist_name('addon_with_deb_dep')} @ {addons_dir.as_uri()}/addon_with_deb_dep
"""
)

0 comments on commit f641d25

Please sign in to comment.