diff --git a/DEVELOP.rst b/DEVELOP.rst
index e010603fec5a60f95061a99adbd29944dcf83698_REVWRUxPUC5yc3Q=..d1586d7d2eefd18f616befaf9ebf4bba06470a96_REVWRUxPUC5yc3Q= 100644
--- a/DEVELOP.rst
+++ b/DEVELOP.rst
@@ -1,4 +1,4 @@
-To install for development purpose:
+As :pep:517 does not provide a way to install for development purpose, it is necessary to follow these steps to install for development :
 
 .. code-block:: SH
 
diff --git a/NEWS.rst b/NEWS.rst
index e010603fec5a60f95061a99adbd29944dcf83698_TkVXUy5yc3Q=..d1586d7d2eefd18f616befaf9ebf4bba06470a96_TkVXUy5yc3Q= 100644
--- a/NEWS.rst
+++ b/NEWS.rst
@@ -15,6 +15,8 @@
 
 Add docker_prettier.
 
+Add odoo_conf_inject_env_var entry point.
+
 15.0.0
 ------
 
diff --git a/README.rst b/README.rst
index e010603fec5a60f95061a99adbd29944dcf83698_UkVBRE1FLnJzdA==..d1586d7d2eefd18f616befaf9ebf4bba06470a96_UkVBRE1FLnJzdA== 100644
--- a/README.rst
+++ b/README.rst
@@ -148,6 +148,11 @@
 create_date and write_date is updated as needed, and so is the date_update in ``ir.model.data``.
 This is part of the import_sql section.
 
+odoo_conf_inject_env_var
+------------------------
+
+This script takes an odoo configuration file and a path and will use environment variables values to set some values in the produced odoo configuration file.
+
 setup.cfg
 =========
 
diff --git a/odoo_scripts/docker_client.py b/odoo_scripts/docker_client.py
index e010603fec5a60f95061a99adbd29944dcf83698_b2Rvb19zY3JpcHRzL2RvY2tlcl9jbGllbnQucHk=..d1586d7d2eefd18f616befaf9ebf4bba06470a96_b2Rvb19zY3JpcHRzL2RvY2tlcl9jbGllbnQucHk= 100644
--- a/odoo_scripts/docker_client.py
+++ b/odoo_scripts/docker_client.py
@@ -1,4 +1,4 @@
-"""Class that encapslulate the docker client"""
+"""Class that encapsulate the docker client"""
 import atexit
 import logging
 import os
diff --git a/odoo_scripts/list_modules.py b/odoo_scripts/odoo_conf_inject_env_var.py
similarity index 16%
copy from odoo_scripts/list_modules.py
copy to odoo_scripts/odoo_conf_inject_env_var.py
index e010603fec5a60f95061a99adbd29944dcf83698_b2Rvb19zY3JpcHRzL2xpc3RfbW9kdWxlcy5weQ==..d1586d7d2eefd18f616befaf9ebf4bba06470a96_b2Rvb19zY3JpcHRzL29kb29fY29uZl9pbmplY3RfZW52X3Zhci5weQ== 100644
--- a/odoo_scripts/list_modules.py
+++ b/odoo_scripts/odoo_conf_inject_env_var.py
@@ -1,7 +1,8 @@
 #!/usr/bin/env python3
-"""Create the file odoo_modules_list from setup.cfg
-"""
-# vim: set shiftwidth=4 softtabstop=4:
-#
-# template version 2.7
+"""Method to inject environment variables into an Odoo configuration file."""
+import logging
+import os.path
+import sys
+from configparser import ConfigParser
+from typing import Collection, Optional, Tuple
 
@@ -7,7 +8,3 @@
 
-import logging
-import sys
-
-from .config import Config
 from .parsing import apply, basic_parser
 
@@ -12,6 +9,20 @@
 from .parsing import apply, basic_parser
 
-MODULES_LIST_FILE = "odoo_modules_list"
+__version__ = "1.0.0"
+__date__ = "2022-02-22"
+__updated__ = "2022-02-23"
+
+# tuple with environment variable nome, section and option
+_environment_variables: Collection[Tuple[str, str, str]] = (
+    ("ODOO_OPTIONS_DB_USER", "options", "db_user"),
+    ("ODOO_OPTIONS_DB_PASSWORD", "options", "db_password"),
+    ("ODOO_OPTIONS_DB_NAME", "options", "db_name"),
+    ("ODOO_OPTIONS_DB_HOST", "options", "db_host"),
+    ("ODOO_OPTIONS_DATA_DIR", "options", "data_dir"),
+    ("ODOO_OPTIONS_MAX_CRON_THREADS", "options", "max_cron_threads"),
+    ("ODOO_OPTIONS_LOAD_LANGUAGE", "options", "load_language"),
+    ("ODOO_OPTIONS_ADDONS_PATH", "options", "addons_path"),
+)
 
 _logger = logging.getLogger(__name__)
 
