gOdoo-cli 0.2.0__tar.gz → 0.3.4__tar.gz

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.
Files changed (34) hide show
  1. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/PKG-INFO +1 -1
  2. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/pyproject.toml +1 -1
  3. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/setup.py +1 -1
  4. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/__init__.py +1 -1
  5. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/cli.py +4 -8
  6. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/commands/__init__.py +1 -1
  7. godoo_cli-0.3.4/src/godoo_cli/commands/config.py +37 -0
  8. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/commands/launch.py +6 -17
  9. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/commands/rpc/importer.py +13 -14
  10. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/commands/source_get.py +1 -1
  11. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/git/git_repo.py +69 -27
  12. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/helpers/system.py +5 -0
  13. godoo_cli-0.2.0/src/godoo_cli/commands/makedev.py +0 -138
  14. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/LICENSE +0 -0
  15. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/README.md +0 -0
  16. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/__main__.py +0 -0
  17. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/commands/bootstrap.py +0 -0
  18. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/commands/rpc/__init__.py +0 -0
  19. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/commands/rpc/cli.py +0 -0
  20. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/commands/rpc/cli_callbacks.py +0 -0
  21. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/commands/rpc/modules.py +0 -0
  22. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/commands/rpc/translations.py +0 -0
  23. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/commands/shell.py +0 -0
  24. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/commands/test.py +0 -0
  25. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/git/__init__.py +0 -0
  26. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/git/git_odoo.py +0 -0
  27. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/git/git_odoo_addons.py +0 -0
  28. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/git/git_url.py +0 -0
  29. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/git/zip_download.py +0 -0
  30. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/helpers/__init__.py +0 -0
  31. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/helpers/bootstrap.py +0 -0
  32. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/helpers/cli.py +0 -0
  33. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/helpers/odoo_files.py +0 -0
  34. {godoo_cli-0.2.0 → godoo_cli-0.3.4}/src/godoo_cli/helpers/odoo_manifest.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: godoo-cli
3
- Version: 0.2.0
3
+ Version: 0.3.4
4
4
  Summary: Wrapper around Odoo-Bin with some convinience RPC functions.
5
5
  Home-page: https://github.com/OpenJKSoftware/gOdoo
6
6
  License: LGPL-3
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "gOdoo-cli"
3
- version = "0.2.0"
3
+ version = "0.3.4"
4
4
  description = "Wrapper around Odoo-Bin with some convinience RPC functions."
5
5
  authors = ["Joshua Kreuder <Joshua_Kreuder@outlook.com>"]
6
6
  license = "LGPL-3"
@@ -40,7 +40,7 @@ entry_points = \
40
40
 
