gOdoo-cli 0.14.3__tar.gz → 0.14.5__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 (103) hide show
  1. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.pre-commit-config.yaml +1 -1
  2. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/PKG-INFO +1 -1
  3. godoo_cli-0.14.5/addons/godoo_test_succ_mod/__init__.py +3 -0
  4. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/addons/godoo_test_succ_mod/models/__init__.py +2 -0
  5. godoo_cli-0.14.5/addons/godoo_test_succ_mod/tests/__init__.py +3 -0
  6. godoo_cli-0.14.5/addons/godoo_test_succ_mod/tests/data.py +10 -0
  7. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/addons/godoo_test_succ_mod/tests/test_succ.py +1 -1
  8. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/docker/Dockerfile +3 -2
  9. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/pyproject.toml +30 -4
  10. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/scripts/migrations/development/shrink_database.py +3 -2
  11. godoo_cli-0.14.5/src/godoo_cli/__about__.py +11 -0
  12. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/cli.py +2 -1
  13. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/backup/dump.py +7 -3
  14. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/backup/load.py +12 -9
  15. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/backup/pull.py +6 -6
  16. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/backup/util.py +5 -3
  17. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/bootstrap.py +11 -13
  18. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/config.py +5 -4
  19. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/db/connection.py +5 -4
  20. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/db/query.py +11 -12
  21. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/launch.py +20 -19
  22. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/rpc/importer.py +5 -3
  23. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/rpc/modules.py +5 -6
  24. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/rpc/translations.py +10 -8
  25. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/shell/scripts/odoo_banner.py +4 -5
  26. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/shell/shell.py +34 -15
  27. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/source_get.py +24 -20
  28. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/test/test_load_data.py +6 -6
  29. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/test/test_run.py +18 -11
  30. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/git/git_odoo.py +6 -2
  31. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/git/git_odoo_addons.py +4 -5
  32. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/git/git_repo.py +4 -3
  33. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/git/git_url.py +25 -16
  34. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/git/zip_download.py +3 -1
  35. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/helpers/cli.py +4 -2
  36. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/helpers/modules.py +40 -33
  37. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/helpers/modules_git.py +5 -6
  38. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/helpers/modules_py.py +4 -5
  39. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/helpers/odoo_files.py +3 -1
  40. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/helpers/odoo_manifest.py +8 -6
  41. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/helpers/pip.py +13 -10
  42. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/helpers/system.py +8 -8
  43. godoo_cli-0.14.3/addons/godoo_test_succ_mod/__init__.py +0 -1
  44. godoo_cli-0.14.3/addons/godoo_test_succ_mod/tests/__init__.py +0 -1
  45. godoo_cli-0.14.3/addons/godoo_test_succ_mod/tests/data.py +0 -10
  46. godoo_cli-0.14.3/src/godoo_cli/__about__.py +0 -11
  47. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.codecovrc +0 -0
  48. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.devcontainer/devcontainer.json +0 -0
  49. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.env.sample +0 -0
  50. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.eslintignore +0 -0
  51. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.eslintrc.yml +0 -0
  52. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.github/FUNDING.yml +0 -0
  53. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.github/workflows/README.md +0 -0
  54. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.github/workflows/quality.yml +0 -0
  55. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.github/workflows/version-bump.yml +0 -0
  56. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.github/workflows/version-publish.yml +0 -0
  57. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.gitignore +0 -0
  58. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.prettierrc.yml +0 -0
  59. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/.vscode/launch.json +0 -0
  60. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/LICENSE +0 -0
  61. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/README.md +0 -0
  62. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/addons/.gitkeep +0 -0
  63. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/addons/godoo_test_succ_mod/__manifest__.py +0 -0
  64. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/assets/godoo-main-cli.png +0 -0
  65. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/assets/odoo_logo.png +0 -0
  66. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/config/nginx.conf +0 -0
  67. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/config/postgresql.conf +0 -0
  68. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/config/supervisord.conf +0 -0
  69. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/docker/cups/Dockerfile +0 -0
  70. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/docker/cups/config/cups-pdf.conf +0 -0
  71. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/docker/cups/config/cupsd.conf +0 -0
  72. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/docker/cups/cups_entrypoint.sh +0 -0
  73. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/docker/depends_build.sh +0 -0
  74. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/docker/depends_runtime.sh +0 -0
  75. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/docker/docker-compose.base.yml +0 -0
  76. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/docker/docker-compose.devcontainer-traefik.yml +0 -0
  77. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/docker/docker-compose.devcontainer.yml +0 -0
  78. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/docker/docker-compose.traefik.yml +0 -0
  79. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/godoo_src.code-workspace +0 -0
  80. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/makefile +0 -0
  81. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/odoo_manifest.yml +0 -0
  82. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/scripts/container_requirements.sh +0 -0
  83. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/scripts/launchodoo.sh +0 -0
  84. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/scripts/reset_devcontainer.sh +0 -0
  85. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/__init__.py +0 -0
  86. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/__main__.py +0 -0
  87. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/cli_common.py +0 -0
  88. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/__init__.py +0 -0
  89. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/backup/__init__.py +0 -0
  90. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/backup/cli.py +0 -0
  91. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/db/__init__.py +0 -0
  92. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/db/cli.py +0 -0
  93. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/db/passwords.py +0 -0
  94. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/rpc/__init__.py +0 -0
  95. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/rpc/cli.py +0 -0
  96. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/rpc/config_parameters.py +0 -0
  97. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/test/__init__.py +0 -0
  98. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/commands/test/cli.py +0 -0
  99. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/git/__init__.py +0 -0
  100. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/godoo_cli/helpers/__init__.py +0 -0
  101. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/src/tests/test_git_clone.py +0 -0
  102. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/thirdparty/.gitkeep +0 -0
  103. {godoo_cli-0.14.3 → godoo_cli-0.14.5}/uv.lock +0 -0