@@ -15,8 +26,20 @@
 
 _logger = logging.getLogger(__name__)
 
-__version__ = "1.0.3"
-__date__ = "2020-02-26"
-__updated__ = "2020-09-11"
+
+def inject_env_var(source_path: str, target_path: str, overwrite: bool = False):
+    """Inject environment variables into an Odoo configuration file."""
+    if os.path.exists(target_path) and not overwrite:
+        raise Exception(f"{target_path} already exists")
+    config_parser = ConfigParser()
+    config_parser.read(source_path)
+    with open(target_path, "w", encoding="UTF-8") as file:
+        for env_var_name, section, option in _environment_variables:
+            if env_var_name in os.environ:
+                _logger.debug("Using %s", env_var_name)
+                if not config_parser.has_section(section):
+                    config_parser.add_section(section)
+                config_parser.set(section, option, os.environ[env_var_name])
+        config_parser.write(file)
 
 
@@ -21,9 +44,7 @@
 
 
-def main(argv=None):  # IGNORE:C0111
-    """Parse arguments and launch conversion"""
-    if argv is None:
-        argv = sys.argv
-    else:
-        sys.argv.extend(argv)
+def main(args: Optional[Collection[str]] = None) -> int:
+    """Parse arguments and launch injection"""
+    if args is None:
+        args = []
 
@@ -29,10 +50,5 @@
 
-    program_version = __version__
-    program_build_date = str(__updated__)
-    program_version_message = "%%(prog)s %s (%s)" % (
-        program_version,
-        program_build_date,
-    )
-    program_shortdesc = __doc__.split("\n", maxsplit=2)[1]
-    program_license = """%s
+    program_version_message = f"%(prog)s {__version__} ({__updated__})"
+    program_short_description = __doc__.split(".", maxsplit=1)[0]
+    program_license = f"""{program_short_description}
 
@@ -38,6 +54,6 @@
 
-  Created by Hugo Monnerie on %s.
-  Copyright 2020 XCG Consulting. All rights reserved.
+  Created by Vincent Hatakeyama on {__date__}.
+  Copyright 2022 XCG Consulting. All rights reserved.
 
   Licensed under the MIT License
 
@@ -45,9 +61,6 @@
   or conditions of any kind, either express or implied.
 
 USAGE
-""" % (
-        program_shortdesc,
-        str(__date__),
-    )
+"""
     # Argument parsing
     parser = basic_parser(program_license, program_version_message)
@@ -52,7 +65,19 @@
     # Argument parsing
     parser = basic_parser(program_license, program_version_message)
-    nmspc = parser.parse_args()
-    apply(nmspc)
-    list_modules(None)
-
+    parser.add_argument(
+        "--source",
+        help="source file",
+        required=True,
+    )
+    parser.add_argument(
+        "--target",
+        help="target file",
+        required=True,
+    )
+    parser.add_argument(
+        "--overwrite",
+        help="Overwrite target file [default: %(default)s]",
+        action="store_true",
+        default=False,
+    )
 
@@ -58,11 +83,8 @@
 
-def list_modules(filename: str = MODULES_LIST_FILE):
-    output = ",".join(Config().module_list)
-    if filename:
-        with open(filename, "w") as f:
-            f.write(output)
-    else:
-        print(output)
+    namespace = parser.parse_args(args)
+    apply(namespace)
+    inject_env_var(namespace.source, namespace.target, namespace.overwrite)
+    return 0
 
 
 if __name__ == "__main__":
@@ -66,4 +88,4 @@
 
 
 if __name__ == "__main__":
-    main()
+    sys.exit(main(sys.argv[1:]))
diff --git a/pyproject.toml b/pyproject.toml
index e010603fec5a60f95061a99adbd29944dcf83698_cHlwcm9qZWN0LnRvbWw=..d1586d7d2eefd18f616befaf9ebf4bba06470a96_cHlwcm9qZWN0LnRvbWw= 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -36,6 +36,7 @@
 minversion = 3.15
 envlist = py36,py37,py38,py39,py310,coverage-report
 skip_missing_interpreters = true
+isolated_build = True
 
 [testenv:py{36,37,38,39,310}]
 setenv =
diff --git a/setup.py b/setup.py
index e010603fec5a60f95061a99adbd29944dcf83698_c2V0dXAucHk=..d1586d7d2eefd18f616befaf9ebf4bba06470a96_c2V0dXAucHk= 100644
--- a/setup.py
+++ b/setup.py
@@ -46,6 +46,7 @@
             "docker_prettier=odoo_scripts.docker_prettier:main [docker]",
             "docker_pylint=odoo_scripts.docker_pylint:main [docker]",
             "conf2reST=odoo_scripts.conf2reST:main [conf2reST]",
+            "odoo_conf_inject_env_var=odoo_scripts.odoo_conf_inject_env_var:main",
             "list_modules=odoo_scripts.list_modules:main",
             "update_duplicate_sources="
             "odoo_scripts.update_duplicate_sources:main [source_control]",
diff --git a/tests/test_config.py b/tests/test_odoo_conf_inject_env_var.py
similarity index 3%
copy from tests/test_config.py
copy to tests/test_odoo_conf_inject_env_var.py
index e010603fec5a60f95061a99adbd29944dcf83698_dGVzdHMvdGVzdF9jb25maWcucHk=..d1586d7d2eefd18f616befaf9ebf4bba06470a96_dGVzdHMvdGVzdF9vZG9vX2NvbmZfaW5qZWN0X2Vudl92YXIucHk= 100644
--- a/tests/test_config.py
+++ b/tests/test_odoo_conf_inject_env_var.py
@@ -1,2 +1,4 @@
-"""Tests of the config module"""
+"""Tests of the Odoo conf module"""
+import os
+import tempfile
 import unittest
@@ -2,2 +4,3 @@
 import unittest
+from configparser import ConfigParser
 
@@ -3,4 +6,19 @@
 
-from odoo_scripts.config import Configuration
+from odoo_scripts.odoo_conf_inject_env_var import inject_env_var, main
+
+
+def clean_up_env():
+    """Clean up environment"""
+    for name in (
+        "ODOO_OPTIONS_DB_USER",
+        "ODOO_OPTIONS_DB_PASSWORD",
+        "ODOO_OPTIONS_DB_NAME",
+        "ODOO_OPTIONS_DB_HOST",
+        "ODOO_OPTIONS_MAX_CRON_THREADS",
+        "ODOO_OPTIONS_DATA_DIR",
+        "ODOO_OPTIONS_LOAD_LANGUAGE",
+        "ODOO_OPTIONS_ADDONS_PATH",
+    ):
+        os.environ.pop(name, None)
 
 
@@ -5,5 +23,41 @@
 
 
-class ConfigTestCase(unittest.TestCase):
-    """Tests of the config module"""
+class OdooConfTestCase(unittest.TestCase):
+    """Tests of the Odoo conf env var class"""
+
+    @classmethod
+    def setUpClass(cls) -> None:
+        """Create the conf file used in the tests"""
+        cls.conf_path = "odoo.conf"
+        with open(cls.conf_path, "w", encoding="UTF-8") as file_io:
+            file_io.write(
+                """# This is a test file similar to an Odoo configuration file
+[options]
+db_user = db_user
+db_password = db_password
+db_name = db_name
+max_cron_threads = 3
+load_language = fr_FR,en
+data_dir = /var/lib/odoo
+db_host = db_host
+addons_path = /mnt/extra-addons
+something_else = something_else
+[anothersection]
+anothersection_key = value
+"""
+            )
+
+    @classmethod
+    def tearDownClass(cls) -> None:
+        """Clean up temporary files"""
+        if os.path.exists(cls.conf_path):
+            os.remove(cls.conf_path)
+
+    def test_no_env_var(self):
+        """Test when there is no environment variable"""
+        with tempfile.TemporaryDirectory() as tmpdirname:
+            new_conf = os.path.join(tmpdirname, "odoo.conf")
+            inject_env_var(self.conf_path, new_conf)
+            config_parser = ConfigParser()
+            config_parser.read(new_conf)
 
@@ -9,3 +63,51 @@
 