41
41
  setup_kwargs = {
42
42
  'name': 'godoo-cli',
43
- 'version': '0.2.0',
43
+ 'version': '0.3.4',
44
44
  'description': 'Wrapper around Odoo-Bin with some convinience RPC functions.',
45
45
  'long_description': '# gOdoo Dev Environment\n\n![OdooLogo](https://raw.githubusercontent.com/OpenJKSoftware/gOdoo/main/assets/odoo_logo.png)\n![ComposeLogo](https://raw.githubusercontent.com/docker/compose/v2/logo.png)\n\n[<img src="https://raw.githubusercontent.com/OpenJKSoftware/gOdoo/main/assets/godoo-main-cli.png" width="1000"/>](image.png)\n\n**gOdoo** is short for **go Odoo**. \\\nIt is a [Vscode Devcontainer](https://code.visualstudio.com/docs/remote/containers) Environment for [Odoo](https://odoo.com/)\nwith Python CLI `godoo` convenience wrapper around `odoo-bin`.\n\nThis repository is the base source for the Python package [godoo-cli](https://pypi.org/project/godoo-cli/) and serves as\nan all batteries included development environment.\n\nMade Possible by: [WEMPE Elektronic GmbH](https://wetech.de)\n\n# gOdoo-cli\n\nPython package that provides `godoo` command line interface around `odoo-bin`.\n\nIt\'s build with [Typer](https://github.com/tiangolo/typer) to provide some convenience Wrappers for Odoo development and\nDeployment.\n\nMost flags can be configured by Env variables. \\\nUse `godoo --help` to find out more. HINT: Install tab-completion with `godoo --install-completion`\n\n# Docker\n\nThis workspace also contains Docker and Docker-Compose files. \\\n\nThey are used to provide either easy Odoo instances where the source is pulled according to\n[ODOO_MANIFEST.yml](./ODOO_MANIFEST.yml), or as a all batteries included devcontainer for VScode.\n\n## Requirements\n\n- [Docker Compose](https://github.com/docker/compose)\n- [Traefik](https://doc.traefik.io/traefik/) container running with docker provider and "traefik" named docker network.\n Example: [Traefik Devproxy](https://github.com/joshkreud/traefik_devproxy)\n- SSH Agent running. (check `echo $SSH_AUTH_SOCK`)\\\n This gets passed trough in the Buildprocess to clone Thirdparty repos.\n\n## Just wanna have a quick and easy Odoo Instance?\n\n```bash\ngit clone https://github.com/OpenJKSoftware/gOdoo\ncd godoo\n. scripts/container_requirements.sh # Check Requirements\ndocker-compose build\ndocker-compose up\n# wait......\n# wait a bit mode ...\n# just a little bit longer ..\n# There we go.\n# Odoo should be reachable on \'https://godoo.docker.localhost\' assuming you didn\'t change .env TRAEFIK_HOST_RULE or COMPOSE_PROJECT_NAME\n```\n\n# Devcontainer\n\n## Features\n\n- All batteries included [Devcontainer](https://code.visualstudio.com/docs/remote/containers) with postgres service\n Container and local DNS resolvig managed by [Traefik](https://doc.traefik.io/traefik/).\n- Easy fully working Odoo instance by `docker-compose up` with https access.\n- `godoo` CLI wrapper around Odoo. (Most flags can be configured by Environment Variables and are already preconfigured\n in the Containers. See [.env.sample](./.env.sample))\n- `odoo-bin` is added to PATH and can thus be invoked from every folder.\n- Odoo will run in Proxy_Mode behind a Traefik reverse proxy for easy access on\n `https://$COMPOSE_PROJECT_NAME.docker.localhost`\n- [Odoo Pylint plugin](https://github.com/OCA/pylint-odoo) preconfigured in vscode\n- Preinstalled vscode Extensions Highlights:\n - [SQL Tools](https://marketplace.visualstudio.com/items?itemName=mtxr.sqltools) with preconfigured connection for\n easy Database access in the Sidebar.\n - [Docker Extension](https://marketplace.visualstudio.com/items?itemName=ms-azuretools.vscode-docker) controls\n container host.\n - [Odoo Snippets](https://marketplace.visualstudio.com/items?itemName=mstuttgart.odoo-snippets)\n - [Odoo Developments](https://marketplace.visualstudio.com/items?itemName=scapigliato.vsc-odoo-development) can Grab\n Odoo Model information from a running Server\n - [Todo Tree](https://marketplace.visualstudio.com/items?itemName=Gruntfuggly.todo-tree)\n\n## Usage\n\n1. For Docker on windows: Clone the repo into the WSL2 Filesystem for better IO performance\n2. Have [Traefik](https://github.com/traefik/traefik) Running on `docker.localhost`\n [Example](https://github.com/joshkreud/traefik_devproxy) \\\n There must be a Docker network called `traefik` that can reach traefik.\n3. Open Devcontianer:\n - If you have the Devcontainer CLI: `devcontainer open .`\n - If not open the workspace in Local Vscode. In the Command pallete search for `Reopen in container`\n4. From **within the container** start Odoo using one of the following commands:\n - You can enable godoo tab-completion by `godoo --install-completion`\n - `make` -> Loads Odoo + Workspace Addons\n - `make bare` -> Loads Odoo with ony `web` installed.\n - `make kill` -> Search for `odoo-bin` processes and kill them\n - `make reset` -> Drops DB, deletes config file and datafolder\n - The full init script is available via "`godoo`". (See --help for Options)\n5. Open Odoo `https://$COMPOSE_PROJECT_NAME.docker.localhost`\\\n For example `COMPOSE_PROJECT_NAME=godoo` --> [https://godoo.docker.localhost](https://godoo.docker.localhost)\n6. Login with `admin:admin`\n7. Profit!\n\n### Access to Odoo and Thirdparty addon Source\n\nYou can access the Odoo source by opening the VsCode workspace [full.code-workspace](full.code-workspace) from within\nthe Container. This will open a [Multi-Root Workspace](https://code.visualstudio.com/docs/editor/multi-root-workspaces).\nReally waiting for https://github.com/microsoft/vscode-remote-release/issues/3665 here.\n\n## Reset Devcontainer Data\n\nWhen you screwed up so bad its time to just start Over godoo has you covered:\n\n### Automatic Reset\n\nThere are 3 Options to reset the Dev Env.\n\n1. From **Outside** the Container run `make reset` in the project root to delete docker volumes and restart the\n container. (Vscode will prompt to reconnect if still open)\n2. From **Outside** the Container run `make reset-hard` in the project root to force rebuild the main Odoo container and\n then do the same as `make reset`\n3. From **Inside** the Container run `make reset` to drop the DB and delete varlib and the bootstrap flag, which is way\n quicker than the other options.\n\n### Manual Reset\n\n1. Close vscode\n2. Remove `app` and `db` container from docker.\n3. Remove volumes: `db, odoo_thirdparty, odoo_web, vscode_extensions`\n4. Restart Devcontainer\n\n## Python Debugging\n\n### VsCode Debugging\n\nDebugging doesn\'t reliably work with\n[Odoo Multiprocess](https://www.odoo.com/documentation/14.0/developer/misc/other/cmdline.html#multiprocessing) mode\nenabled. \\\nThe container ships with a Vscode Debug profile, that sets `--workers 0` to allow for Debugging Breakpoints. See [.vscode/launch.json](./.vscode/launch.json)\n\n### Interactive Shell\n\nUse `godoo shell` to enter an interactive shell on the Database.\n\n# Odoo Modules\n\n## Third Party Modules (manifest.yml)\n\nThe `godoo` bootstrap function, will download some modules using git. \\\nWhich Repos to download is specified in `ODOO_MANIFEST.yml` ([Default](./ODOO_MANIFEST.yml)) \\\nNot all of the cloned addons are automatically installed. \\\nInstall them via the Apps Page in Odoo using `godoo rpc modules install` or using `odoo-bin`.\\\nModules downloaded on the Odoo Marketplace can be dropped as a `.zip` archive in [./thirdparty](./thirdparty)\n',
46
46
  'author': 'Joshua Kreuder',
@@ -1,2 +1,2 @@
1
- __version__ = "0.2.0"
1
+ __version__ = "0.3.4"
2
2
  from .cli import launch_cli
@@ -11,10 +11,10 @@ from .commands import (
11
11
  get_source_file,
12
12
  install_module_dependencies,
13
13
  launch_odoo,
14
- makedec_cli_app,
15
14
  odoo_shell,
16
15
  odoo_test,
17
16
  rpc_cli_app,
17
+ set_odoo_config,
18
18
  uninstall_modules,
19
19
  )
20
20
  from .helpers.system import set_logging
@@ -55,15 +55,11 @@ def main_cli():
55
55
  app.add_typer(
56
56
  typer_instance=rpc_cli_app(),
57
57
  name="rpc",
58
- help="Various RPC Wrappers",
59
- )
60
- app.add_typer(
61
- typer_instance=makedec_cli_app(),
62
- name="makedev",
63
- help="Set config and RPC settings to generate a staging environment",
58
+ help="Commands that act on a running Odoo instance through RPC",
64
59
  )
65
60
 
66
61
  # Normal Subcommands
62
+ app.command("config", help="Set odoo.conf options")(set_odoo_config)
67
63
  app.command("launch", help="Launch Odoo, Bootstrap if bootstrapflag is not present")(launch_odoo)
68
64
  app.command("bootstrap", help="Bootstrap Odoo")(bootstrap_odoo)
69
65
  app.command("source-get-file", help="Get Raw file from odoo git remote or specific git remote.")(get_source_file)
@@ -72,7 +68,7 @@ def main_cli():
72
68
  )