@@ -49,7 +49,7 @@ repos:
49
49
  args: ["--fix"]
50
50
 
51
51
  - repo: https://github.com/astral-sh/ruff-pre-commit
52
- rev: v0.3.0
52
+ rev: v0.10.0
53
53
  hooks:
54
54
  - id: ruff
55
55
  args: [--fix]
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gOdoo-cli
3
- Version: 0.14.3
3
+ Version: 0.14.5
4
4
  Summary: Wrapper around Odoo-Bin with some convinience RPC functions.
5
5
  Project-URL: repository, https://github.com/OpenJKSoftware/gOdoo
6
6
  Author-email: Joshua Kreuder <Joshua_Kreuder@outlook.com>
@@ -0,0 +1,3 @@
1
+ """Test Succ Mod. (Module with all successful tests)."""
2
+
3
+ from . import models
@@ -1,3 +1,5 @@
1
+ """Models for the Test Succ Mod."""
2
+
1
3
  from logging import getLogger
2
4
 
3
5
  LOGGER = getLogger(__name__)
@@ -0,0 +1,3 @@
1
+ """Test Suite for the Test Succ Mod. (All tests are successful)."""
2
+
3
+ from . import test_succ
@@ -0,0 +1,10 @@
1
+ """Data Generation for the Test Succ Mod."""
2
+
3
+ from odoo import api
4
+
5
+
6
+ # pylint: disable=unused-argument
7
+ # ruff: noqa: ARG001
8
+ def generate_test_data(env: api.Environment):
9
+ """Generate Test Data for the ven Environment."""
10
+ # Add your Test Data Generation code here
@@ -3,4 +3,4 @@ from odoo.tests import TransactionCase
3
3
 
4
4
  class TestSucessfull(TransactionCase):
5
5
  def test_assert_true(self):
6
- self.assertTrue(True)
6
+ assert True
@@ -30,7 +30,8 @@ ARG VIRTUAL_ENV
30
30
  ARG USERNAME
31
31
  # Path Env Vars:
32
32
  ENV VIRTUAL_ENV=${VIRTUAL_ENV} \
33
- UV_PROJECT_ENVIRONMENT=${VIRTUAL_ENV}
33
+ UV_PROJECT_ENVIRONMENT=${VIRTUAL_ENV} \
34
+ UV_COMPILE_BYTECODE=1
34
35
  ENV PYTHONPATH="$ODOO_MAIN_FOLDER:$WORKSPACE:$PYTHONPATH" \
35
36
  PATH="$ODOO_MAIN_FOLDER:$WORKSPACE:$WORKSPACE/scripts:$VIRTUAL_ENV/bin:$PATH"