-    def test_no_conf(self):
+            self.assertTrue(config_parser.has_section("options"))
+            self.assertEqual(config_parser.get("options", "db_user"), "db_user")
+            self.assertEqual(config_parser.get("options", "db_password"), "db_password")
+            self.assertEqual(config_parser.get("options", "db_name"), "db_name")
+            self.assertEqual(config_parser.get("options", "max_cron_threads"), "3")
+            self.assertEqual(config_parser.get("options", "load_language"), "fr_FR,en")
+            self.assertEqual(config_parser.get("options", "data_dir"), "/var/lib/odoo")
+            self.assertEqual(config_parser.get("options", "db_host"), "db_host")
+            self.assertEqual(
+                config_parser.get("options", "addons_path"), "/mnt/extra-addons"
+            )
+            self.assertEqual(
+                config_parser.get("options", "something_else"), "something_else"
+            )
+            self.assertTrue(config_parser.has_section("anothersection"))
+            self.assertEqual(
+                config_parser.get("anothersection", "anothersection_key"), "value"
+            )
+
+            os.remove(new_conf)
+
+    def test_target_exists(self):
+        """Test when the target file exists"""
+        with tempfile.TemporaryDirectory() as tmpdirname:
+            new_conf = os.path.join(tmpdirname, "odoo.conf")
+            with open(new_conf, "w", encoding="UTF-8") as file:
+                file.write("\n")
+            with self.assertRaises(Exception):
+                inject_env_var(self.conf_path, new_conf)
+
+    def test_no_options_section(self):
+        """Test when the source file does not have the options section"""
+        self.addCleanup(clean_up_env)
+
+        with tempfile.TemporaryDirectory() as tmpdirname:
+            empty_conf = os.path.join(tmpdirname, "odoo-empty.conf")
+            with open(empty_conf, "w", encoding="UTF-8") as file:
+                file.write("\n")
+            new_conf = os.path.join(tmpdirname, "odoo.conf")
+            os.environ["ODOO_OPTIONS_DB_USER"] = "user"
+            inject_env_var(empty_conf, new_conf)
+
+            config_parser = ConfigParser()
+            config_parser.read(new_conf)
+
+            self.assertTrue(config_parser.has_section("options"))
+            self.assertEqual(config_parser.get("options", "db_user"), "user")
+
+    def test_env_var(self):
         """Test when there is no configuration file"""
@@ -11,4 +113,18 @@
         """Test when there is no configuration file"""
-        configuration = Configuration("config-no-file/")
-        self.assertEqual(configuration.modules, [])
+        self.addCleanup(clean_up_env)
+
+        with tempfile.TemporaryDirectory() as tmpdirname:
+            new_conf = os.path.join(tmpdirname, "odoo.conf")
+            os.environ["ODOO_OPTIONS_DB_USER"] = "another"
+            os.environ["ODOO_OPTIONS_DB_PASSWORD"] = "password"
+            os.environ["ODOO_OPTIONS_DB_NAME"] = "name"
+            os.environ["ODOO_OPTIONS_DB_HOST"] = "host"
+            os.environ["ODOO_OPTIONS_MAX_CRON_THREADS"] = "2"
+            os.environ["ODOO_OPTIONS_DATA_DIR"] = "/mnt"
+            os.environ["ODOO_OPTIONS_LOAD_LANGUAGE"] = "en_US"
+            os.environ["ODOO_OPTIONS_ADDONS_PATH"] = "/addons"
+            # use main rather than inject_env_var to also test its code
+            main(["--source", self.conf_path, "--target", new_conf])
+            config_parser = ConfigParser()
+            config_parser.read(new_conf)
 
@@ -14,8 +130,22 @@
 
-    def test_empty_conf(self):
-        """Test when there is no configuration file"""
-        configuration = Configuration("config-empty/")
-        self.assertEqual(configuration.modules, [])
+            self.assertTrue(config_parser.has_section("options"))
+            self.assertEqual(config_parser.get("options", "db_user"), "another")
+            self.assertEqual(config_parser.get("options", "db_password"), "password")
+            self.assertEqual(config_parser.get("options", "db_name"), "name")
+            self.assertEqual(config_parser.get("options", "max_cron_threads"), "2")
+            self.assertEqual(config_parser.get("options", "load_language"), "en_US")
+            self.assertEqual(config_parser.get("options", "data_dir"), "/mnt")
+            self.assertEqual(config_parser.get("options", "db_host"), "host")
+            self.assertEqual(config_parser.get("options", "addons_path"), "/addons")
+            self.assertEqual(
+                config_parser.get("options", "something_else"), "something_else"
+            )
+            self.assertTrue(config_parser.has_section("anothersection"))
+            self.assertEqual(
+                config_parser.get("anothersection", "anothersection_key"), "value"
+            )
+
+            os.remove(new_conf)
 
 
 if __name__ == "__main__":