diff --git a/.gitignore b/.gitignore index 3ad0a867b8f..ac767604569 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,6 @@ setup/win32/static/postgresql*.exe /man/ /share/ /src/ + +# avoid adding it after generation from tsconfig command +tsconfig.json diff --git a/doc/reference/cmdline.rst b/doc/reference/cmdline.rst index 7936a32b888..d5acf811fa0 100644 --- a/doc/reference/cmdline.rst +++ b/doc/reference/cmdline.rst @@ -743,3 +743,20 @@ load. If the module works despite the presence of those files, they are probably not loaded and should therefore be removed from the module, or at least excluded in the manifest via ``cloc_exclude``. +TSConfig Generator +================== + +.. program:: odoo-bin tsconfig + +When working on javascript, there are ways to help your editor providing you with +powerful auto-completion. One of those ways is the use of a tsconfig.json file. +Originally meant for typescript, editors can use its information with plain javascript also. +With this config file, you will now have full auto-completion across modules. + +The command to generate this files takes as many unnamed arguments as you need. Those are relative paths +to your addon directories. In the example below, we move up one folder to save the tsconfig file in the folder +containing community and enterprise. + +.. code-block:: console + + $ community/odoo-bin tsconfig --addons-path community/addons,community/odoo/addons,enterprise > tsconfig.json diff --git a/odoo/cli/__init__.py b/odoo/cli/__init__.py index 3734b533354..070cd7e96f2 100644 --- a/odoo/cli/__init__.py +++ b/odoo/cli/__init__.py @@ -13,3 +13,4 @@ from . import server from . import shell from . import start from . import populate +from . import tsconfig diff --git a/odoo/cli/tsconfig.py b/odoo/cli/tsconfig.py new file mode 100644 index 00000000000..a58cb307efd --- /dev/null +++ b/odoo/cli/tsconfig.py @@ -0,0 +1,124 @@ +import argparse +import glob +import json +import os +import re +import sys + +from . import Command +from odoo.modules.module import MANIFEST_NAMES + + +class TSConfig(Command): + """Generates tsconfig files for javascript code""" + + def get_module_list(self, path): + return [ + mod.split(os.path.sep)[-2] + for mname in MANIFEST_NAMES + for mod in glob.glob(os.path.join(path, f'*/{mname}')) + ] + + def clean_path(self, path): + return re.sub(r"/{2,}", "/", path) + + def prefix_suffix_path(self, path, prefix, suffix): + return self.clean_path(f"{prefix}/{path}/{suffix}") + + def remove_(self, modules, module): + for name, path in modules: + if module == name: + modules.remove((name, path)) + + def run(self, cmdargs): + parser = argparse.ArgumentParser( + prog="%s %s" % (sys.argv[0].split(os.path.sep)[-1], self.command_name), + description=self.__doc__ + ) + parser.add_argument('--addons-path', type=str, nargs=1, dest="paths") + args = parser.parse_args(args=cmdargs) + + modules = {} + for path in args.paths[0].split(','): + for module in self.get_module_list(self.clean_path(path)): + modules[module] = self.prefix_suffix_path(module, path, "/static/src/*") + + content = self.generate_file_content(modules) + # pylint: disable=bad-builtin + print(json.dumps(content, indent=2)) + + def generate_imports(self, modules): + return { + f'@{module}/*': [path] + for module, path in modules.items() + } + + def generate_file_content(self, modules): + return { + 'compilerOptions': { + "baseUrl": ".", + "checkJs": True, + "allowJs": True, + "noEmit": True, + "paths": self.generate_imports(modules) + }, "exclude": self.generate_excludes() + } + + def generate_excludes(self): + return [ + "/**/*.po", + "/**/*.py", + "/**/*.pyc", + "/**/*.xml", + "/**/*.png", + "/**/*.md", + "/**/*.dat", + "/**/*.scss", + "/**/*.jpg", + "/**/*.svg", + "/**/*.pot", + "/**/*.csv", + "/**/*.mo", + "/**/*.txt", + "/**/*.less", + "/**/*.bcmap", + "/**/*.properties", + "/**/*.html", + "/**/*.ttf", + "/**/*.rst", + "/**/*.css", + "/**/*.pack", + "/**/*.idx", + "/**/*.h", + "/**/*.map", + "/**/*.gif", + "/**/*.sample", + "/**/*.doctree", + "/**/*.so", + "/**/*.pdf", + "/**/*.xslt", + "/**/*.conf", + "/**/*.woff", + "/**/*.xsd", + "/**/*.eot", + "/**/*.jst", + "/**/*.flow", + "/**/*.sh", + "/**/*.yml", + "/**/*.pfb", + "/**/*.jpeg", + "/**/*.crt", + "/**/*.template", + "/**/*.pxd", + "/**/*.dylib", + "/**/*.pem", + "/**/*.rng", + "/**/*.xsl", + "/**/*.xls", + "/**/*.cfg", + "/**/*.pyi", + "/**/*.pth", + "/**/*.markdown", + "/**/*.key", + "/**/*.ico", + ]