36
37
  RUN --mount=type=cache,target=$UV_CACHE_DIR,uid=1000,gid=1000 uv venv ${VIRTUAL_ENV}
@@ -51,7 +52,7 @@ COPY pyproject.toml uv.lock README.md ./
51
52
  RUN --mount=type=cache,target=$UV_CACHE_DIR,uid=1000,gid=1000 uv sync --no-install-project --compile-bytecode
52
53
 
53
54
  COPY --chown=$USERNAME:$USERNAME ./src ./src
54
- RUN --mount=type=cache,target=$UV_CACHE_DIR,uid=1000,gid=1000 uv sync --compile-bytecode
55
+ RUN --mount=type=cache,target=$UV_CACHE_DIR,uid=1000,gid=1000 uv sync --all-extras --compile-bytecode
55
56
  # In the Devcontainer stage we remove everything in $WORKSPACE and replace it with a Bind-Mount
56
57
  # ------------------------------------------------------------------------------------------------------
57
58
  # Godoo Pypi Install via pip
@@ -82,9 +82,9 @@ installer = "uv"
82
82
 
83
83
  # Linting commands
84
84
  lint = [
85
- "ruff check src",
86
- "ruff format --check src",
87
- "pylint src", # Keep pylint for Odoo-specific checks
85
+ "ruff check .",
86
+ "ruff format --check .",
87
+ "pylint .", # Keep pylint for Odoo-specific checks
88
88
  ]
89
89
 
90
90
  # Testing commands