73
69
  app.command("source-get", help="Download/Unzip Odoo Source and thirdparty addons.")(get_source)
74
70
  app.command("test", help="Bootstrap or Launch odoo in Testing Mode")(odoo_test)
75
- app.command("shell", help="Shell into Odoo")(odoo_shell)
71
+ app.command("shell", help="Start interactive Odoo shell")(odoo_shell)
76
72
  app.command("uninstall", help="Uninstall Modules")(uninstall_modules)
77
73
  return app
78
74
 
@@ -1,6 +1,6 @@
1
1
  from .bootstrap import bootstrap_odoo
2
+ from .config import set_odoo_config
2
3
  from .launch import launch_odoo
3
- from .makedev import makedec_cli_app
4
4
  from .rpc import rpc_cli_app
5
5
  from .shell import odoo_shell, uninstall_modules
6
6
  from .source_get import get_source, get_source_file, install_module_dependencies
@@ -0,0 +1,37 @@
1
+ """
2
+ Set odoo.conf variables
3
+ """
4
+ import logging
5
+ from configparser import ConfigParser
6
+ from pathlib import Path
7
+ from typing import List
8
+
9
+ import typer
10
+
11
+ from ..helpers.cli import typer_unpacker
12
+
13
+ LOGGER = logging.getLogger(__name__)
14
+
15
+
16
+ @typer_unpacker
17
+ def set_odoo_config(
18
+ ctx: typer.Context,
19
+ options: List[str] = typer.Argument(..., help="odoo.conf options by key=value"),
20
+ ):
21
+ """
22
+ Set odoo.conf values.
23
+ """
24
+ conf_path = Path(ctx.obj.odoo_conf_path)
25
+ odoo_conf = ConfigParser()
26
+ odoo_conf.read(conf_path)
27
+ LOGGER.info("Setting Odoo Conf Options for Stage")
28
+ custom_opts = {}
29
+ for op in options:
30
+ if "=" not in op:
31
+ LOGGER.error("Cannot parse Option: '%s' --> missing = sign", op)
32
+ raise ValueError("")
33
+ op_split = op.split("=")
34
+ custom_opts[op_split[0]] = op_split[1]
35
+ LOGGER.debug("Writing Conf Options: %s", custom_opts)
36
+ odoo_conf["options"].update(custom_opts)
37
+ odoo_conf.write(conf_path.open("w"))
@@ -10,7 +10,6 @@ from ..helpers.cli import typer_retuner, typer_unpacker
10
10
  from ..helpers.odoo_files import get_odoo_module_paths
