gOdoo-cli 0.8.6__tar.gz → 0.9.3__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 (51) hide show
  1. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/PKG-INFO +1 -1
  2. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/pyproject.toml +1 -1
  3. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/cli_common.py +9 -1
  4. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/backup/cli.py +2 -0
  5. godoo_cli-0.9.3/src/godoo_cli/commands/backup/dump.py +85 -0
  6. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/bootstrap.py +21 -28
  7. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/db/cli.py +3 -1
  8. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/db/connection.py +11 -0
  9. godoo_cli-0.9.3/src/godoo_cli/commands/db/query.py +125 -0
  10. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/launch.py +29 -39
  11. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/source_get.py +42 -21
  12. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/test/test_load_data.py +10 -5
  13. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/test/test_run.py +10 -5
  14. godoo_cli-0.9.3/src/godoo_cli/git/git_odoo.py +46 -0
  15. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/helpers/odoo_files.py +15 -16
  16. godoo_cli-0.9.3/src/godoo_cli/version.py +1 -0
  17. godoo_cli-0.8.6/src/godoo_cli/commands/db/query.py +0 -48
  18. godoo_cli-0.8.6/src/godoo_cli/git/git_odoo.py +0 -89
  19. godoo_cli-0.8.6/src/godoo_cli/version.py +0 -1
  20. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/LICENSE +0 -0
  21. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/README.md +0 -0
  22. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/__init__.py +0 -0
  23. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/__main__.py +0 -0
  24. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/cli.py +0 -0
  25. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/__init__.py +0 -0
  26. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/backup/__init__.py +0 -0
  27. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/backup/load.py +0 -0
  28. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/backup/pull.py +0 -0
  29. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/backup/util.py +0 -0
  30. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/config.py +0 -0
  31. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/db/__init__.py +0 -0
  32. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/db/passwords.py +0 -0
  33. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/rpc/__init__.py +0 -0
  34. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/rpc/cli.py +0 -0
  35. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/rpc/config_parameters.py +0 -0
  36. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/rpc/importer.py +0 -0
  37. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/rpc/modules.py +0 -0
  38. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/rpc/translations.py +0 -0
  39. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/shell.py +0 -0
  40. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/test/__init__.py +0 -0
  41. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/commands/test/cli.py +0 -0
  42. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/git/__init__.py +0 -0
  43. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/git/git_odoo_addons.py +0 -0
  44. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/git/git_repo.py +0 -0
  45. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/git/git_url.py +0 -0
  46. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/git/zip_download.py +0 -0
  47. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/helpers/__init__.py +0 -0
  48. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/helpers/bootstrap.py +0 -0
  49. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/helpers/cli.py +0 -0
  50. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/helpers/odoo_manifest.py +0 -0
  51. {godoo_cli-0.8.6 → godoo_cli-0.9.3}/src/godoo_cli/helpers/system.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: gOdoo-cli
3
- Version: 0.8.6
3
+ Version: 0.9.3
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.8.6"
3
+ version = "0.9.3"
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"
@@ -8,7 +8,15 @@ from typer_common_functions import get_type_from_default, typer_retuner, typer_u
8
8
 
9
9
  @dataclass
10
10
  class OdooLaunchArgs:
11
- extra_cmd_args: List[str] = Option(None, help="extra agruments to pass to odoo-bin", rich_help_panel="Odoo")
11
+ extra_cmd_args: List[str] = Option(
12
+ None, help="extra agruments to pass to odoo-bin", envvar="ODOO_BIN_ARGS", rich_help_panel="Odoo"
13
+ )
14
+ extra_cmd_args_bootstrap: List[str] = Option(
15
+ None,
16
+ help="extra agruments to pass to odoo-bin in bootstrap mode",
17
+ envvar="ODOO_BIN_BOOTSTRAP_ARGS",
18
+ rich_help_panel="Odoo",
19
+ )
12
20
  multithread_worker_count: int = Option(
13
21
  -1, help="count of worker threads. will enable proxy_mode if >0. (Autodetect with -1)", rich_help_panel="Odoo"
14
22
  )
@@ -1,5 +1,6 @@
1
1
  import typer
2
2
 
3
+ from .dump import dump_instance
3
4
  from .load import load_instance_data
4
5
  from .pull import InstancePuller
5
6
 
@@ -13,5 +14,6 @@ def backup_cli_app():
13
14
 
14
15
  app.command("pull")(puller.pull_instance_data)
15
16
  app.command("load")(load_instance_data)
17
+ app.command("dump")(dump_instance)
16
18
 
17
19
  return app
@@ -0,0 +1,85 @@
1
+ import logging
2
+ import shutil
3
+ from configparser import ConfigParser
4
+ from datetime import datetime
5
+ from pathlib import Path
6
+
7
+ import typer
8
+
9
+ from ...cli_common import CommonCLI
10
+ from ...helpers.odoo_files import odoo_bin_get_version
11
+ from ..db.connection import DBConnection
12
+
13
+ LOGGER = logging.getLogger(__name__)
14
+ CLI = CommonCLI()
15
+
16
+
17
+ @CLI.arg_annotator
18
+ def dump_instance(
19
+ dump_path: Path = typer.Argument(
20
+ ...,
21
+ help="Path to dump to",
22
+ file_okay=False,
23
+ dir_okay=True,
24
+ writable=True,
25
+ resolve_path=True,
26
+ ),
27
+ db_name=CLI.database.db_name,
28
+ db_host=CLI.database.db_host,
29
+ db_port=CLI.database.db_port,
30
+ db_user=CLI.database.db_user,
31
+ db_password=CLI.database.db_password,
32
+ odoo_main_path=CLI.odoo_paths.bin_path,
33
+ conf_path=CLI.odoo_paths.conf_path,
34
+ ):
35
+ """Dump DB and Filestore into Folder"""
36
+ db_connection = DBConnection(
37
+ db_name=db_name,
38
+ hostname=db_host,
39
+ username=db_user,
40
+ password=db_password,
41
+ port=db_port,
42
+ )
43
+ dump_path.mkdir(parents=True, exist_ok=True)
44
+
45
+ if not conf_path:
46
+ raise typer.Exit("No Odoo Conf Path provided. Cannot dump Filestore")
47
+
48
+ # Read .conf value [options] datad_dir
49
+ conf_path = Path(conf_path)
50
+ parser = ConfigParser()
51
+ parser.read(conf_path)
52
+ data_dir = parser["options"]["data_dir"]
53
+ data_dir = Path(data_dir)
54
+
55
+ # Copy Filestore
56
+ LOGGER.info("Dumping Filestore")
57
+ filestore_target = dump_path / "odoo_filestore"
58
+ shutil.rmtree(filestore_target, ignore_errors=True)
59
+ shutil.copytree(data_dir, filestore_target)
60
+
61
+ # Dump DB using pg_dump
62
+ LOGGER.info("Dumping DB")
63
+ db_dump_target = dump_path / "odoo.dump"
64
+ db_dump_target.unlink(missing_ok=True)
65
+ db_connection.run_psql_shell_command("pg_dump --format c {} > %s" % db_dump_target)
66
+
67
+ readme_path = Path(dump_path) / "README.md"
68
+ readme_path.unlink(missing_ok=True)
69
+
70
+ odoo_version = odoo_bin_get_version(odoo_main_path)
71
+
72
+ readme_content = f"""
73
+ # gOdoo Dump
74
+
75
+ SQL Dump and Filestore of gOdoo Instance.
76
+
77
+ ## Metadata
78
+
79
+
80
+ - Odoo Version: {odoo_version.raw}
81
+ - Filestore: [{ datetime.fromtimestamp(filestore_target.stat().st_mtime)}]({filestore_target.relative_to(dump_path)})
82
+ - SQL Dump: [{ datetime.fromtimestamp(db_dump_target.stat().st_mtime)}]({db_dump_target.relative_to(dump_path)})
83
+
84
+ """
85
+ readme_path.write_text(readme_content)
@@ -2,7 +2,7 @@ import logging
2
2
  import os
3
3
  import re
4
4
  from pathlib import Path
5
- from typing import Any, List
5
+ from typing import Any, List, Optional
6
6
 
7
7
  import typer
8
8
  from typing_extensions import Annotated
@@ -11,6 +11,7 @@ from ..cli_common import CommonCLI
11
11
  from ..helpers.bootstrap import _install_py_reqs_by_odoo_cmd
12
12
  from ..helpers.odoo_files import get_addon_paths, get_odoo_module_paths
13
13
  from ..helpers.system import run_cmd
14
+ from .db.connection import DBConnection
14
15
 
15
16
  CLI = CommonCLI()
16
17
 
@@ -27,13 +28,9 @@ def _boostrap_command(
27
28
  odoo_conf_path: Path,
28
29
  addon_paths: List[Path],
29
30
  workspace_addon_path: Path,
30
- db_host: str,
31
31
  db_filter: str,
32
- db_name: str,
33
- db_user: str,
34
- db_password: str,
35
- db_port: str,
36
- extra_cmd_args: List[str] = None,
32
+ db_connection: DBConnection,
33
+ extra_cmd_args: Optional[List[str]] = None,
37
34
  install_workspace_modules: bool = True,
38
35
  multithread_worker_count: int = -1,
39
36
  languages: str = "de_DE,en_US",
@@ -53,16 +50,8 @@ def _boostrap_command(
53
50
  path to addons in dev repo
54
51
  db_filter : str
55
52
  db filter for odoo.conf
56
- db_host : str
57
- db hostname for odoo.conf
58
- db_name : str
59
- database name for odoo.conf
60
- db_user : str
61
- db user
62
- db_password : str
63
- db user password
64
- db_port : str
65
- db host port
53
+ db_connection : DBConnection
54
+ DB Connection
66
55
  extra_cmd_args : List[str], optional
67
56
  extra args to pass to odoo-bin, by default None
68
57
  install_workspace_modules : bool, optional
@@ -82,11 +71,11 @@ def _boostrap_command(
82
71
  odoo_conf_path.parent.mkdir(parents=True, exist_ok=True)
83
72
 
84
73
  db_command = [
85
- f"--database {db_name}",
86
- f"--db_user {db_user}",
87
- f"--db_password {db_password}",
88
- f"--db_host {db_host}" if db_host else "",
89
- f"--db_port {db_port}" if db_host else "",
74
+ f"--database {db_connection.db_name}",
75
+ f"--db_user {db_connection.username}",
76
+ f"--db_password {db_connection.password}",
77
+ f"--db_host {db_connection.hostname}" if db_connection.hostname else "",
78
+ f"--db_port {db_connection.port}" if db_connection.hostname else "",
90
79
  f"--db-filter=^{db_filter}$",
91
80
  ]
92
81
 
@@ -149,7 +138,7 @@ def bootstrap_odoo(
149
138
  db_name=CLI.database.db_name,
150
139
  db_user=CLI.database.db_user,
151
140
  db_password=CLI.database.db_password,
152
- extra_cmd_args=CLI.odoo_launch.extra_cmd_args,
141
+ extra_cmd_args=CLI.odoo_launch.extra_cmd_args_bootstrap,
153
142
  multithread_worker_count=CLI.odoo_launch.multithread_worker_count,
154
143
  languages=CLI.odoo_launch.languages,
155
144
  install_workspace_modules=CLI.odoo_launch.install_workspace_modules,
@@ -170,17 +159,21 @@ def bootstrap_odoo(
170
159
  thirdparty_addon_path=thirdparty_addon_path,
171
160
  )
172
161
 
162
+ db_connection = DBConnection(
163
+ hostname=db_host,
164
+ port=db_port,
165
+ username=db_user,
166
+ password=db_password,
167
+ db_name=db_name,
168
+ )
169
+
173
170
  cmd_string = _boostrap_command(
174
171
  odoo_main_path=odoo_main_path,
175
172
  odoo_conf_path=odoo_conf_path,
176
173
  workspace_addon_path=workspace_addon_path,
177
174
  addon_paths=addon_paths,
178
- db_host=db_host,
179
- db_name=db_name,
180
175
  db_filter=db_filter,
181
- db_user=db_user,
182
- db_password=db_password,
183
- db_port=db_port,
176
+ db_connection=db_connection,
184
177
  extra_cmd_args=extra_cmd_args,
185
178
  install_workspace_modules=install_workspace_modules,
186
179
  multithread_worker_count=multithread_worker_count,
@@ -2,7 +2,7 @@ import typer
2
2
 
3
3
  from .connection import login_db
4
4
  from .passwords import set_passwords
5
- from .query import query_database
5
+ from .query import get_installed_modules, is_bootstrapped, query_database
6
6
 
7
7
 
8
8
  def db_cli_app():
@@ -14,5 +14,7 @@ def db_cli_app():
14
14
  app.command()(set_passwords)
15
15
  app.command("login")(login_db)
16
16
  app.command("query")(query_database)
17
+ app.command("odoo-bootstrapped")(is_bootstrapped)
18
+ app.command("installed-modules")(get_installed_modules)
17
19
 
18
20
  return app
@@ -52,6 +52,17 @@ class DBConnection:
52
52
  connect_timeout=self.conn_timeout,
53
53
  )
54
54
 
55
+ @property
56
+ def cli_dict(self):
57
+ """Return a dict that when expanded Matches the Default DB connection Args used throuout gOdoo"""
58
+ return {
59
+ "db_host": self.hostname,
60
+ "db_port": self.port,
61
+ "db_name": self.db_name,
62
+ "db_user": self.username,
63
+ "db_password": self.password,
64
+ }
65
+
55
66
  @contextmanager
56
67
  def connect(self):
57
68
  connection = self.get_connection()
@@ -0,0 +1,125 @@
1
+ import logging
2
+ from enum import Enum
3
+
4
+ import typer
5
+ from psycopg2 import OperationalError, ProgrammingError
6
+
7
+ from ...cli_common import CommonCLI
8
+ from ...helpers.cli import check_dangerous_command
9
+ from .connection import DBConnection
10
+
11
+
12
+ class DB_BOOTSTRAP_STATUS(Enum):
13
+ BOOTSTRAPPED = 0
14
+ NO_DB = 1
15
+ EMPTY_DB = 2
16
+
17
+
18
+ LOGGER = logging.getLogger(__name__)
19
+ CLI = CommonCLI()
20
+
21
+
22
+ @CLI.arg_annotator
23
+ def query_database(
24
+ query: str = typer.Argument(..., help="SQL Query"),
25
+ db_host=CLI.database.db_host,
26
+ db_port=CLI.database.db_port,
27
+ db_name=CLI.database.db_name,
28
+ db_user=CLI.database.db_user,
29
+ db_password=CLI.database.db_password,
30
+ ):
31
+ """Run a Query against the database."""
32
+
33
+ check_dangerous_command()
34
+ # regex to check if SQL query contains writing command
35
+
36
+ connection = DBConnection(
37
+ hostname=db_host,
38
+ port=db_port,
39
+ username=db_user,
40
+ password=db_password,
41
+ db_name=db_name,
42
+ )
43
+ with connection.connect() as cursor:
44
+ try:
45
+ LOGGER.info("Running Query: %s", query)
46
+ cursor.execute(query)
47
+ LOGGER.info("Affected Rows: %s", cursor.rowcount)
48
+ try:
49
+ rows = cursor.fetchall()
50
+ for row in rows:
51
+ print("\t".join(row)) # pylint: disable=print-used
52
+ except ProgrammingError:
53
+ pass
54
+ except Exception as e:
55
+ LOGGER.exception(e)
56
+ raise typer.Exit(1)
57
+
58
+
59
+ def _is_bootstrapped(db_connection: DBConnection) -> DB_BOOTSTRAP_STATUS:
60
+ """check if postgres contains database db_name and if this database has any tables present"""
61
+ try:
62
+ with db_connection.connect() as cursor:
63
+ cursor.execute("SELECT EXISTS (SELECT 1 FROM pg_tables WHERE schemaname = 'public');")
64
+ if not cursor.fetchone()[0]:
65
+ LOGGER.warning("Database %s is empty", db_connection.db_name)
66
+ return DB_BOOTSTRAP_STATUS.EMPTY_DB
67
+ LOGGER.debug("Database %s is not empty", db_connection.db_name)
68
+ return DB_BOOTSTRAP_STATUS.BOOTSTRAPPED
69
+ except OperationalError:
70
+ LOGGER.warning("Database %s does not exist", db_connection.db_name)
71
+ return DB_BOOTSTRAP_STATUS.NO_DB
72
+
73
+
74
+ @CLI.arg_annotator
75
+ def is_bootstrapped(
76
+ db_host=CLI.database.db_host,
77
+ db_port=CLI.database.db_port,
78
+ db_name=CLI.database.db_name,
79
+ db_user=CLI.database.db_user,
80
+ db_password=CLI.database.db_password,
81
+ ):
82
+ """Check if the database is empty. Return code = 1 if database does not exist, 2 if database is empty, 0 if database is not empty."""
83
+ check_dangerous_command()
84
+ connection = DBConnection(
85
+ hostname=db_host,
86
+ port=db_port,
87
+ username=db_user,
88
+ password=db_password,
89
+ db_name=db_name,
90
+ )
91
+ boot = _is_bootstrapped(db_connection=connection)
92
+ raise typer.Exit(boot.value)
93
+
94
+
95
+ def _get_installed_modules(db_connection: DBConnection):
96
+ """Get list of installed modules in database"""
97
+ if boot := _is_bootstrapped(db_connection=db_connection) != DB_BOOTSTRAP_STATUS.BOOTSTRAPPED:
98
+ return boot.value
99
+ with db_connection.connect() as cursor:
100
+ cursor.execute("SELECT name FROM ir_module_module WHERE state = 'installed';")
101
+ sql_res = cursor.fetchall()
102
+ return [r[0] for r in sql_res]
103
+
104
+
105
+ @CLI.arg_annotator
106
+ def get_installed_modules(
107
+ db_host=CLI.database.db_host,
108
+ db_port=CLI.database.db_port,
109
+ db_name=CLI.database.db_name,
110
+ db_user=CLI.database.db_user,
111
+ db_password=CLI.database.db_password,
112
+ ):
113
+ """Returns Modules Marked as installed by Odoo in the database"""
114
+ db_connection = DBConnection(
115
+ hostname=db_host,
116
+ port=db_port,
117
+ username=db_user,
118
+ password=db_password,
119
+ db_name=db_name,
120
+ )
121
+ installed_modules = _get_installed_modules(db_connection=db_connection)
122
+ if isinstance(installed_modules, int):
123
+ raise typer.Exit(installed_modules)
124
+ for module in sorted(installed_modules):
125
+ print(module) # pylint: disable=print-used
@@ -10,6 +10,8 @@ from ..cli_common import CommonCLI
10
10
  from ..helpers.odoo_files import get_odoo_module_paths, odoo_bin_get_version
11
11
  from ..helpers.system import run_cmd
12
12
  from .bootstrap import bootstrap_odoo
13
+ from .db.connection import DBConnection
14
+ from .db.query import DB_BOOTSTRAP_STATUS, _is_bootstrapped
13
15
  from .rpc import import_to_odoo
14
16
  from .source_get import py_depends_by_db, update_odoo_conf
15
17
 
@@ -60,11 +62,7 @@ def pre_launch(
60
62
  thirdparty_addon_path: Path,
61
63
  odoo_conf_path: Path,
62
64
  db_filter: str,
63
- db_host: str,
64
- db_port: int,
65
- db_name: str,
66
- db_user: str,
67
- db_password: str,
65
+ db_connection: DBConnection,
68
66
  odoo_demo: bool,
69
67
  dev_mode: bool,
70
68
  multithread_worker_count: int = 0,
@@ -89,16 +87,8 @@ def pre_launch(
89
87
  path to odoo conf
90
88
  db_filter : str
91
89
  odoo.conf db_filter
92
- db_host : str
93
- database host url. Empty string for Unix sock
94
- db_port : int
95
- database port. 0 for unix sock
96
- db_name : str
97
- odoo main database name
98
- db_user : str
99
- database user
100
- db_password : str
101
- database password
90
+ db_connection : DBConnection
91
+ DBConnection object
102
92
  odoo_demo : bool
103
93
  if false, add --without-demo to bootstrap
104
94
  dev_mode : bool
@@ -142,12 +132,8 @@ def pre_launch(
142
132
  if not odoo_demo:
143
133
  _extra_bootstrap_args += ["--without-demo all"]
144
134
  ret = bootstrap_odoo(
145
- db_name=db_name,
135
+ **db_connection.cli_dict,
146
136
  db_filter=db_filter,
147
- db_user=db_user,
148
- db_password=db_password,
149
- db_host=db_host,
150
- db_port=db_port,
151
137
  thirdparty_addon_path=thirdparty_addon_path,
152
138
  odoo_main_path=odoo_main_path,
153
139
  odoo_conf_path=odoo_conf_path,
@@ -172,6 +158,9 @@ def pre_launch(
172
158
  odoo_main_path = odoo_main_path
173
159
  odoo_version = odoo_bin_get_version(odoo_main_path)
174
160
 
161
+ if _is_bootstrapped(db_connection) != DB_BOOTSTRAP_STATUS.BOOTSTRAPPED:
162
+ return 404
163
+
175
164
  update_odoo_conf(
176
165
  odoo_conf=odoo_conf_path,
177
166
  odoo_main_path=odoo_main_path,
@@ -183,11 +172,7 @@ def pre_launch(
183
172
  odoo_main_path=odoo_main_path,
184
173
  workspace_addon_path=workspace_addon_path,
185
174
  thirdparty_addon_path=thirdparty_addon_path,
186
- db_host=db_host,
187
- db_port=db_port,
188
- db_name=db_name,
189
- db_user=db_user,
190
- db_password=db_password,
175
+ **db_connection.cli_dict,
191
176
  )
192
177
 
193
178
  if dev_mode:
@@ -224,26 +209,28 @@ def launch_odoo(
224
209
  dev_mode=CLI.odoo_launch.dev_mode,
225
210
  install_workspace_modules=CLI.odoo_launch.install_workspace_modules,
226
211
  extra_args=CLI.odoo_launch.extra_cmd_args,
227
- extra_bootstrap_args=CLI.odoo_launch.extra_cmd_args,
212
+ extra_bootstrap_args=CLI.odoo_launch.extra_cmd_args_bootstrap,
228
213
  log_file_path=CLI.odoo_launch.log_file_path,
229
214
  multithread_worker_count=CLI.odoo_launch.multithread_worker_count,
230
215
  languages=CLI.odoo_launch.languages,
231
216
  ):
232
217
  """
233
- Launch Odoo, Bootstrap if bootstrapflag is not present.
218
+ Launch Odoo, Bootstrap if db is empty.
234
219
  """
235
-
220
+ db_connection = DBConnection(
221
+ hostname=db_host,
222
+ port=db_port,
223
+ username=db_user,
224
+ password=db_password,
225
+ db_name=db_name,
226
+ )
236
227
  launch_cmd = pre_launch(
237
228
  odoo_main_path=odoo_main_path,
238
229
  workspace_addon_path=workspace_addon_path,
239
230
  thirdparty_addon_path=thirdparty_addon_path,
240
231
  odoo_conf_path=odoo_conf_path,
241
232
  db_filter=db_filter,
242
- db_host=db_host,
243
- db_port=db_port,
244
- db_name=db_name,
245
- db_user=db_user,
246
- db_password=db_password,
233
+ db_connection=db_connection,
247
234
  odoo_demo=odoo_demo,
248
235
  dev_mode=dev_mode,
249
236
  install_workspace_addons=install_workspace_modules,
@@ -285,11 +272,18 @@ def launch_import(
285
272
  dev_mode=CLI.odoo_launch.dev_mode,
286
273
  install_workspace_modules=CLI.odoo_launch.install_workspace_modules,
287
274
  extra_launch_args=CLI.odoo_launch.extra_cmd_args,
288
- extra_bootstrap_args=CLI.odoo_launch.extra_cmd_args,
275
+ extra_bootstrap_args=CLI.odoo_launch.extra_cmd_args_bootstrap,
289
276
  log_file_path=CLI.odoo_launch.log_file_path,
290
277
  multithread_worker_count=CLI.odoo_launch.multithread_worker_count,
291
278
  ):
292
279
  """Bootstrap and Start odoo. Launches RPC import in second thread."""
280
+ db_connection = DBConnection(
281
+ hostname=db_host,
282
+ port=db_port,
283
+ username=db_user,
284
+ password=db_password,
285
+ db_name=db_name,
286
+ )
293
287
 
294
288
  launch_cmd = pre_launch(
295
289
  odoo_main_path=odoo_main_path,
@@ -297,11 +291,7 @@ def launch_import(
297
291
  thirdparty_addon_path=thirdparty_addon_path,
298
292
  odoo_conf_path=odoo_conf_path,
299
293
  db_filter=db_filter,
300
- db_host=db_host,
301
- db_port=db_port,
302
- db_name=db_name,
303
- db_user=db_user,
304
- db_password=db_password,
294
+ db_connection=db_connection,
305
295
  odoo_demo=odoo_demo,
306
296
  dev_mode=dev_mode,
307
297
  install_workspace_addons=install_workspace_modules,
@@ -17,6 +17,7 @@ from ..helpers.odoo_files import get_addon_paths, get_odoo_module_paths, get_zip
17
17
  from ..helpers.odoo_manifest import remove_unused_folders
18
18
  from ..helpers.system import download_file
19
19
  from .db.connection import DBConnection
20
+ from .db.query import _get_installed_modules
20
21
 
21
22
  LOGGER = logging.getLogger(__name__)
22
23
  CLI = CommonCLI()
@@ -109,28 +110,47 @@ def py_depends_by_db(
109
110
  db_password=CLI.database.db_password,
110
111
  ):
111
112
  """Insall Python Dependencies for all installed modules in DB."""
112
- connection = DBConnection(
113
- hostname=db_host,
114
- port=db_port,
115
- username=db_user,
116
- password=db_password,
117
- db_name=db_name,
113
+ connection = DBConnection(hostname=db_host, port=db_port, username=db_user, password=db_password, db_name=db_name)
114
+ module_list = _get_installed_modules(connection)
115
+ if isinstance(module_list, int):
116
+ return CLI.returner(module_list)
117
+ LOGGER.info("Ensuring Py Reqiurements for Installed Modules are met")
118
+ LOGGER.debug("Modules:\n%s", module_list)
119
+ odoo_addon_paths = get_addon_paths(
120
+ odoo_main_repo=odoo_main_path,
121
+ workspace_addon_path=workspace_addon_path,
122
+ thirdparty_addon_path=thirdparty_addon_path,
118
123
  )
119
- with connection.connect() as conn:
120
- try:
121
- conn.execute("SELECT name FROM ir_module_module WHERE state='installed'")
122
- except UnboundLocalError as e:
123
- LOGGER.error("Could not connect to DB. Check your DB Connection settings.")
124
- raise typer.Exit(1) from e
125
- module_list = [r[0] for r in conn.fetchall()]
126
- LOGGER.info("Ensuring Py Reqiurements for Installed Modules are met")
127
- LOGGER.debug("Modules:\n%s", module_list)
128
- odoo_addon_paths = get_addon_paths(
129
- odoo_main_repo=odoo_main_path,
130
- workspace_addon_path=workspace_addon_path,
131
- thirdparty_addon_path=thirdparty_addon_path,
132
- )
133
- _install_py_reqs_for_modules(odoo_addon_paths, module_list)
124
+ module_list = [m for m in module_list if m != "base"]
125
+ _install_py_reqs_for_modules(odoo_addon_paths, module_list)
126
+
127
+
128
+ @CLI.arg_annotator
129
+ def get_installed_module_paths(
130
+ odoo_main_path=CLI.odoo_paths.bin_path,
131
+ workspace_addon_path=CLI.odoo_paths.workspace_addon_path,
132
+ thirdparty_addon_path=CLI.odoo_paths.thirdparty_addon_path,
133
+ db_host=CLI.database.db_host,
134
+ db_port=CLI.database.db_port,
135
+ db_name=CLI.database.db_name,
136
+ db_user=CLI.database.db_user,
137
+ db_password=CLI.database.db_password,
138
+ ):
139
+ """Get Paths of all installed modules in DB."""
140
+ connection = DBConnection(hostname=db_host, port=db_port, username=db_user, password=db_password, db_name=db_name)
141
+ module_list = _get_installed_modules(connection)
142
+ if isinstance(module_list, int):
143
+ return CLI.returner(module_list)
144
+ LOGGER.debug("Searching Folders for:\n%s", module_list)
145
+ odoo_addon_paths = get_addon_paths(
146
+ odoo_main_repo=odoo_main_path,
147
+ workspace_addon_path=workspace_addon_path,
148
+ thirdparty_addon_path=thirdparty_addon_path,
149
+ )
150
+ module_list = [m for m in module_list if m != "base"]
151
+ module_paths = get_odoo_module_paths(odoo_addon_paths, module_names=module_list)
152
+ for p in module_paths:
153
+ print(p.absolute()) # pylint: disable=print-used
134
154
 
135
155
 
136
156
  @CLI.unpacker
@@ -276,5 +296,6 @@ def source_cli_app():
276
296
  app.command("get-file")(get_source_file)
277
297
  app.command("get-dependencies")(py_depends_by_modules)
278
298
  app.command("get-dependencies-db")(py_depends_by_db)
299
+ app.command("installed-module-paths")(get_installed_module_paths)
279
300
 
280
301
  return app
@@ -5,6 +5,7 @@ import typer
5
5
 
6
6
  from ...cli_common import CommonCLI
7
7
  from ...helpers.system import run_cmd
8
+ from ..db.connection import DBConnection
8
9
  from ..launch import pre_launch
9
10
  from ..shell import odoo_shell
10
11
 
@@ -56,17 +57,21 @@ def odoo_load_test_data(
56
57
  if extra_launch_args:
57
58
  launch_args = extra_launch_args + launch_args
58
59
 
60
+ db_connection = DBConnection(
61
+ hostname=db_host,
62
+ port=db_port,
63
+ username=db_user,
64
+ password=db_password,
65
+ db_name=db_name,
66
+ )
67
+
59
68
  launch_cmd = pre_launch(
60
69
  odoo_main_path=odoo_main_path,
61
70
  workspace_addon_path=workspace_addon_path,
62
71
  thirdparty_addon_path=thirdparty_addon_path,
63
72
  odoo_conf_path=odoo_conf_path,
64
73
  db_filter=db_filter,
65
- db_host=db_host,
66
- db_port=db_port,
67
- db_name=db_name,
68
- db_user=db_user,
69
- db_password=db_password,
74
+ db_connection=db_connection,
70
75
  dev_mode=False,
71
76
  install_workspace_addons=False,
72
77
  extra_launch_args=launch_args,
@@ -9,6 +9,7 @@ from typing_extensions import Annotated
9
9
  from ...cli_common import CommonCLI
10
10
  from ...helpers.odoo_files import get_changed_modules, get_depends_of_module, get_odoo_module_paths
11
11
  from ...helpers.system import run_cmd
12
+ from ..db.connection import DBConnection
12
13
  from ..launch import pre_launch
13
14
  from ..shell import odoo_pregenerate_assets
14
15
 
@@ -113,17 +114,21 @@ def odoo_run_tests(
113
114
 
114
115
  bootstrap_args = extra_bootstrap_args + bootstrap_args
115
116
 
117
+ db_connection = DBConnection(
118
+ hostname=db_host,
119
+ port=db_port,
120
+ username=db_user,
121
+ password=db_password,
122
+ db_name=db_name,
123
+ )
124
+
116
125
  launch_cmd = pre_launch(
117
126
  odoo_main_path=odoo_main_path,
118
127
  workspace_addon_path=workspace_addon_path,
119
128
  thirdparty_addon_path=thirdparty_addon_path,
120
129
  odoo_conf_path=odoo_conf_path,
121
130
  db_filter=db_filter,
122
- db_host=db_host,
123
- db_port=db_port,
124
- db_name=db_name,
125
- db_user=db_user,
126
- db_password=db_password,
131
+ db_connection=db_connection,
127
132
  dev_mode=False,
128
133
  install_workspace_addons=False,
129
134
  extra_launch_args=launch_args,
@@ -0,0 +1,46 @@
1
+ import logging
2
+ from pathlib import Path
3
+
4
+ from ..helpers.odoo_manifest 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
+ manifest_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(manifest_file.resolve())
19
+ if not git_repos:
20
+ raise FileNotFoundError(f"Couldnt load yml file from: {str(manifest_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(manifest_file)}")
25
+
26
+ odoo_url = odoo_data["url"]
27
+ odoo_branch = odoo_data.get("branch", "master")
28
+ odoo_commit = odoo_data.get("commit", "")
29
+
30
+ if add_compare_comment:
31
+ yaml_add_compare_commit(odoo_data, odoo_branch)
32
+ else:
33
+ yaml_remove_compare_commit(odoo_data)
34
+
35
+ git_ensure_repo(
36
+ target_folder=target_folder,
37
+ repo_src=odoo_url,
38
+ branch=odoo_branch,
39
+ commit=odoo_commit,
40
+ pull=force_fetch,
41
+ zip_mode=download_archive,
42
+ filter="blob:none",
43
+ single_branch=True,
44
+ )
45
+
46
+ yaml.dump(git_repos, manifest_file)
@@ -4,7 +4,7 @@ import re
4
4
  from ast import literal_eval
5
5
  from dataclasses import dataclass
6
6
  from pathlib import Path
7
- from typing import List, Union
7
+ from typing import List, Optional, Union
8
8
 
9
9
  from git import Repo
10
10
 
@@ -26,7 +26,7 @@ class OdooVersion:
26
26
  return f"{self.major}.{self.minor}"
27
27
 
28
28
 
29
- def odoo_bin_get_version(odoo_main_repo_path: Path) -> str:
29
+ def odoo_bin_get_version(odoo_main_repo_path: Path) -> OdooVersion:
30
30
  """Get Odoo Version by calling 'odoo-bin --version'
31
31
 
32
32
  Parameters
@@ -71,13 +71,18 @@ def folder_is_odoo_module(folder: Path) -> bool:
71
71
  return folder.is_dir() and any(folder.glob("__manifest__.py"))
72
72
 
73
73
 
74
- def get_odoo_module_paths(search_folders: Union[List[Path], Path]) -> List[Path]:
74
+ def get_odoo_module_paths(
75
+ search_folders: Union[List[Path], Path],
76
+ module_names: Optional[List[str]] = None,
77
+ ) -> List[Path]:
75
78
  """List all Valid odoo module names in one or many Odoo addons folder.
76
79
 
77
80
  Parameters
78
81
  ----------
79
82
  search_folders : Path
80
83
  Folder(s) to search in.
84
+ module_names : Optional[List[str]], optional
85
+ Filter for module names, by default None
81
86
 
82
87
  Returns
83
88
  -------
@@ -94,6 +99,11 @@ def get_odoo_module_paths(search_folders: Union[List[Path], Path]) -> List[Path]
94
99
  for folder in folder.iterdir():
95
100
  if folder_is_odoo_module(folder):
96
101
  module_paths.append(folder)
102
+ if module_names:
103
+ filtered_module_paths = [p for p in module_paths if p.stem in module_names]
104
+ if unavailable_modules := set(module_names).difference([p.stem for p in filtered_module_paths]):
105
+ LOGGER.warning("Could not find Module folder for: %s", unavailable_modules)
106
+ return filtered_module_paths
97
107
  return module_paths
98
108
 
99
109
 
@@ -143,7 +153,7 @@ def get_changed_modules(
143
153
  def get_depends_of_module(
144
154
  all_modules: List[Path],
145
155
  module_to_check: Path,
146
- already_done_modules: List[Path] = None,
156
+ already_done_modules: Optional[List[Path]] = None,
147
157
  ):
148
158
  """Recursively Searches sub dependencies for Odoo modules.
149
159
 
@@ -253,18 +263,7 @@ def _get_python_requirements_of_modules(addon_paths: List[Path], filter_module_n
253
263
  Modules to look for manifests, by default all available modules
254
264
  """
255
265
  available_modules = get_odoo_module_paths(addon_paths)
256
- available_module_names = [p.stem for p in available_modules]
257
-
258
- if not filter_module_names:
259
- filter_module_names = available_module_names
260
- filter_module_names = [f for f in filter_module_names if f != "base"]
261
-
262
- LOGGER.debug("Checking python requirements of Modules: %s", sorted(filter_module_names))
263
- if unavailable_modules := set(filter_module_names).difference(available_module_names):
264
- LOGGER.warning("Could not find __manifest__ for: %s", unavailable_modules)
265
- LOGGER.debug("Search Paths:\n%s", map(str, addon_paths))
266
-
267
- check_modules = [mp for mp in available_modules if mp.stem in filter_module_names]
266
+ check_modules = get_odoo_module_paths(addon_paths, module_names=filter_module_names)
268
267
 
269
268
  if odoo_main_path := _get_odoo_main_path(addon_paths):
270
269
  # When the Odoo main path is in the supplied path, exclude those modules.
@@ -0,0 +1 @@
1
+ __version__ = "0.9.3"
@@ -1,48 +0,0 @@
1
- import logging
2
-
3
- import typer
4
- from psycopg2 import ProgrammingError
5
-
6
- from ...cli_common import CommonCLI
7
- from ...helpers.cli import check_dangerous_command
8
- from .connection import DBConnection
9
-
10
- LOGGER = logging.getLogger(__name__)
11
- CLI = CommonCLI()
12
-
13
-
14
- @CLI.arg_annotator
15
- def query_database(
16
- query: str = typer.Argument(..., help="SQL Query"),
17
- db_host=CLI.database.db_host,
18
- db_port=CLI.database.db_port,
19
- db_name=CLI.database.db_name,
20
- db_user=CLI.database.db_user,
21
- db_password=CLI.database.db_password,
22
- ):
23
- """Run a Query against the database."""
24
-
25
- check_dangerous_command()
26
- # regex to check if SQL query contains writing command
27
-
28
- connection = DBConnection(
29
- hostname=db_host,
30
- port=db_port,
31
- username=db_user,
32
- password=db_password,
33
- db_name=db_name,
34
- )
35
- with connection.connect() as cursor:
36
- try:
37
- LOGGER.info("Running Query: %s", query)
38
- cursor.execute(query)
39
- LOGGER.info("Affected Rows: %s", cursor.rowcount)
40
- try:
41
- rows = cursor.fetchall()
42
- for row in rows:
43
- print("\t".join(row)) # pylint: disable=print-used
44
- except ProgrammingError:
45
- pass
46
- except Exception as e:
47
- LOGGER.exception(e)
48
- raise typer.Exit(1)
@@ -1,89 +0,0 @@
1
- import json
2
- import logging
3
- from pathlib import Path
4
-
5
- from ..helpers.odoo_manifest import yaml_add_compare_commit, yaml_remove_compare_commit, yaml_roundtrip_loader
6
- from .git_repo import git_ensure_repo
7
-
8
- LOGGER = logging.getLogger(__name__)
9
-
10
-
11
- def git_ensure_odoo_repo(
12
- target_folder: Path,
13
- manifest_file: Path,
14
- force_fetch: bool,
15
- add_compare_comment: bool,
16
- download_archive: bool,
17
- ):
18
- yaml = yaml_roundtrip_loader()
19
- git_repos = yaml.load(manifest_file.resolve())
20
- if not git_repos:
21
- raise FileNotFoundError(f"Couldnt load yml file from: {str(manifest_file)}")
22
-
23
- odoo_data = git_repos.get("odoo")
24
- if not odoo_data:
25
- raise KeyError(f"Could not find key 'odoo' in {str(manifest_file)}")
26
-
27
- odoo_url = odoo_data["url"]
28
- odoo_branch = odoo_data.get("branch", "master")
29
- odoo_commit = odoo_data.get("commit", "")
30
-
31
- download_stubs(target_folder, force_fetch, download_archive, odoo_data, odoo_branch)
32
-
33
- if add_compare_comment:
34
- yaml_add_compare_commit(odoo_data, odoo_branch)
35
- else:
36
- yaml_remove_compare_commit(odoo_data)
37
-
38
- git_ensure_repo(
39
- target_folder=target_folder,
40
- repo_src=odoo_url,
41
- branch=odoo_branch,
42
- commit=odoo_commit,
43
- pull=force_fetch,
44
- zip_mode=download_archive,
45
- filter="blob:none",
46
- single_branch=True,
47
- )
48
-
49
- yaml.dump(git_repos, manifest_file)
50
-
51
-
52
- def download_stubs(
53
- target_folder: Path,
54
- force_fetch: bool,
55
- download_archive: bool,
56
- odoo_data,
57
- odoo_branch: str,
58
- ):
59
- """Download Odoo stubs for https://github.com/odoo-ide/vscode-odoo
60
-
61
- Hopefully this Method will become obsolete in the future, when the vscode-odoo extension includes stubs in the extension itself.
62
-
63
- Parameters
64
- ----------
65
- target_folder : Path
66
- Stubs will be downloaded to target_folder.parent/odoo-stubs
67
- force_fetch : bool
68
- passed down to git_ensure_repo
69
- download_archive : bool
70
- passed down to git_ensure_repo
71
- odoo_data : Dict
72
- odoo_data from manifest.yml
73
- odoo_branch : str
74
- branch to download stubs from
75
- """
76
- odoo_stubs = odoo_data.get("stubs")
77
- if odoo_stubs:
78
- stub_target_path = target_folder.parent / "odoo-stubs"
79
- git_ensure_repo(
80
- target_folder=stub_target_path,
81
- repo_src=odoo_stubs["url"],
82
- branch=odoo_branch,
83
- pull=force_fetch,
84
- zip_mode=download_archive,
85
- filter="blob:none",
86
- single_branch=True,
87
- )
88
- if pyright_path := odoo_stubs.get("pyright_conf"):
89
- json.dump({"stubPath": str(stub_target_path.absolute())}, Path(pyright_path).open("w"))
@@ -1 +0,0 @@
1
- __version__ = "0.8.6"
File without changes
File without changes