@@ -102,6 +102,7 @@ ci = [
102
102
  [tool.ruff]
103
103
  line-length = 120
104
104
  target-version = "py39"
105
+ exclude = [".venv"]
105
106
 
106
107
  [tool.ruff.lint]
107
108
  select = [
@@ -112,11 +113,34 @@ select = [
112
113
  "C", # flake8-comprehensions
113
114
  "B", # flake8-bugbear
114
115
  "D", # pydocstyle
116
+ "ANN", # flake8-annotations (type hints)
117
+ "ARG", # flake8-unused-arguments
118
+ "COM", # flake8-commas
119
+ "DTZ", # flake8-datetimez
120
+ "EM", # flake8-errmsg (better error messages)
121
+ "ERA", # eradicate (commented out code)
122
+ "N", # pep8-naming
123
+ "PIE", # flake8-pie
124
+ "PT", # flake8-pytest-style
125
+ "RUF", # Ruff-specific rules
126
+ "SIM", # flake8-simplify
127
+ "TD", # flake8-todos
128
+ "TRY", # flake8-try-except-raise
129
+ "UP", # pyupgrade
115
130
  ]
116
131
  ignore = [
117
132
  "E203", # Whitespace before ':'
118
133
  "E266", # Too many leading '#' for block comment
119
134
  "E501", # Line too long (handled by formatter)
135
+ "ANN401", # Dynamically typed expressions (Any) are disallowed
136
+ "ANN201", # Missing return type for public method
137
+ "ANN202", # Missing type for private method
138
+ "TD002", # Missing author in TODO
139
+ "TD003", # Missing issue link in TODO
140
+ "COM812", # enforce trailing comma in broken up lists
141
+ "TRY003", # Dont enforce exception subclasses
142
+ "TRY201", # Allow reraise of caught exception
143
+ "DTZ006", # Datetime timezone requrement
120
144
  ]
121
145
 
122
146
  [tool.ruff.lint.pydocstyle]
@@ -129,6 +153,7 @@ skip-magic-trailing-comma = false
129
153
  line-ending = "auto"
130
154
 
131
155
  [tool.ruff.lint.per-file-ignores]
156
+ "__manifest__.py" = ["D101","D100","B018"]
132
157
  "__init__.py" = ["F401", "F403"] # Ignore unused and * imports in __init__.py files
133
158
  "tests/*" = ["S101", "D100", "D101", "D102", "D103", "D104", "D105", "D107"] # Ignore assert usage and docstrings in tests
134
159
  "test_*.py" = ["S101", "D100", "D101", "D102", "D103", "D104", "D105", "D107"] # Same for test files in any directory
@@ -136,7 +161,7 @@ line-ending = "auto"
136
161
 
137
162
  [tool.pylint.master]
138
163
  load-plugins = "pylint_odoo,pylint.extensions.no_self_use"
139
- ignore = ["CVS", ".git", ".hg", ".tox", ".eggs", "*.egg", "build", "dist"]
164
+ ignore = ["CVS", ".git", ".hg", ".tox", ".eggs", "*.egg", "build", "dist", ".venv"]
140
165
  persistent = true
141
166
  jobs = 0
142
167
 
@@ -177,6 +202,7 @@ enable = [
177
202
  "missing-return",
178
203
  "syntax-error",
179
204
  "undefined-variable",
205
+ "no-value-for-parameter", # E1120
180
206
  ]
181
207
 
182
208
  [tool.pylint.similarities]
@@ -4,7 +4,7 @@ from logging import getLogger
4
4
 
5
5
  LOGGER = getLogger("migrations.shrink_database")
6
6
 
7
- env = env # Just to silence pyright # pyright: ignore # NOQA
7
+ env = env # noqa: F821 # pylint: disable=undefined-variable # pyright: ignore
8
8
 
9
9
  LOGGER.info("Shrinking Database")
10
10
  att = env["ir.attachment"].search(
@@ -22,7 +22,8 @@ LOGGER.info("Attachments to Delete: %d", len(att))
22
22
  LOGGER.info("Size: %dMB", round(sum(att.mapped("file_size")) / 1024 / 1024, 2))
23
23
 
24
24
 
25
- def chunks(lst, n):
25
+ def chunks(lst: list, n: int):
26
+ """Chunk an iterable into chunks of size n."""
26
27
  for i in range(0, len(lst), n):
27
28
  yield lst[i : i + n]
28
29
 
@@ -0,0 +1,11 @@
1
+ """Version information."""
2
+
3
+ from packaging import version
4
+
5
+ __version__ = "0.14.5" # Initial version, will be managed by Hatch
6
+
7
+
8
+ def get_version_tuple() -> tuple[int, int, int]:
9
+ """Convert the version string into a tuple of integers."""
10
+ vers = version.parse(__version__)
11
+ return vers.major, vers.minor, vers.micro
@@ -5,6 +5,7 @@ It sets up the command structure, configures logging, and provides the core CLI
5
5
  for interacting with Odoo instances.
6
6
  """
7
7
 
8
+ from pathlib import Path
8
9
  from typing import Annotated, Optional
9
10
 
10
11
  import typer
@@ -34,7 +35,7 @@ from .helpers.system import set_logging
34
35
  CLI = CommonCLI()
35
36
 
36
37
 
37
- def print_versions(odoo_main_path=CLI.odoo_paths.bin_path):
38
+ def print_versions(odoo_main_path: Annotated[Path, CLI.odoo_paths.bin_path]):
38
39
  """Print gOdoo and Odoo Version info."""
39
40
  rich_print(f"gOdoo Version: [bold green]{__about__.__version__}[/bold green]")
40
41
  odoo_version = odoo_bin_get_version(odoo_main_path)
@@ -50,10 +50,14 @@ def dump_instance(
50
50
  port=db_port,
51
51
  )
52
52
  if not conf_path.exists():
53
- raise typer.Exit("No Odoo Conf Path provided or doesnt exists: '%s'" % conf_path)
53
+ msg = f"No Odoo Conf Path provided or doesnt exists: '{conf_path}'"
54
+ LOGGER.error(msg)
55
+ raise typer.Exit(msg)
54
56
 
55
57
  if not dump_path.exists():
56
- raise typer.Exit("No Dump Path provided or doesnt exists: %s" % dump_path)
58
+ msg = f"No Dump Path provided or doesnt exists: '{dump_path}'"
59
+ LOGGER.error(msg)
60
+ raise typer.Exit(msg)
57
61
 
58
62
  # Read .conf value [options] datad_dir
59
63
  parser = ConfigParser()
@@ -70,7 +74,7 @@ def dump_instance(
70
74
  db_dump_target = dump_path / "odoo.dump"
71
75
  LOGGER.info("Dumping DB -> %s", db_dump_target)
72
76
  db_dump_target.unlink(missing_ok=True)
73
- db_connection.run_psql_shell_command("pg_dump --format c {} > %s" % db_dump_target)
77
+ db_connection.run_psql_shell_command(f"pg_dump --format c {{}} > {db_dump_target}")
74
78
  LOGGER.info("SQL Dump Completed with size -> %.2f MB", db_dump_target.stat().st_size / (1024 * 1024))
75
79
 
76
80
  readme_path = dump_path / "README.md"
@@ -6,9 +6,9 @@ supporting various dump formats and handling database creation and restoration.
6
6
 
7
7
  import logging
8
8
  from pathlib import Path
9
+ from typing import Annotated, Optional
9
10
 
10
11
  import typer
11
- from typing_extensions import Annotated
12
12
 
13
13
  from ...cli_common import CommonCLI
14
14
  from ..db.connection import DBConnection
@@ -21,14 +21,16 @@ CLI = CommonCLI()
21
21
  def load_pg_dump(
22
22
  dump_path: Path,
23
23
  db_name: str,
24
- db_host: str = None,
24
+ db_host: Optional[str] = None,
25
25
  db_port: int = 0,
26
- db_user: str = None,
27
- db_password: str = None,
26
+ db_user: Optional[str] = None,
27
+ db_password: Optional[str] = None,
28
28
  ):
29
29
  """Drop and recreate db_name and restore dump_path into it."""
30
30
  if not dump_path.exists():
31
- raise FileNotFoundError("Cannot find Odoo Dump @ %s" % dump_path)
31
+ msg = f"Cannot find Odoo Dump @ {dump_path}"
32
+ LOGGER.error(msg)
33
+ raise FileNotFoundError(msg)
32
34
 
33
35
  conn = DBConnection(
34
36
  db_name="postgres",
@@ -49,10 +51,11 @@ def load_pg_dump(
49
51
  round(dump_path.stat().st_size / (1024 * 1024), 2),
50
52
  db_name,
51
53
  )
52
- if dump_path.suffix == ".dump":
53
- command = "pg_restore --no-owner --format c --dbname %s --jobs 8 {} %s" % (db_name, dump_path)
54
- else:
55
- command = "cat %s | psql {} >/dev/null" % dump_path
54
+ command = (
55
+ f"pg_restore --no-owner --format c --dbname {db_name} --jobs 8 {dump_path}"
56
+ if dump_path.suffix == ".dump"
57
+ else f"cat {dump_path} | psql {db_name} >/dev/null"
58
+ )
56
59
  load_return = conn.run_psql_shell_command(
57
60
  command=command,
58
61
  text=True,
@@ -7,10 +7,10 @@ supporting various transfer methods and backup formats.
7
7
  import logging
8
8
  import subprocess
9
9
  from pathlib import Path
10
+ from typing import Annotated, Optional
10
11
 
11
12
  import typer
12
13
  from rich.progress import track
13
- from typing_extensions import Annotated
14
14
 
15
15
  from ...cli_common import CommonCLI
16
16
  from ...helpers.system import typer_ask_overwrite_path
@@ -147,30 +147,30 @@ class InstancePuller:
147
147
  pg_db_user: Annotated[str, CLI.database.db_user],
148
148
  pg_db_name: Annotated[str, CLI.database.db_name],
149
149
  ssh_user: Annotated[
150
- str,
150
+ Optional[str],
151
151
  typer.Option(
152
152
  help="SSH User of remote instance.", rich_help_panel="Remote Options", envvar="ODOO_PULL_SSH_USER"
153
153
  ),
154
154
  ] = None,
155
155
  ssh_hostname: Annotated[
156
- str,
156
+ Optional[str],
157
157
  typer.Option(
158
158
  help="SSH Hostname of remote instance.", rich_help_panel="Remote Options", envvar="ODOO_PULL_HOST"
159
159
  ),
160
160
  ] = None,
161
161
  filestore_folder: Annotated[
162
- Path,
162
+ Optional[Path],
163
163
  typer.Option(help="Path to odoo web folder.", rich_help_panel="Filestore Options"),
164
164
  ] = None,
165
165
  filestore_volume: Annotated[
166
- str,
166
+ Optional[str],
167
167
  typer.Option(
168
168
  help="Alternative to valib-folder. A Docker volume name, that gets used to derive filestore-folder.",
169
169
  rich_help_panel="Filestore Options",
170
170
  ),
171
171
  ] = None,
172
172
  pg_container: Annotated[
173
- str,
173
+ Optional[str],
174
174
  typer.Option(
175
175
  help="Postgres Container Name. (Optional)",
176
176
  rich_help_panel="Database Options",
@@ -25,7 +25,9 @@ def call_rsync(source_folder: Path, target_folder: Path, rsync_delete: bool = Tr
25
25
  FileNotFoundError: If source folder doesn't exist or is empty.
26
26
  """
27
27
  if not source_folder.exists() and not source_folder.glob("*"):
28
- raise FileNotFoundError("Cannot find filestore Backup @ %s" % source_folder)
28
+ msg = f"Cannot find filestore Backup @ {source_folder}"
29
+ LOGGER.error(msg)
30
+ raise FileNotFoundError(msg)
29
31
  args = ["rsync", "-a", "--no-perms", "--no-owner", "--no-group", "--info=progress2"]
30
32
  if rsync_delete:
31
33
  args += ["--delete"]
@@ -40,7 +42,7 @@ def drop_db(connection: DBConnection, db_name: str):
40
42
  with connection.connect() as cur:
41
43
  cur.connection.autocommit = True
42
44
  LOGGER.info("Dropping DB: %s", db_name)
43
- cur.execute("DROP DATABASE IF EXISTS %s" % db_name)
45
+ cur.execute(f"DROP DATABASE IF EXISTS {db_name}")
44
46
 
45
47
 
46
48
  def create_db(connection: DBConnection, db_name: str):
@@ -48,4 +50,4 @@ def create_db(connection: DBConnection, db_name: str):
48
50
  with connection.connect() as cur:
49
51
  cur.connection.autocommit = True
50
52
  LOGGER.info("Creating DB: %s", db_name)
51
- cur.execute("CREATE DATABASE %s" % db_name)
53
+ cur.execute(f"CREATE DATABASE {db_name}")
@@ -9,13 +9,12 @@ import logging
9
9
  import os
10
10
  import re
11
11
  from pathlib import Path
12
- from typing import Any, List, Optional
12
+ from typing import Annotated, Any, Optional
13
13
 
14
14
  import typer
15
- from typing_extensions import Annotated
16
15
 
17
16
  from ..cli_common import CommonCLI
18
- from ..helpers.modules import get_addon_paths, godooModules
17
+ from ..helpers.modules import GodooModules, get_addon_paths
19
18
  from ..helpers.modules_py import _install_py_reqs_by_odoo_cmd
20
19
  from ..helpers.system import run_cmd
21
20
  from .db.connection import DBConnection
@@ -26,7 +25,7 @@ CLI = CommonCLI()
26
25
  LOGGER = logging.getLogger(__name__)
27
26
 
28
27
 
29
- def _add_default_argument(cmd_list: List[str], arg: str, arg_val: Any):
28
+ def _add_default_argument(cmd_list: list[str], arg: str, arg_val: Any):
30
29
  """Add a default argument to the command list if not already present.
31
30
 
32
31
  Args:
@@ -41,11 +40,11 @@ def _add_default_argument(cmd_list: List[str], arg: str, arg_val: Any):
41
40
  def _boostrap_command(
42
41
  odoo_main_path: Path,
43
42
  odoo_conf_path: Path,
44
- addon_paths: List[Path],
43
+ addon_paths: list[Path],
45
44
  workspace_addon_path: Path,
46
45
  db_filter: str,
47
46
  db_connection: DBConnection,
48
- extra_cmd_args: Optional[List[str]] = None,
47
+ extra_cmd_args: Optional[list[str]] = None,
49
48
  install_workspace_modules: bool = True,
50
49
  multithread_worker_count: int = -1,
51
50
  languages: str = "de_DE,en_US",
@@ -87,11 +86,10 @@ def _boostrap_command(
87
86
 
88
87
  init_modules = []
89
88
  extra_cmd_args_str = " ".join(extra_cmd_args or [])
90
- if not re.search(r"(-i|--init) ", extra_cmd_args_str):
91
- if install_workspace_modules:
92
- workspace_modules = godooModules([workspace_addon_path])
93
- if workspace_addons := workspace_modules.get_modules():
94
- init_modules += [f.name for f in workspace_addons]
89
+ if install_workspace_modules and not re.search(r"(-i|--init) ", extra_cmd_args_str):
90
+ workspace_modules = GodooModules([workspace_addon_path])
91
+ if workspace_addons := workspace_modules.get_modules():
92
+ init_modules += [f.name for f in workspace_addons]
95
93
  init_cmd = "--init " + ",".join(init_modules) if init_modules else ""
96
94
 
97
95
  addon_paths_str_list = [str(p.absolute()) for p in addon_paths if p and p.exists()]
@@ -100,7 +98,7 @@ def _boostrap_command(
100
98
  base_cmds = [
101
99
  str(odoo_main_path.absolute()) + "/odoo-bin",
102
100
  init_cmd,
103
- f"--config {str(odoo_conf_path.absolute())}",
101
+ f"--config {odoo_conf_path.absolute()!s}",
104
102
  "--save",
105
103
  f"--load-language {languages}",
106
104
  "--stop-after-init",
@@ -137,7 +135,7 @@ def bootstrap_odoo(
137
135
  db_host: Annotated[str, CLI.database.db_host],
138
136
  db_port: Annotated[int, CLI.database.db_port] = 0,
139
137
  db_password: Annotated[str, CLI.database.db_password] = "",
140
- extra_cmd_args: Annotated[List[str], CLI.odoo_launch.extra_cmd_args_bootstrap] = None,
138
+ extra_cmd_args: Annotated[Optional[list[str]], CLI.odoo_launch.extra_cmd_args_bootstrap] = None,
141
139
  multithread_worker_count: Annotated[int, CLI.odoo_launch.multithread_worker_count] = 2,
142
140
  languages: Annotated[str, CLI.odoo_launch.languages] = "de_DE,en_US",
143
141
  install_workspace_modules: Annotated[bool, CLI.odoo_launch.install_workspace_modules] = True,
@@ -8,7 +8,7 @@ command-line arguments.
8
8
  import logging
9
9
  from configparser import ConfigParser
10
10
  from pathlib import Path
11
- from typing import Annotated, List
11
+ from typing import Annotated
12
12
 
13
13
  import typer
14
14
 
@@ -19,7 +19,7 @@ LOGGER = logging.getLogger(__name__)
19
19
 
20
20
 
21
21
  def set_odoo_config(
22
- options: Annotated[List[str], typer.Argument(help="odoo.conf options by key=value")],
22
+ options: Annotated[list[str], typer.Argument(help="odoo.conf options by key=value")],
23
23
  odoo_conf_path: Annotated[Path, CLI.odoo_paths.conf_path],
24
24
  ):
25
25
  """Set odoo.conf values."""
@@ -30,8 +30,9 @@ def set_odoo_config(
30
30
  custom_opts = {}
31
31
  for op in options:
32
32
  if "=" not in op:
33
- LOGGER.error("Cannot parse Option: '%s' --> missing = sign", op)
34
- raise ValueError("Configuration option must be in format key=value")
33
+ msg = f"Cannot parse Option: '{op}' --> missing '=' sign (key=value)"
34
+ LOGGER.error(msg)
35
+ raise ValueError(msg)
35
36
  op_split = op.split("=")
36
37
  custom_opts[op_split[0]] = op_split[1]
37
38
  LOGGER.debug("Writing Conf Options: %s", custom_opts)
@@ -6,9 +6,10 @@ executing database queries using the psycopg2 library.
6
6
 
7
7
  import logging
8
8
  import subprocess
9
+ from collections.abc import Generator
9
10
  from contextlib import contextmanager
10
11
  from dataclasses import dataclass
11
- from typing import Annotated, Dict, Optional
12
+ from typing import Annotated, Any, Optional
12
13
 
13
14
  import psycopg2
14
15
 
@@ -86,7 +87,7 @@ class DBConnection:
86
87
  )
87
88
 
88
89
  @property
89
- def cli_dict(self) -> Dict[str, Optional[str]]:
90
+ def cli_dict(self) -> dict[str, Optional[str]]:
90
91
  """Get connection parameters as a dictionary.
91
92
 
92
93
  Returns:
@@ -101,7 +102,7 @@ class DBConnection:
101
102
  }
102
103
 
103
104
  @contextmanager
104
- def connect(self):
105
+ def connect(self) -> Generator[psycopg2.extensions.cursor, None, None]:
105
106
  """Create a database connection and cursor.
106
107
 
107
108
  This context manager creates a database connection and cursor,
@@ -129,7 +130,7 @@ class DBConnection:
129
130
  cr.close()
130
131
  connection.close()
131
132
 
132
- def run_psql_shell_command(self, command: str, **kwargs):
133
+ def run_psql_shell_command(self, command: str, **kwargs: dict[str, Any]) -> subprocess.CompletedProcess:
133
134
  """Run a psql command using the provided credentials.
134
135
 
135
136
  {} in the command will get templated with the connection string.
@@ -16,7 +16,7 @@ from ...helpers.cli import check_dangerous_command
16
16
  from .connection import DBConnection
17
17
 
18
18
 
19
- class DB_BOOTSTRAP_STATUS(enum.Enum):
19
+ class DbBootstrapStatus(enum.Enum):
20
20
  """Database bootstrap status enumeration.
21
21
 
22
22
  This enum represents the possible states of database bootstrapping:
@@ -78,24 +78,23 @@ def query_database(
78
78
  except ProgrammingError:
79
79
  # When there is nothing to fetch, fetchall() raises a ProgrammingError
80
80
  pass
81
- except Exception as e:
82
- LOGGER.exception(e)
81
+ except Exception:
83
82
  raise typer.Exit(1) # noqa: B904
84
83
 
85
84
 
86
- def _is_bootstrapped(db_connection: DBConnection) -> DB_BOOTSTRAP_STATUS:
85
+ def _is_bootstrapped(db_connection: DBConnection) -> DbBootstrapStatus:
87
86
  """Check if postgres contains database db_name and if this database has any tables present."""
88
87
  try:
89
88
  with db_connection.connect() as cursor:
90
89
  cursor.execute("SELECT EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'public');")
91
90
  if not cursor.fetchone()[0]:
92
91
  LOGGER.debug("Database '%s' is empty", db_connection.db_name)
93
- return DB_BOOTSTRAP_STATUS.EMPTY_DB
92
+ return DbBootstrapStatus.EMPTY_DB
94
93
  LOGGER.debug("Database '%s' is not empty", db_connection.db_name)
95
- return DB_BOOTSTRAP_STATUS.BOOTSTRAPPED
94
+ return DbBootstrapStatus.BOOTSTRAPPED
96
95
  except OperationalError:
97
96
  LOGGER.debug("Database '%s' does not exist", db_connection.db_name)
98
- return DB_BOOTSTRAP_STATUS.NO_DB
97
+ return DbBootstrapStatus.NO_DB
99
98
 
100
99
 
101
100
  def is_bootstrapped(
@@ -119,16 +118,16 @@ def is_bootstrapped(
119
118
  bootstrap_value = _is_bootstrapped(db_connection=connection)
120
119
  LOGGER.info("Odoo Database Status: %s", bootstrap_value.value)
121
120
  ret_mapping = {
122
- DB_BOOTSTRAP_STATUS.BOOTSTRAPPED: 0,
123
- DB_BOOTSTRAP_STATUS.NO_DB: 20,
124
- DB_BOOTSTRAP_STATUS.EMPTY_DB: 21,
121
+ DbBootstrapStatus.BOOTSTRAPPED: 0,
122
+ DbBootstrapStatus.NO_DB: 20,
123
+ DbBootstrapStatus.EMPTY_DB: 21,
125
124
  }
126
125
  raise typer.Exit(ret_mapping[bootstrap_value])
127
126
 
128
127
 
129
- def _get_installed_modules(db_connection: DBConnection, to_install=False):
128
+ def _get_installed_modules(db_connection: DBConnection, to_install: bool = False) -> list[str]:
130
129
  """Get list of installed modules in database (to_install includes the modules marked for installation)."""
131
- if (boot := _is_bootstrapped(db_connection=db_connection)) != DB_BOOTSTRAP_STATUS.BOOTSTRAPPED:
130
+ if (boot := _is_bootstrapped(db_connection=db_connection)) != DbBootstrapStatus.BOOTSTRAPPED:
132
131
  return boot.value
133
132
  lookup_states = ["installed", "to upgrade"]
134
133
  if to_install: