diff --git a/newsfragments/+build-with-uv.feature b/newsfragments/+build-with-uv.feature new file mode 100644 index 0000000000000000000000000000000000000000..3913ea630f62cf1bd994e0a319ded55354676c1a_bmV3c2ZyYWdtZW50cy8rYnVpbGQtd2l0aC11di5mZWF0dXJl --- /dev/null +++ b/newsfragments/+build-with-uv.feature @@ -0,0 +1,1 @@ +Build python packages with uv when available \ No newline at end of file diff --git a/odoo_scripts/docker_build_clean.py b/odoo_scripts/docker_build_clean.py index 75ef4de48aecb18ffbe93fb06b657ee743a4948a_b2Rvb19zY3JpcHRzL2RvY2tlcl9idWlsZF9jbGVhbi5weQ==..3913ea630f62cf1bd994e0a319ded55354676c1a_b2Rvb19zY3JpcHRzL2RvY2tlcl9idWlsZF9jbGVhbi5weQ== 100644 --- a/odoo_scripts/docker_build_clean.py +++ b/odoo_scripts/docker_build_clean.py @@ -8,7 +8,7 @@ from typing import List, Optional from ._parsing import apply, basic_parser -from .docker_build_copy import _PYTHON_PACKAGES_DIR +from .docker_build_copy import _ODOO_MODULES_DIR, _PYTHON_PACKAGES_DIR from .list_modules import MODULES_LIST_FILE _logger = logging.getLogger(__name__) @@ -51,7 +51,7 @@ """Clean up after a build""" if os.path.exists(MODULES_LIST_FILE): os.remove(MODULES_LIST_FILE) - for directory in ("odoo_modules", "odoo_setup", _PYTHON_PACKAGES_DIR): + for directory in (_ODOO_MODULES_DIR, "odoo_setup", _PYTHON_PACKAGES_DIR): if os.path.exists(directory): shutil.rmtree(directory) diff --git a/odoo_scripts/docker_build_copy.py b/odoo_scripts/docker_build_copy.py index 75ef4de48aecb18ffbe93fb06b657ee743a4948a_b2Rvb19zY3JpcHRzL2RvY2tlcl9idWlsZF9jb3B5LnB5..3913ea630f62cf1bd994e0a319ded55354676c1a_b2Rvb19zY3JpcHRzL2RvY2tlcl9idWlsZF9jb3B5LnB5 100644 --- a/odoo_scripts/docker_build_copy.py +++ b/odoo_scripts/docker_build_copy.py @@ -25,5 +25,5 @@ _logger = logging.getLogger(__name__) -__version__ = "2.6.3" +__version__ = "2.7.0" __date__ = "2020-06-30" @@ -29,3 +29,3 @@ __date__ = "2020-06-30" -__updated__ = "2024-12-03" +__updated__ = "2024-12-11" @@ -31,6 +31,6 @@ -_ODOO_MODULES_DIR = "odoo_modules" -_PYTHON_PACKAGES_DIR = "python_packages" +_ODOO_MODULES_DIR: str = "odoo_modules" +_PYTHON_PACKAGES_DIR: str = "python_packages" def add_build_copy_options(parser: argparse.ArgumentParser): @@ -380,5 +380,5 @@ def _compile_package(package_to_compile, target) -> List[str]: versions = _find_packages_version(package_to_compile, tags_only=False) - content = [] + content: list[str] = [] requirements = [] @@ -384,5 +384,7 @@ requirements = [] + cachedirname: str = "" + tmpdirname: str = "" if versions: cachedirname = compiled_cache_dir(versions[0][0], versions[0][1]) if not os.path.exists(cachedirname): os.makedirs(cachedirname) @@ -385,9 +387,13 @@ if versions: cachedirname = compiled_cache_dir(versions[0][0], versions[0][1]) if not os.path.exists(cachedirname): os.makedirs(cachedirname) - content = os.listdir(cachedirname) - if not content: - package_path = os.path.join(".", package_to_compile) - with tempfile.TemporaryDirectory() as tmpdirname: + _logger.info("Using cache for %s", package_to_compile) + content = [os.path.join(cachedirname, f) for f in os.listdir(cachedirname)] + try: + if not content: + _logger.info("Compiling %s", package_to_compile) + package_path = os.path.join(".", package_to_compile) + tmpdirname = tempfile.mkdtemp() + # Faster is using uv try: @@ -393,7 +399,2 @@ try: - # TODO pip wheel semble plus rapide - # build is not usable directly so use a subprocess. - # Disable flake8, this is just to test that the package is installed. - import build # type: ignore[import] # noqa: F401 - cmd = [ @@ -399,4 +400,3 @@ cmd = [ - sys.executable, - "-m", + "uv", "build", @@ -402,5 +402,6 @@ "build", - "--outdir", + "--wheel", + "--out-dir", tmpdirname, package_path, ] @@ -404,5 +405,7 @@ tmpdirname, package_path, ] + if not _logger.getChild("compile_package").isEnabledFor(logging.DEBUG): + cmd.append("--quiet") _logger.debug(" ".join(cmd)) check_call(cmd) @@ -407,24 +410,45 @@ _logger.debug(" ".join(cmd)) check_call(cmd) - except ImportError: - # pip is not usable directly, it is indicated in its doc to use - # subprocess instead. - cmd = [ - sys.executable, - "-m", - "pip", - "wheel", - "--no-deps", - "-w", - tmpdirname, - "--ignore-requires-python", - package_path, - ] - _logger.debug(" ".join(cmd)) - check_call(cmd) - content = os.listdir(tmpdirname) - for file in content: - # LINUX - check_call(["cp", os.path.join(tmpdirname, file), target]) - if versions: + except FileNotFoundError: + try: + # TODO pip wheel semble plus rapide + # build is not usable directly so use a subprocess. + # Disable flake8, this is just to test that the package is + # installed. + import build # type: ignore[import] # noqa: F401 + + cmd = [ + sys.executable, + "-m", + "build", + "--outdir", + tmpdirname, + package_path, + ] + _logger.debug(" ".join(cmd)) + check_call(cmd) + except ImportError: + # pip is not usable directly, it is indicated in its doc to use + # subprocess instead. + cmd = [ + sys.executable, + "-m", + "pip", + "wheel", + "--no-deps", + "-w", + tmpdirname, + "--ignore-requires-python", + package_path, + ] + _logger.debug(" ".join(cmd)) + check_call(cmd) + # could also filter to use only .whl + content = [ + os.path.join(tmpdirname, f) + for f in os.listdir(tmpdirname) + if f not in (".gitignore", ".hgignore") + ] + if cachedirname: + for file in content: # LINUX @@ -430,5 +454,4 @@ # LINUX - check_call(["cp", os.path.join(target, file), cachedirname]) - else: + check_call(["cp", "-a", file, cachedirname]) for file in content: # LINUX @@ -433,9 +456,12 @@ for file in content: # LINUX - check_call(["cp", os.path.join(cachedirname, file), target]) - for file in content: - requirements.append(os.path.join(".", target, file)) - + check_call(["cp", "-a", file, target]) + requirements.append(os.path.join(".", target, os.path.basename(file))) + finally: + if tmpdirname: + for file in os.listdir(tmpdirname): + os.remove(os.path.join(tmpdirname, file)) + os.rmdir(tmpdirname) try: # Disable flake8, this is just to test that the package is installed import twine # type: ignore[import] # noqa: F401