# HG changeset patch
# User Vincent Hatakeyama <vincent.hatakeyama@xcg-consulting.fr>
# Date 1669799507 -3600
#      Wed Nov 30 10:11:47 2022 +0100
# Node ID bbe2a58b80cf6f95ca8271f773b2de9b580eabd8
# Parent  245b708c11e0bf6feeab2aaaace265a1ea433910
🔨 change docker_isort heavily to be able to use it to write changes

diff --git a/NEWS.rst b/NEWS.rst
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -2,6 +2,11 @@
 History
 =======
 
+17.0.0
+------
+
+Changes to docker_isort so that it can be used to apply changes.
+
 16.10.0
 -------
 
diff --git a/odoo_scripts/docker_isort.py b/odoo_scripts/docker_isort.py
--- a/odoo_scripts/docker_isort.py
+++ b/odoo_scripts/docker_isort.py
@@ -7,22 +7,27 @@
 import os
 import sys
 
-from .config import ODOO_13, ODOO_15, Config
+from .config import ODOO_7, ODOO_8, ODOO_9, ODOO_10, ODOO_11, ODOO_12, ODOO_13, Config
+from .docker_build import add_build_options, build_local_image, get_build_options
 from .docker_client import DockerClient
+from .docker_prettier import get_volumes
 from .parsing import apply, basic_parser
 
-__version__ = "2.1.0"
+__version__ = "3.0.0"
 __date__ = "2020-09-10"
-__updated__ = "2022-01-27"
+__updated__ = "2022-11-02"
 
 _logger = logging.getLogger(__name__)
 _ISORT_DEST = "isort"
 """Name of destination variable used for isort in parsing"""
+_ISORT_DIR_DEST = "isort_dir"
 
 CHECK_MODE = "check"
 """Run isort to check"""
 DIFF_MODE = "diff"
 """Run isort to show differences"""
+WRITE_MODE = "write"
+"""Run isort to write differences"""
 
 
 def __parser():
@@ -79,61 +84,105 @@
     )
 
 
-def apply_isort(namespace: argparse.Namespace, odoo_type: str):
+def parser_add_isort(parser: argparse.ArgumentParser):
+    """Add isort option (--isort/--no-isort) to the given parser.
+    Defaults to not using isort."""
+    parser.add_argument(
+        help="Run pylint on given directory (relative path, for example "
+        "github.com/OCA/server-auth)",
+        dest=_ISORT_DIR_DEST,
+    )
+    isort_group = parser.add_mutually_exclusive_group()
+    isort_group.add_argument(
+        "--check",
+        help="Run isort (check only)",
+        action="store_const",
+        dest=_ISORT_DEST,
+        const=CHECK_MODE,
+        default=CHECK_MODE,
+    )
+    isort_group.add_argument(
+        "--diff",
+        help="Run isort (diff only)",
+        action="store_const",
+        dest=_ISORT_DEST,
+        const=DIFF_MODE,
+    )
+    isort_group.add_argument(
+        "--write",
+        help="Run isort (write)",
+        action="store_const",
+        dest=_ISORT_DEST,
+        const=WRITE_MODE,
+    )
+
+
+def apply_isort(namespace: argparse.Namespace, config: Config = None):
     """Run isort if the option was set."""
     if _ISORT_DEST in namespace and getattr(namespace, _ISORT_DEST):
-        return isort(getattr(namespace, _ISORT_DEST), odoo_type)
+        return isort(
+            getattr(namespace, _ISORT_DEST),
+            directory=getattr(namespace, _ISORT_DIR_DEST),
+            config=config,
+        )
     return 0
 
 
 def main(argv=None):
     """Copy modules for a build, callable version that parses arguments"""
     parser = __parser()
+    add_build_options(parser)
+    parser_add_isort(parser)
     nmspc = parser.parse_args(argv)
-    apply(nmspc)
     config = Config()