11
11
  from ..helpers.system import run_cmd
12
12
  from .bootstrap import bootstrap_odoo
13
- from .makedev import makedev_config, makedev_rpc
14
13
  from .rpc import import_to_odoo
15
14
 
16
15
  LOGGER = logging.getLogger(__name__)
@@ -62,8 +61,7 @@ def launch_odoo(
62
61
  install_workspace_addons: bool = typer.Option(True, help="Install Workspace addons"),
63
62
  update_source: bool = typer.Option(True, help="Git Pull Addons"),
64
63
  addons_remove_unspecified: bool = typer.Option(True, help="Cleanup/Remove unspecified Addons"),
65
- load_data_path: Path = typer.Option(None, help="Starts Async Importer Job with provided path"),
66
- prep_stage: bool = typer.Option(False, help="Starts Async Stage Prepper"),
64
+ load_data_path: List[Path] = typer.Option(None, help="Starts Async Importer Job with provided path(s)"),
67
65
  extra_args: List[str] = typer.Option([], help="Extra args to Pass to odoo Launch"),
68
66
  extra_bootstrap_args: List[str] = typer.Option([], help="Extra args to Pass to odoo Bootstrap"),
69
67
  log_file_path: Path = typer.Option(None, dir_okay=False, writable=True, help="Logfile Path"),
@@ -79,8 +77,6 @@ def launch_odoo(
79
77
  log_file_path.unlink(missing_ok=True)
80
78
  extra_odoo_args.append("--logfile " + str(log_file_path.absolute()))
81
79
 
82
- if ctx.obj.odoo_conf_path.exists() and prep_stage:
83
- makedev_config(ctx)
84
80
  LOGGER.info("Bootstrap Flag Status: %s", ctx.obj.bootstrap_flag_location.exists())
85
81
  bootstraped = False
86
82
  ret = ""
@@ -110,29 +106,22 @@ def launch_odoo(
110
106
  extra_odoo_args += ea
111
107
 
112
108
  if dev_mode:
113
- extra_odoo_args.append("--dev xml,qweb" if load_data_path else "--dev xml,qweb,reload")
109
+ extra_odoo_args.append(
110
+ "--dev xml,qweb" if load_data_path else "--dev xml,qweb,reload"
111
+ ) # Prevent server restart if Importer threads will be spawned.
114
112
 
115
113
  if bootstraped and not launch:
116
114
  return typer_retuner(ret)
117
115
 
118
116
  rpc_callback(ctx) # Add RPC Options using Defaults and Envvars
119
117
 
120
- if prep_stage:
121
- LOGGER.info("Starting Stage Prepper Thread")
122
- loader_thread = threading.Thread(
123
- target=makedev_rpc,
124
- args=(ctx,),
125
- name="Stage Cutter",
126
- )
127
- loader_thread.start()
128
-
129
118
  if load_data_path:
130
- LOGGER.info("Starting Data Importer Thread")
119
+ LOGGER.info("Starting Data Importer Thread for: '%s'", ", ".join(map(str, load_data_path)))
131
120
  loader_thread = threading.Thread(
132
121
  target=import_to_odoo,
133
122
  name="DataLoader",
134
123
  args=(ctx,),
135
- kwargs={"read_path": load_data_path.absolute()},
124
+ kwargs={"read_paths": load_data_path},
136
125
  )
137
126
  loader_thread.start()
138
127
 
@@ -6,6 +6,7 @@ Places Systemparam to Track if import was already done.
6
6
 
7
7
  import logging
8
8
  from pathlib import Path
9
+ from typing import List
9
10
 
10
11
  import typer
11
12
  from godoo_rpc import import_data
@@ -21,7 +22,7 @@ LOGGER = logging.getLogger(__name__)
21
22
  @typer_unpacker
22
23
  def import_to_odoo(
23
24
  ctx: typer.Context,
24
- read_path: Path = typer.Argument(
25
+ read_paths: List[Path] = typer.Argument(
25
26
  ...,
26
27
  readable=True,
27
28
  exists=True,
@@ -53,18 +54,16 @@ def import_to_odoo(
53
54
  odoo_user=ctx.obj.odoo_rpc_user,
54
55
  odoo_password=ctx.obj.odoo_rpc_password,
55
56
  )
56
- if not read_path.exists():
57
- raise ValueError("Provided import Path: %s doesn't exist", read_path)
58
57
 
59
- if read_path.is_file():
60
- product_image_regex = ""
61
- file_regex = ""
58
+ if missing_paths := [p for p in read_paths if not p.exists()]:
59
+ raise ValueError("Provided import Paths: %s doesn't exist", ", ".join(missing_paths))
62
60
 
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
- )
61
+ for path in read_paths:
62
+ import_data(
63
+ odoo_api=odoo_api,
64
+ read_path=path.absolute(),
65
+ data_regex=file_regex,
66
+ product_image_regex="" if path.is_file() else product_image_regex,
67
+ check_dataset_timestamp="" if path.is_file() else check_data_timestamp,
68
+ skip_existing_ids=skip_existing_ids,
69
+ )
@@ -39,13 +39,13 @@ def unpack_addon_archives(archive_folder: Path, target_addon_folder: Path, remov
39
39
  remove_excess : bool , optional
40
40
  remove all and then unzip, by default False
41
41
  """
42
+ target_addon_folder.mkdir(exist_ok=True, parents=True)
42
43
  if remove_excess:
43
44
  LOGGER.debug("Clearing out unarchive folder: %s", target_addon_folder)
44
45
  for folder in target_addon_folder.iterdir():
45
46
  shutil.rmtree(folder)
46
47
  LOGGER.info("Extracting archive addons to: %s", target_addon_folder)
47
48
  for zip_file in archive_folder.glob("*.zip"):
48
- target_addon_folder.mkdir(exist_ok=True, parents=True)
49
49
  LOGGER.info("Extracting addon archive: %s", zip_file)
50
50
  with tempfile.TemporaryDirectory() as td:
51
51
  td = Path(td)
@@ -1,7 +1,9 @@
1
+ """ Module to provide GIT interaction."""
1
2
  import logging
3
+ import shutil
2
4
  from pathlib import Path
3
5
 
4
- from git import InvalidGitRepositoryError, Repo
6
+ from git import GitCommandError, InvalidGitRepositoryError, Repo
5
7
 
6
8
  from .git_url import GitUrl
7
9
  from .zip_download import git_download_zip
@@ -9,6 +11,32 @@ from .zip_download import git_download_zip
9
11
  LOGGER = logging.getLogger(__name__)
10
12
 
11
13
 
14
+ def _git_clean_clone(repo_src: str, target_folder: Path, **kwargs):
15
+ """Clears targetfolder and does a clean clone_from
16
+
17
+ Parameters
18
+ ----------
19
+ repo_src : str
20
+ Clone url
21
+ target_folder : Path
22
+ Download folder
23
+ branch : str
24
+ branch to clone
25
+
26
+ Returns
27
+ -------
28
+ _type_re
29
+ _description_
30
+ """
31
+ LOGGER.debug("Cloning Repo: %s, to '%s', Kwargs: '%s'", repo_src, target_folder, kwargs)
32
+ if not isinstance(target_folder, Path):
33
+ target_folder = Path(target_folder)
34
+ if target_folder.exists():
35
+ LOGGER.debug("Clearing Repo folder: %s", target_folder)
36
+ shutil.rmtree(target_folder)
37
+ return Repo.clone_from(repo_src, target_folder, **kwargs)
38
+
39
+
12
40
  def git_pull_checkout_reset(
13
41
  repo: Repo, branch: str = "master", commit: str = "", pull: str = "", reset_hard: bool = True
14
42
  ):
@@ -27,27 +55,32 @@ def git_pull_checkout_reset(
27
55
  pull : str, optional
28
56
  specific target to pull. Usually used in conjunction with branch.
29
57
  reset_hard : bool, optional
30
- will call reset --hard after checkout to ensure clean git repo, by default True
58
+ will call reset --hard before checkout to ensure clean git repo, by default True
31
59
  """
32
60
 
33
- try:
34
- if pull:
35
- LOGGER.debug("Pulling Repo: %s, %s", repo.git_dir, pull)
61
+ if reset_hard:
62
+ repo.git.reset("--hard", "HEAD")
63
+
64
+ if pull:
65
+ LOGGER.debug("Pulling Repo: %s, %s", repo.working_dir, pull)
66
+ try:
36
67
  repo.remotes[0].pull(pull)
37
- if commit:
38
- if str(repo.head.commit) != str(commit):
39
- LOGGER.debug("Checking out %s to Commit: %s", repo.git_dir, commit)
40
- repo.git.checkout(commit)
41
- return
42
- if branch:
43
- LOGGER.debug("Checking Out repo %s to Branch: %s", repo.git_dir, branch)
44
- repo.git.checkout(branch)
45
- if reset_hard:
46
- repo.git.reset("--hard")
47
- except Exception as e:
48
- raise Exception(
49
- str(f"Error while ensuring Git repo: {str(repo)}, branch='{branch}', commit='{commit}', fetch='{pull}'")
50
- ) from e
68
+ except GitCommandError as e:
69
+ if "fatal: refusing to merge unrelated histories" in e.stderr:
70
+ clone_kwargs = {}
71
+ if branch:
72
+ clone_kwargs["branch"] = branch
73
+ repo = _git_clean_clone(repo.remotes[0].url, repo.working_dir, **clone_kwargs)
74
+ else:
75
+ raise e
76
+ if commit:
77
+ if str(repo.head.commit) != str(commit):
78
+ LOGGER.debug("Checking out %s to Commit: %s", repo.git_dir, commit)
79
+ repo.git.checkout(commit)
80
+ return
81
+ if branch:
82
+ LOGGER.debug("Checking Out repo %s to Branch: %s", repo.git_dir, branch)
83
+ repo.git.checkout(branch)
51
84
 
52
85
 
53
86
  def git_ensure_ref(
@@ -81,23 +114,32 @@ def git_ensure_ref(
81
114
  target_folder.mkdir(exist_ok=True, parents=True)
82
115
  try:
83
116
  repo = Repo(target_folder)
84
- current = repo.head.commit
117
+ current = str(repo.head.commit)
85
118
 
86
119
  if not pull and commit and str(commit) != str(current):
87
120
  pull = str(commit)
88
121
 
89
122
  if not pull and branch and not commit:
90
- pull = str(branch)
91
- git_pull_checkout_reset(repo=repo, branch=branch, commit=commit, pull=pull)
92
-
93
- if current == repo.head.commit:
123
+ remote_name = str(repo.remotes[0].name)
124
+ try:
125
+ remote_commit = repo.git.rev_parse(remote_name + "/" + str(branch))
126
+ except Exception:
127
+ remote_commit = "unknown"
128
+ LOGGER.debug(
129
+ "Repo: %s comparing local head '%s' with remote head '%s'", repo.working_dir, current, remote_commit
130
+ )
131
+ if str(remote_commit) != current:
132
+ pull = str(branch)
133
+
134
+ git_pull_checkout_reset(repo=repo, branch=branch, commit=commit, pull=pull)
135
+
136
+ if current == str(repo.head.commit):
94
137
  LOGGER.info("Repo Commit matches. Skipping: '%s' --> '%s'", repo_src, target_folder)
95
138
  else:
96
139
  LOGGER.info("Pulled Repo from: '%s'. Head is now at: %s", repo_src, repo.head.commit)
97
140
  except InvalidGitRepositoryError:
98
- LOGGER.debug("Cloning Repo: %s, to '%s', branch '%s'", repo_src, target_folder, branch)
99
- repo = Repo.clone_from(repo_src, target_folder, branch=branch, **kwargs)
100
- git_pull_checkout_reset(repo=repo, branch=branch, commit=commit, pull=pull)
141
+ repo = _git_clean_clone(repo_src, target_folder, branch=branch, **kwargs)
142
+ git_pull_checkout_reset(repo=repo, branch=branch, commit=commit, pull=False)
101
143
 
102
144
  LOGGER.info(
103
145
  "Cloned Repo: '%s'. Branch='%s' Head='%s'",
@@ -4,8 +4,12 @@ import os
4
4
  import subprocess
5
5
  from pathlib import Path
6
6
 
7
+ import click
7
8
  import requests
8
9
  from rich.logging import RichHandler
10
+ from rich.traceback import install as install_rich_traceback
11
+
12
+ from . import cli as godoo_cli_helpers
9
13
 
10
14
  LOGGER = logging.getLogger(__name__)
11
15
 
@@ -66,6 +70,7 @@ def set_logging(verbose: bool = False) -> None:
66
70
  verbose : bool
67
71
  Wether to Log debug Messages
68
72
  """
73
+ install_rich_traceback(suppress=[click, godoo_cli_helpers])
69
74
  if verbose:
70
75
  logging.basicConfig(
71
76
  level=logging.DEBUG,
@@ -1,138 +0,0 @@
1
- """
2
- Disconnects SMTP From odoo via Config.
3
- Disconnects Label Printers via RPC.
4
- Installs and configures Web Ribbon Banner.
5
- Disables Audit rules via RPC.
6
- """
7
-
8
- import logging
9
- from configparser import ConfigParser
10
-
11
- import typer
12
- from godoo_rpc.login import wait_for_odoo
13
-
14
- from ..commands.rpc.cli import rpc_callback
15
- from ..helpers.cli import typer_unpacker
16
-
17
- LOGGER = logging.getLogger(__name__)
18
-
19
-
20
- def remove_label_printers(odoo_api, printer_url="host.docker.internal"):
21
- """Set Odoo Label Printer URL.
22
-
23
- Parameters
24
- ----------
25
- odoo_api : _type_
26
- Logged in Odoo API
27
- printer_url : str, optional
28
- printer url, by default "host.docker.internal"
29
- """
30
- printer_env = odoo_api.session.env["wetech.label.printer"]
31
- l_printer_ids = printer_env.search([])
32
- l_printers = printer_env.browse(l_printer_ids)
33
- LOGGER.info("Setting Label Printer URL for %s Printers", len(l_printers))
34
- l_printers.write({"hostname": printer_url})
35
-
36
-
37
- def staging_banner(odoo_api, banner_text: str = "", banner_background_color: str = ""):
38
- """Set Odoo top left Banner.
39
-
40
- Parameters
41
- ----------
42
- odoo_api : _type_
43
- Logged in Odoo API
44
- banner_text : str, optional
45
- Text to display on banner, by default ""
46
- banner_background_color : str, optional
47
- rbg("","","",""), by default ""
48
- """
49
- mod = odoo_api.session.env["ir.module.module"]
50
- mod_ids = mod.search(["&", ("name", "in", ["web_environment_ribbon"]), ("state", "=", "uninstalled")])
51
- modules = mod.browse(mod_ids)
52
- if modules:
53
- LOGGER.info("Installing Modules: %s", ",".join(modules.mapped("name")))
54
- modules.button_immediate_install()
55
- param_env = odoo_api.session.env["ir.config_parameter"]
56
- ribbon_text_id = param_env.search([("key", "=", "ribbon.name")])
57
- param_env.browse(ribbon_text_id).value = banner_text
58
- LOGGER.info("Setting Banner Text to: %s", banner_text)
59
- ribbon_text_id = param_env.search([("key", "=", "ribbon.background.color")])
60
- param_env.browse(ribbon_text_id).value = banner_background_color
61
- LOGGER.info("Setting Banner background color: %s", banner_background_color)
62
-
63
-
64
- def disable_audit_logs(odoo_api):
65
- """Disable audit log rules.
66
-
67
- Parameters
68
- ----------
69
- odoo_api : _type_
70
- Logged in Odoo API
71
- """
72
- mod = odoo_api.session.env["auditlog.rule"]
73
- rule_ids = mod.search([("state", "=", "subscribed")])
74
- rules = mod.browse(rule_ids)
75
- if rules:
76
- LOGGER.info("Disabling '%s' audit log rules", len(rules))
77
- rules.unsubscribe()
78
-
79
-
80
- @typer_unpacker
81
- def makedev_config(ctx: typer.Context):
82
- """
83
- Set odoo.conf values for Staging Env.
84
- """
85
- odoo_conf = ConfigParser()
86
- odoo_conf.read(ctx.obj.odoo_conf_path)
87
- LOGGER.info("Setting Odoo Conf Options for Stage")
88
- odoo_conf["options"].update(
89
- {
90
- "smtp_server": "localhost",
91
- "smtp_password": "False",
92
- "smtp_user": "False",
93
- "logfile": "",
94
- "limit_memory_hard": "2684354560",
95
- "limit_memory_soft": "2147483648",
96
- "workers": "3",
97
- "max_cron_threads": "1",
98
- "limit_time_cpu": "36000",
99
- "limit_time_real": "42000",
100
- }
101
- )
102
-
103
- with ctx.obj.odoo_conf_path.open("w") as conf:
104
- odoo_conf.write(conf)
105
-
106
-
107
- @typer_unpacker
108
- def makedev_rpc(
109
- ctx: typer.Context,
110
- banner_text: str = typer.Option(
111
- "Development", envvar="ODOO_BANNER_TEXT", help="Text to display in Top left ribbon banner"
112
- ),
113
- banner_background_color: str = typer.Option(
114
- "rgba(255,0,0,.6)", envvar="ODOO_BANNER_BG_COLOR", help="Top left ribbon banner color"
115
- ),
116
- ):
117
- """
118
- Set some Odoo Options via RPC to disable prod features.
119
- """
120
-
121
- LOGGER.info("Starting Stagesplitter")
122
- odoo_api = wait_for_odoo(
123
- odoo_host=ctx.obj.odoo_rpc_host,
124
- odoo_db=ctx.obj.odoo_main_db,
125
- odoo_user=ctx.obj.odoo_rpc_user,
126
- odoo_password=ctx.obj.odoo_rpc_password,
127
- )
128
-
129
- remove_label_printers(odoo_api=odoo_api)
130
- staging_banner(odoo_api=odoo_api, banner_text=banner_text, banner_background_color=banner_background_color)
131
- disable_audit_logs(odoo_api=odoo_api)
132
-
133
-
134
- def makedec_cli_app():
135
- app = typer.Typer(callback=rpc_callback, no_args_is_help=True)
136
- app.command("rpc", help="Set odoo.conf values for Staging Env.")(makedev_rpc)
137
- app.command("config", help="Set some Odoo Options via RPC to disable prod features.")(makedev_config)
138
- return app
File without changes
File without changes