gOdoo-cli 0.0.2__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,70 @@
1
+ """
2
+ Import read_path into Odoo.
3
+ Will wait until Odoo is Online.
4
+ Places Systemparam to Track if import was already done.
5
+ """
6
+
7
+ import logging
8
+ from pathlib import Path
9
+
10
+ import typer
11
+ from godoo_rpc import import_data
12
+ from godoo_rpc.login import wait_for_odoo
13
+
14
+ from ...helpers.cli import typer_unpacker
15
+ from .cli import rpc_callback
16
+
17
+ app = typer.Typer(callback=rpc_callback, no_args_is_help=True)
18
+ LOGGER = logging.getLogger(__name__)
19
+
20
+
21
+ @typer_unpacker
22
+ def import_to_odoo(
23
+ ctx: typer.Context,
24
+ read_path: Path = typer.Argument(
25
+ ...,
26
+ readable=True,
27
+ exists=True,
28
+ help="Folder in which to search for import",
29
+ ),
30
+ file_regex: str = typer.Option(
31
+ r"(?P<module>.*)\.(csv|py|xlsx|json)$",
32
+ help="Regex for filesearch. Add group 'module' to set a Module for RPC import",
33
+ ),
34
+ product_image_regex: str = typer.Option(
35
+ r"(?P<default_code>\d{6})\.(jpeg|png|jpg)$",
36
+ help="Regex to search for Product images. Add Fields as regex group for Matching.",
37
+ ),
38
+ check_data_timestamp: bool = typer.Option(
39
+ True,
40
+ help="If true, Odoo remembers the Name of an uploaded File in a Serverparameter. Subsequent Imports will ignore the file if it hasnt changed.",
41
+ ),
42
+ skip_existing_ids: bool = typer.Option(False, help="Will skip import of already existing External IDs."),
43
+ ):
44
+ """
45
+ Import Csv Files into Odoo.
46
+ Adds an ir.config_parameter for each imported file,
47
+ containing the modification time of the file.
48
+ Will Skip already matching Timestamps and only import files that are new.
49
+ """
50
+ odoo_api = wait_for_odoo(
51
+ odoo_host=ctx.obj.odoo_rpc_host,
52
+ odoo_db=ctx.obj.odoo_main_db,
53
+ odoo_user=ctx.obj.odoo_rpc_user,
54
+ odoo_password=ctx.obj.odoo_rpc_password,
55
+ )
56
+ if not read_path.exists():
57
+ raise ValueError("Provided import Path: %s doesn't exist", read_path)
58
+
59
+ if read_path.is_file():
60
+ product_image_regex = ""
61
+ file_regex = ""
62
+
63
+ import_data(
64
+ odoo_api=odoo_api,
65
+ read_path=read_path.absolute(),
66
+ data_regex=file_regex,
67
+ product_image_regex=product_image_regex,
68
+ check_dataset_timestamp=check_data_timestamp,
69
+ skip_existing_ids=skip_existing_ids,
70
+ )
@@ -0,0 +1,108 @@
1
+ import logging
2
+ from typing import Any, List
3
+
4
+ import typer
5
+ from godoo_rpc import OdooApiWrapper
6
+ from godoo_rpc.login import wait_for_odoo
7
+
8
+ from ...helpers.cli import typer_retuner
9
+ from .cli import rpc_callback
10
+
11
+ LOGGER = logging.getLogger(__name__)
12
+
13
+
14
+ def rpc_get_modules(odoo_api: OdooApiWrapper, module_query: str, valid_module_names: List[str] = None):
15
+ """Get ir.module.module records by a query search string.
16
+
17
+ Parameters
18
+ ----------
19
+ odoo_api : OdooApiWrapper
20
+ Odoo Wrapper
21
+ module_query : str
22
+ Custom query. Module name. Comma sep list of modules or % wildcards are supported
23
+ valid_module_names : List[str], optional
24
+ only allow certain model names to be returned, by default None
25
+
26
+ Returns
27
+ -------
28
+ _type_
29
+ _description_
30
+ """
31
+ mod_env = odoo_api.session.env["ir.module.module"]
32
+ mod_env.update_list()
33
+
34
+ base_domain = []
35
+ if "," in module_query:
36
+ search_domain = [("name", "in", module_query.split(","))]
37
+ else:
38
+ if "%" in module_query:
39
+ search_domain = [("name", "=ilike", module_query)]
40
+ else:
41
+ search_domain = [("name", "=", module_query)]
42
+
43
+ if valid_module_names:
44
+ base_domain.insert(1, "&")
45
+ base_domain.append(("name", "in", valid_module_names))
46
+
47
+ if ids := mod_env.search(base_domain + search_domain):
48
+ return mod_env.browse(ids)
49
+
50
+
51
+ def rpc_install_modules(
52
+ modules: Any,
53
+ upgrade: bool = True,
54
+ ):
55
+ """Install and upgrade Modules to Database.
56
+
57
+ Parameters
58
+ ----------
59
+ modules : Iterable RPC ir.module.module records
60
+ List of
61
+ upgrade : bool, optional
62
+ Upgrade module if already installed, by default True
63
+ """
64
+ did_something = False
65
+
66
+ if install_module_ids := [m.id for m in modules if not m.installed]:
67
+ install_modules = modules.browse(install_module_ids)
68
+ LOGGER.info("Installing Module: " + ", ".join(install_modules.mapped("name")))
69
+ install_modules.button_immediate_install()
70
+ did_something = True
71
+
72
+ if upgrade and (up_module_ids := [m.id for m in modules if m.installed]):
73
+ up_modules = modules.browse(up_module_ids)
74
+ LOGGER.info("Updating Module: " + ", ".join(up_modules.mapped("name")))
75
+ up_modules.button_immediate_upgrade()
76
+ did_something = True
77
+ return did_something
78
+
79
+
80
+ def install_modules(
81
+ ctx: typer.Context,
82
+ module_name_query: str = typer.Argument(..., help=r"Module Internal name. Will use ilike Match if \% is present"),
83
+ upgrade: bool = typer.Option(True, help="Upgrae Module if already installed"),
84
+ ):
85
+ """Upgrades or Installs Modules in Odoo via RPC."""
86
+
87
+ odoo_api = wait_for_odoo(
88
+ odoo_host=ctx.obj.odoo_rpc_host,
89
+ odoo_db=ctx.obj.odoo_main_db,
90
+ odoo_user=ctx.obj.odoo_rpc_user,
91
+ odoo_password=ctx.obj.odoo_rpc_password,
92
+ )
93
+
94
+ if modules := rpc_get_modules(odoo_api, module_name_query):
95
+ if rpc_install_modules(modules):
96
+ return
97
+ else:
98
+ LOGGER.warn("Found Modules, but didn't do anything on DB.")
99
+ else:
100
+ LOGGER.warn("Could not find modules with Query: '%s'", module_name_query)
101
+ return typer_retuner(1)
102
+
103
+
104
+ def modules_cli_app():
105
+ app = typer.Typer(callback=rpc_callback, no_args_is_help=True)
106
+
107
+ app.command(name="install")(install_modules)
108
+ return app
@@ -0,0 +1,94 @@
1
+ import logging
2
+ from base64 import b64decode
3
+ from pathlib import Path
4
+
5
+ import typer
6
+ from godoo_rpc.login import wait_for_odoo
7
+
8
+ from ...helpers.cli import typer_retuner
9
+ from ...helpers.odoo_files import get_odoo_addons_in_folder
10
+ from .cli import rpc_callback
11
+ from .modules import rpc_get_modules
12
+
13
+ app = typer.Typer(callback=rpc_callback, no_args_is_help=True)
14
+ LOGGER = logging.getLogger(__name__)
15
+
16
+
17
+ def dump_translation(module, target_path: Path):
18
+ """Dump Translation of a module into POT file.
19
+
20
+ Parameters
21
+ ----------
22
+ module : _type_
23
+ _description_
24
+ target_path : Path
25
+ _description_
26
+ """
27
+ trans_exp_mod = module.env["base.language.export"]
28
+
29
+ LOGGER.info("Exporting: %s --> %s", module.name, str(target_path))
30
+ trans_wiz_id = trans_exp_mod.create({"format": "po", "modules": [module.id]})
31
+ trans_wiz = trans_exp_mod.browse([trans_wiz_id])
32
+ trans_wiz.act_getfile()
33
+ trans_wiz = trans_exp_mod.browse([trans_wiz_id])
34
+ target_path.parent.mkdir(exist_ok=True)
35
+ target_path.write_bytes(b64decode(trans_wiz.data))
36
+
37
+
38
+ def _dump_translations(
39
+ modules,
40
+ workspace_addon_path: Path,
41
+ upgrade_modules: bool = True,
42
+ ):
43
+ """Dump translations of given Modules into their addon folders.
44
+
45
+ Parameters
46
+ ----------
47
+ odoo_api : OdooApiWrapper
48
+ Odoo Api Wrapper
49
+ modules : _type_
50
+ Api Models of modules
51
+ workspace_addon_path : Path
52
+ path where those modules are installed
53
+ upgrade_modules : bool, optional
54
+ Wether to upgrade modules before dumping, by default True
55
+ """
56
+
57
+ if upgrade_modules:
58
+ LOGGER.info("Upgrading Modules: '%s'", ", ".join(modules.mapped("name")))
59
+ modules.button_immediate_upgrade()
60
+
61
+ for mod in modules:
62
+ ex_path: Path = workspace_addon_path / mod.name / "i18n"
63
+ pot_path: Path = ex_path / (mod.name + ".pot")
64
+ dump_translation(mod, pot_path)
65
+
66
+
67
+ def dump_translations(
68
+ ctx: typer.Context,
69
+ module_query=typer.Argument(..., help="Module Name. Add % to force =ilike match. Only valid for Workspace Addons."),
70
+ upgrade_modules: bool = typer.Option(True, help="Upgrade modules before exporting"),
71
+ ):
72
+
73
+ addon_path = ctx.obj.workspace_addon_path
74
+ addon_folders = get_odoo_addons_in_folder(addon_path)
75
+ valid_module_names = [str(p.stem) for p in addon_folders]
76
+ LOGGER.debug("Found modules:\n%s", "\n".join(["\t" + mn for mn in valid_module_names]))
77
+
78
+ odoo_api = wait_for_odoo(
79
+ odoo_host=ctx.obj.odoo_rpc_host,
80
+ odoo_db=ctx.obj.odoo_main_db,
81
+ odoo_user=ctx.obj.odoo_rpc_user,
82
+ odoo_password=ctx.obj.odoo_rpc_password,
83
+ )
84
+
85
+ modules = rpc_get_modules(odoo_api, module_query, valid_module_names)
86
+ if not modules:
87
+ LOGGER.warning("No installed Modules found for Query string: '%s'", module_query)
88
+ return typer_retuner(1)
89
+
90
+ _dump_translations(
91
+ modules=modules,
92
+ workspace_addon_path=addon_path,
93
+ upgrade_modules=upgrade_modules,
94
+ )
@@ -0,0 +1,42 @@
1
+ import logging
2
+ import os
3
+ from typing import List
4
+
5
+ import typer
6
+
7
+ from ..helpers.cli import typer_retuner, typer_unpacker
8
+
9
+ LOGGER = logging.getLogger(__name__)
10
+
11
+
12
+ @typer_unpacker
13
+ def uninstall_modules(
14
+ ctx: typer.Context,
15
+ module_list: List[str] = typer.Argument(..., help="List of Modules to uninstall"),
16
+ ):
17
+ """
18
+ Uninstall Given Modules from Odoo via shell.
19
+ """
20
+ module_list_str = str(list(module_list))
21
+ uninstall_cmd = f"env['ir.module.module'].search([('name','in',{module_list_str})]).filtered(lambda m: m.state not in ['uninstallable','uninstalled']).button_immediate_uninstall()"
22
+ uninstall_shell = f'echo "{uninstall_cmd}" | {str(ctx.obj.odoo_main_path.absolute())}/odoo-bin shell -c {str(ctx.obj.odoo_conf_path.absolute())} --no-http'
23
+ LOGGER.info("Launching Uninstaller: '%s'", uninstall_shell)
24
+ ret = os.system(uninstall_shell)
25
+ return typer_retuner(ret)
26
+
27
+
28
+ @typer_unpacker
29
+ def odoo_shell(
30
+ ctx: typer.Context,
31
+ pipe_in_command: str = typer.Argument(""),
32
+ ):
33
+ """
34
+ Start Odoo session in an Interactive shell.
35
+ """
36
+ shell_cmd = (
37
+ f"{str(ctx.obj.odoo_main_path.absolute())}/odoo-bin shell -c {str(ctx.obj.odoo_conf_path.absolute())} --no-http"
38
+ )
39
+ if pipe_in_command:
40
+ shell_cmd = f'echo "{pipe_in_command}" |' + shell_cmd
41
+ LOGGER.debug("Running Command: %s", shell_cmd)
42
+ os.system(shell_cmd)
@@ -0,0 +1,164 @@
1
+ import configparser
2
+ import logging
3
+ import shutil
4
+ import zipfile
5
+ from enum import Enum
6
+ from pathlib import Path
7
+ from typing import List
8
+
9
+ import typer
10
+ from ruamel.yaml import YAML
11
+
12
+ from ..git import GitUrl, git_ensure_addon_repos, git_ensure_odoo_repo
13
+ from ..helpers import download_file
14
+ from ..helpers.cli import typer_unpacker
15
+ from ..helpers.odoo_files import get_odoo_addons_in_folder
16
+ from ..helpers.repospec import remove_unused_folders
17
+
18
+ LOGGER = logging.getLogger(__name__)
19
+
20
+
21
+ class UpdateMode(str, Enum):
22
+ all = "all"
23
+ zip = "zip"
24
+ odoo = "odoo"
25
+ thirdparty = "thirdparty"
26
+
27
+
28
+ def unzip_addons(zip_folder: Path, target_addon_folder: Path, remove_excess: bool = False):
29
+ """Take .zip files from zip_folder and extracts them into the odoo addons folder.
30
+
31
+ Parameters
32
+ ----------
33
+ zip_folder : Path
34
+ Where to look for zip files
35
+ target_addon_folder : Path
36
+ where to place them
37
+ remove_excess : bool , optional
38
+ remove all and then unzip, by default False
39
+ """
40
+ if remove_excess:
41
+ for folder in target_addon_folder.iterdir():
42
+ shutil.rmtree(folder)
43
+ LOGGER.info("Extracting Zip Addons to: %s", target_addon_folder)
44
+ for zip_file in zip_folder.glob("*.zip"):
45
+ target_addon_folder.mkdir(exist_ok=True, parents=True)
46
+ LOGGER.info("Extracting Zip Addon: %s", zip_file)
47
+ with zipfile.ZipFile(zip_file, "r") as zip_ref:
48
+ zip_ref.extractall(target_addon_folder)
49
+
50
+
51
+ def update_odoo_conf_addon_paths(odoo_conf: Path, addon_paths: List[Path]):
52
+ """Update Odoo.Conf with Addon Paths
53
+
54
+ Parameters
55
+ ----------
56
+ odoo_conf : Path
57
+ odoo.conf location
58
+ addon_paths : List[Path]
59
+ list of paths
60
+ """
61
+ config = configparser.ConfigParser()
62
+ config.read(odoo_conf)
63
+ addon_paths = ",".join([str(p.absolute()) for p in addon_paths])
64
+ config["options"]["addons_path"] = addon_paths
65
+ LOGGER.info("Writing Addon Paths to Odoo Config.")
66
+ LOGGER.debug(addon_paths)
67
+ config.write(odoo_conf.open("w"))
68
+
69
+
70
+ @typer_unpacker
71
+ def get_source_file(
72
+ repospec_yml: Path = typer.Option(
73
+ "", envvar="ODOO_GITSPEC", help="godoo Repospec path, when downloading odoo source (skip repo_url)"
74
+ ),
75
+ repo_url: str = typer.Option("", help="git repo url, for specific repo (skip repospec_yml)"),
76
+ file_ref: str = typer.Option("", help="When not using repospec. File Branch, Commit, Tag..."),
77
+ file_path: str = typer.Option(..., help="Relative Filepath in Repository"),
78
+ save_path: Path = typer.Option(..., file_okay=True, dir_okay=False, help="Where to write the file"),
79
+ ):
80
+ """Get Raw file from git remote.
81
+ Either from the Odoo Repo defined in repospec file or from a custom Git remote.
82
+ """
83
+
84
+ if not repo_url and not repospec_yml:
85
+ raise ValueError("Need to provide either repospec_yml or repo_url")
86
+ if repospec_yml and not repo_url:
87
+ repospec = YAML().load(repospec_yml.resolve())
88
+ odoo_spec = repospec["odoo"]
89
+ repo_url = odoo_spec["url"]
90
+ file_ref = odoo_spec.get("commit") or odoo_spec.get("branch")
91
+ if not file_ref:
92
+ raise ValueError(
93
+ "Need to provide file ref. If you provided a repospec, make sure there is a branch or commit key in the odoo section"
94
+ )
95
+ git_url = GitUrl(repo_url)
96
+ file_url = git_url.get_file_raw_url(ref=file_ref, file_path=file_path)
97
+
98
+ return download_file(url=file_url, save_path=save_path)
99
+
100
+
101
+ @typer_unpacker
102
+ def get_source(
103
+ ctx: typer.Context,
104
+ repospec_yml: Path = typer.Option(
105
+ ..., envvar="ODOO_GITSPEC", help="Git.yml file, that specified what to download with wich prefix"
106
+ ),
107
+ thirdparty_addon_path: Path = typer.Option(
108
+ ..., envvar="ODOO_THIRDPARTY_LOCATION", help="Root folder of the Thirdparty addon repos"
109
+ ),
110
+ thirdparty_zip_source: Path = typer.Option(
111
+ ..., envvar="ODOO_THIRDPARTY_ZIP_LOCATION", help="Source folder, where to look for Addon zips"
112
+ ),
113
+ update_mode: UpdateMode = typer.Option(UpdateMode.all, help="What to Update"),
114
+ add_compare_comments: bool = typer.Option(
115
+ False, help="Wether to add github.com three dot compare links as comments."
116
+ ),
117
+ remove_unspecified_addons: bool = typer.Option(
118
+ False, help="Remove Addon folders that are not in YML or thirdparty.zip"
119
+ ),
120
+ force_fetch: bool = typer.Option(
121
+ False,
122
+ help="Forces origin fetch, regardless of current branch or commit sha (may be slow)",
123
+ ),
124
+ ):
125
+ """Update Odoo Source and Thirdparty source."""
126
+ LOGGER.info("Updating Addon Repos")
127
+ zip_addon_path = thirdparty_addon_path / "custom"
128
+
129
+ if update_mode in ["all", "zip"]:
130
+ unzip_addons(thirdparty_zip_source, zip_addon_path)
131
+
132
+ if update_mode in ["all", "odoo"]:
133
+ git_ensure_odoo_repo(
134
+ target_folder=ctx.obj.odoo_main_path,
135
+ repo_spec_file=repospec_yml,
136
+ force_fetch=force_fetch,
137
+ add_compare_comment=add_compare_comments,
138
+ download_archive=ctx.obj.source_download_archive,
139
+ )
140
+
141
+ if update_mode in ["all", "thirdparty"]:
142
+ git_repos = git_ensure_addon_repos(
143
+ root_folder=thirdparty_addon_path,
144
+ git_yml_path=repospec_yml,
145
+ generate_yml_compare_comments=add_compare_comments,
146
+ download_archive=ctx.obj.source_download_archive,
147
+ )
148
+ if remove_unspecified_addons:
149
+ remove_unused_folders(
150
+ thirdparty_addon_path=thirdparty_addon_path,
151
+ thirdparty_repos=git_repos.get("thirdparty", []),
152
+ keep_folders=[zip_addon_path],
153
+ )
154
+
155
+ if (conf_path := ctx.obj.odoo_conf_path).exists():
156
+ odoo_addon_paths = [ctx.obj.odoo_main_path / "addons"]
157
+ if get_odoo_addons_in_folder(ctx.obj.workspace_addon_path):
158
+ odoo_addon_paths.append(ctx.obj.workspace_addon_path)
159
+ if get_odoo_addons_in_folder(zip_addon_path):
160
+ odoo_addon_paths.append(zip_addon_path)
161
+ odoo_addon_paths += [
162
+ p for p in thirdparty_addon_path.iterdir() if p.is_dir() and not p.resolve() == zip_addon_path.resolve()
163
+ ]
164
+ update_odoo_conf_addon_paths(odoo_conf=conf_path, addon_paths=odoo_addon_paths)
@@ -0,0 +1,91 @@
1
+ import logging
2
+ import re
3
+ from pathlib import Path
4
+ from typing import List
5
+
6
+ import typer
7
+
8
+ from ..helpers.cli import typer_retuner
9
+ from ..helpers.odoo_files import get_changed_modules, get_depends_of_modules, get_odoo_addons_in_folder
10
+ from .launch import launch_odoo as launch_odoo
11
+
12
+ LOGGER = logging.getLogger(__name__)
13
+
14
+
15
+ def _test_modules_special_cases(in_modules: List[str], workspace_addon_path: Path):
16
+ if len(in_modules) == 1:
17
+ command = in_modules[0]
18
+ out_modules = []
19
+ if command == "all":
20
+ out_modules = get_odoo_addons_in_folder(workspace_addon_path)
21
+
22
+ if re_match := re.match(r"changes\:(.*)", command):
23
+ compare_branch = re_match.group(1)
24
+ changed_modules = get_changed_modules(addon_path=workspace_addon_path, diff_branch=compare_branch)
25
+ if not changed_modules:
26
+ return []
27
+ out_modules = get_depends_of_modules(workspace_addon_path, changed_modules)
28
+ if out_modules:
29
+ out_modules_with_tests = [p for p in out_modules if any(p.rglob("tests/__init__.py"))]
30
+ return [p.stem for p in out_modules_with_tests]
31
+ return in_modules
32
+
33
+
34
+ def odoo_test(
35
+ ctx: typer.Context,
36
+ test_modules: List[str] = typer.Argument(
37
+ ...,
38
+ help="Modules to install and test (Use 'all' for all Workspace modules), ('changes:<branch> to compare git changes)",
39
+ ),
40
+ skip_test_modules: List[str] = typer.Option(
41
+ [], envvar="ODOO_TEST_SKIP_MODULES", help="Modules not to Test even if specified in test_modules"
42
+ ),
43
+ odoo_log_level: str = typer.Option("test", help="Log level"),
44
+ ):
45
+ workspace_addon_path = ctx.obj.workspace_addon_path
46
+
47
+ test_modules = _test_modules_special_cases(test_modules, workspace_addon_path)
48
+
49
+ skip_test_modules = [m for m in skip_test_modules if m in test_modules] # Filter out skip mods that arent requested
50
+ if skip_test_modules:
51
+ LOGGER.info("Skipping Tests for Modules:\n%s", ", ".join(["\t" + m for m in skip_test_modules]))
52
+ test_modules = [m for m in test_modules if m not in skip_test_modules]
53
+
54
+ if not test_modules:
55
+ LOGGER.info("Nothing to Test. Skipping.")
56
+ return
57
+
58
+ test_module_list = ",".join(["/" + m for m in test_modules])
59
+ module_list = ",".join(test_modules)
60
+
61
+ LOGGER.info("Testing Odoo Modules:\n%s", "\n".join(sorted(["\t" + m for m in test_modules])))
62
+
63
+ bootstrap_args = [
64
+ "--test-enable",
65
+ f"--init {module_list}",
66
+ ]
67
+ if re.search("(sale|account)", test_module_list, re.IGNORECASE):
68
+ bootstrap_args[-1] += ",l10n_generic_coa"
69
+
70
+ bootstrap_args.append(f"--test-tags {test_module_list}")
71
+ bootstrap_args.append("--load-language en_US")
72
+ launch_args = [
73
+ f"-u {module_list}",
74
+ "--test-enable",
75
+ f"--log-level {odoo_log_level}",
76
+ "--stop-after-init",
77
+ "--no-http",
78
+ f"--test-tags {test_module_list}",
79
+ ]
80
+
81
+ ret = launch_odoo(
82
+ ctx=ctx,
83
+ install_workspace_addons=False,
84
+ extra_args=launch_args,
85
+ extra_bootstrap_args=bootstrap_args,
86
+ launch=False,
87
+ multithread_worker_count=0,
88
+ odoo_demo=True,
89
+ update_source=False,
90
+ )
91
+ return typer_retuner(ret)
@@ -0,0 +1,4 @@
1
+ from .git_odoo import git_ensure_odoo_repo
2
+ from .git_odoo_addons import git_ensure_addon_repos
3
+ from .git_repo import git_ensure_repo
4
+ from .git_url import GitUrl
@@ -0,0 +1,45 @@
1
+ import logging
2
+ from pathlib import Path
3
+
4
+ from ..helpers.repospec import yaml_add_compare_commit, yaml_remove_compare_commit, yaml_roundtrip_loader
5
+ from .git_repo import git_ensure_repo
6
+
7
+ LOGGER = logging.getLogger(__name__)
8
+
9
+
10
+ def git_ensure_odoo_repo(
11
+ target_folder: Path,
12
+ repo_spec_file: Path,
13
+ force_fetch: bool,
14
+ add_compare_comment: bool,
15
+ download_archive: bool,
16
+ ):
17
+ yaml = yaml_roundtrip_loader()
18
+ git_repos = yaml.load(repo_spec_file.resolve())
19
+ if not git_repos:
20
+ raise FileNotFoundError(f"Couldnt load yml file from: {str(repo_spec_file)}")
21
+
22
+ odoo_data = git_repos.get("odoo")
23
+ if not odoo_data:
24
+ raise KeyError(f"Could not find key 'odoo' in {str(repo_spec_file)}")
25
+
26
+ odoo_url = odoo_data["url"]
27
+ odoo_branch = odoo_data.get("branch", "master")
28
+ odoo_commit = odoo_data.get("commit", "")
29
+ if add_compare_comment:
30
+ yaml_add_compare_commit(odoo_data, odoo_branch)
31
+ else:
32
+ yaml_remove_compare_commit(odoo_data)
33
+
34
+ git_ensure_repo(
35
+ target_folder=target_folder,
36
+ repo_src=odoo_url,
37
+ branch=odoo_branch,
38
+ commit=odoo_commit,
39
+ pull=force_fetch,
40
+ zip_mode=download_archive,
41
+ filter="blob:none",
42
+ single_branch=True,
43
+ )
44
+
45
+ yaml.dump(git_repos, repo_spec_file)