-    odoo_type = config.odoo_type
-    return isort(DIFF_MODE, odoo_type)
+    apply(nmspc)
+    if config.odoo_type not in (ODOO_7, ODOO_8, ODOO_9, ODOO_10):
+        build_local_image(get_build_options(nmspc))
+    return apply_isort(nmspc, config=config)
 
 
-def isort(mode: str, odoo_type: str, pull: bool = True):
+def isort(mode: str, directory: str = "", config: Config = None):
     """Run isort"""
+    if config is None:
+        config = Config()
+    odoo_type = config.odoo_type
+
+    command = []
+
     if mode == CHECK_MODE:
-        command = ["--check"]
+        command.append("--check")
     if mode == DIFF_MODE:
-        command = ["--check", "--diff"]
+        command.append("--check")
+        command.append("--diff")
 
     # determine image to use based on odoo version
-    repository = "quay.orus.io/odoo/odoo"
-    if odoo_type == ODOO_15:
-        tag = "15.0"
-        # append the directory, needed with isort≥5.0.0
-        command.append(".")
-    elif odoo_type == ODOO_13:
-        tag = "13.0"
-    else:
+    if odoo_type in (ODOO_7, ODOO_8, ODOO_9, ODOO_10):
         repository = "xcgd/isort"
         tag = "odoo"
+        pull = True
+    else:
+        repository = config.local_image
+        tag = config.local_tag
+        pull = False
 
-    _logger.info("Running isort")
+        if odoo_type not in (ODOO_11, ODOO_12, ODOO_13):
+            # append the directory, needed with isort≥5.0.0
+            command.append(".")
+
     pwd = os.environ["PWD"]
+    volumes, path = get_volumes(pwd, directory, mode == WRITE_MODE)
+    _logger.info("Running prettier in %s", path)
     return DockerClient.run(
         repository,
         tag,
         {
             "entrypoint": "isort",
-            "user": "root",
+            "user": os.getuid(),
             "command": command,
-            "volumes": {
-                pwd: {
-                    "bind": "/mnt",
-                    "mode": "ro" if mode in (CHECK_MODE, DIFF_MODE) else "rw",
-                }
-            },
-            "working_dir": "/mnt",
+            "volumes": volumes,
+            "working_dir": path,
         },
         pull,
-        {"/mnt": pwd},
     )
 
 
diff --git a/odoo_scripts/docker_prettier.py b/odoo_scripts/docker_prettier.py
--- a/odoo_scripts/docker_prettier.py
+++ b/odoo_scripts/docker_prettier.py
@@ -81,27 +81,13 @@
         image = config.local_image
         tag = config.local_tag
 
-    pwd = os.environ["PWD"]
-    path = os.path.abspath(os.path.join(pwd, directory))
-    volumes = {
-        pwd: {
-            "bind": pwd,
-            "mode": "rw" if write else "ro",
-        }
-    }
-    # also bind any symbolic link, but only for the given directory or its parent.
-    # all symbolic link could be scanned for but that might take too much time
-    for potential_link in (path, os.path.dirname(path)):
-        if os.path.islink(potential_link):
-            volumes[potential_link] = {
-                "bind": os.path.realpath(potential_link),
-                "mode": "rw" if write else "ro",
-            }
-
     command = ["."]
     if write:
         command.append("--write")
 
+    pwd = os.environ["PWD"]
+    volumes, path = get_volumes(pwd, directory, write)
+
     _logger.info("Running prettier in %s", path)
     return DockerClient.run(
         image,
@@ -118,5 +104,24 @@
     )
 
 
+def get_volumes(base_dir, directory: str, write: bool = False):
+    path = os.path.abspath(os.path.join(base_dir, directory))
+    volumes = {
+        base_dir: {
+            "bind": base_dir,
+            "mode": "rw" if write else "ro",
+        }
+    }
+    # also bind any symbolic link, but only for the given directory or its parent.
+    # all symbolic link could be scanned for but that might take too much time
+    for potential_link in (path, os.path.dirname(path)):
+        if os.path.islink(potential_link):
+            volumes[potential_link] = {
+                "bind": os.path.realpath(potential_link),
+                "mode": "rw" if write else "ro",
+            }
+    return volumes, path
+
+
 if __name__ == "__main__":
     sys.exit(main(sys.argv[1:]))