odoo-dev 0.3.2__tar.gz → 0.4.0__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 (72) hide show
  1. odoo_dev-0.4.0/.github/workflows/release-please.yml +43 -0
  2. odoo_dev-0.4.0/.release-please-manifest.json +3 -0
  3. odoo_dev-0.4.0/CHANGELOG.md +8 -0
  4. odoo_dev-0.4.0/PKG-INFO +201 -0
  5. odoo_dev-0.4.0/README.md +187 -0
  6. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/pyproject.toml +1 -1
  7. odoo_dev-0.4.0/release-please-config.json +12 -0
  8. odoo_dev-0.4.0/src/odoo_dev/__init__.py +3 -0
  9. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/commands/run.py +38 -10
  10. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/commands/setup.py +22 -6
  11. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/config.py +50 -0
  12. odoo_dev-0.4.0/src/odoo_dev/preflight.py +158 -0
  13. odoo_dev-0.4.0/tests/test_db_config.py +49 -0
  14. odoo_dev-0.4.0/tests/test_preflight.py +132 -0
  15. odoo_dev-0.4.0/tests/test_setup_db.py +41 -0
  16. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/uv.lock +49 -1
  17. odoo_dev-0.3.2/.claude/settings.json +0 -8
  18. odoo_dev-0.3.2/.claude/settings.local.json +0 -13
  19. odoo_dev-0.3.2/PKG-INFO +0 -19
  20. odoo_dev-0.3.2/README.md +0 -5
  21. odoo_dev-0.3.2/src/odoo_dev/__init__.py +0 -3
  22. odoo_dev-0.3.2/tests/fixtures/odoo-empty/.git +0 -1
  23. odoo_dev-0.3.2/tests/fixtures/odoo-empty/.gitignore +0 -78
  24. odoo_dev-0.3.2/tests/fixtures/odoo-empty/.gitlab-ci.yml +0 -8
  25. odoo_dev-0.3.2/tests/fixtures/odoo-empty/.gitmodules +0 -0
  26. odoo_dev-0.3.2/tests/fixtures/odoo-empty/.repos/.gitkeep +0 -0
  27. odoo_dev-0.3.2/tests/fixtures/odoo-empty/Notes/Warning Upgrade all +0 -45
  28. odoo_dev-0.3.2/tests/fixtures/odoo-empty/README.md +0 -0
  29. odoo_dev-0.3.2/tests/fixtures/odoo-empty/addons/.gitkeep +0 -0
  30. odoo_dev-0.3.2/tests/fixtures/odoo-empty/note.txt +0 -331
  31. odoo_dev-0.3.2/tests/fixtures/odoo-empty/requirements.txt +0 -0
  32. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/abstorelsymlink.sh +0 -12
  33. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/adaptation.md +0 -99
  34. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/after_migration.sh +0 -13
  35. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/checkout2 +0 -17
  36. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/cleanup.sql +0 -60
  37. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/deploy +0 -108
  38. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/fix_mail_templates.sql +0 -18
  39. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/gitpull +0 -17
  40. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/main.py +0 -569
  41. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/modules_cleanup.sql +0 -58
  42. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/post-upgrade steps.md +0 -78
  43. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/pre_commit_hook.py +0 -81
  44. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/requirements.txt +0 -3
  45. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/test +0 -62
  46. odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/update_addon_versions.py +0 -24
  47. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/.gitignore +0 -0
  48. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/.gitmodules +0 -0
  49. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/.python-version +0 -0
  50. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/cli.py +0 -0
  51. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/commands/__init__.py +0 -0
  52. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/commands/db.py +0 -0
  53. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/commands/docker.py +0 -0
  54. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/__init__.py +0 -0
  55. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/docker/Dockerfile +0 -0
  56. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/docker/__init__.py +0 -0
  57. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/docker/docker-entrypoint.sh +0 -0
  58. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/vscode/__init__.py +0 -0
  59. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/vscode/launch.json +0 -0
  60. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/vscode/settings.json +0 -0
  61. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/vscode/tasks.json +0 -0
  62. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/utils/__init__.py +0 -0
  63. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/utils/console.py +0 -0
  64. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/__init__.py +0 -0
  65. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/fixtures/__init__.py +0 -0
  66. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/test_cli.py +0 -0
  67. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/test_config.py +0 -0
  68. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/test_db.py +0 -0
  69. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/test_drop_database.py +0 -0
  70. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/test_integration.py +0 -0
  71. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/test_run.py +0 -0
  72. {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/test_setup.py +0 -0
@@ -0,0 +1,43 @@
1
+ name: Release
2
+
3
+ on:
4
+ push:
5
+ branches: [master]
6
+
7
+ permissions:
8
+ contents: write
9
+ pull-requests: write
10
+
11
+ jobs:
12
+ release-please:
13
+ runs-on: ubuntu-latest
14
+ outputs:
15
+ release_created: ${{ steps.release.outputs.release_created }}
16
+ tag_name: ${{ steps.release.outputs.tag_name }}
17
+ steps:
18
+ # Maintains a release PR from Conventional Commits; when that PR is merged
19
+ # it creates the git tag + GitHub release and sets release_created=true.
20
+ - uses: googleapis/release-please-action@v4
21
+ id: release
22
+ with:
23
+ token: ${{ secrets.GITHUB_TOKEN }}
24
+ # release-please-config.json and .release-please-manifest.json are
25
+ # read from the repo root by default.
26
+
27
+ publish:
28
+ needs: release-please
29
+ if: ${{ needs.release-please.outputs.release_created == 'true' }}
30
+ runs-on: ubuntu-latest
31
+ permissions:
32
+ contents: read
33
+ id-token: write # OIDC: mint a short-lived token for PyPI Trusted Publishing
34
+ steps:
35
+ - uses: actions/checkout@v4
36
+ - name: Install uv
37
+ uses: astral-sh/setup-uv@v5
38
+ with:
39
+ python-version: "3.12"
40
+ - name: Build sdist + wheel
41
+ run: uv build
42
+ - name: Publish to PyPI (Trusted Publishing / OIDC)
43
+ run: uv publish --trusted-publishing always
@@ -0,0 +1,3 @@
1
+ {
2
+ ".": "0.4.0"
3
+ }
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## [0.4.0](https://github.com/bemade/odoo-dev/compare/v0.3.3...v0.4.0) (2026-06-11)
4
+
5
+
6
+ ### Features
7
+
8
+ * configurable DB connection + connectivity preflight ([#3](https://github.com/bemade/odoo-dev/issues/3)) ([632738e](https://github.com/bemade/odoo-dev/commit/632738e37c1d22d79ec4a03cba72a28ca580f7c8))
@@ -0,0 +1,201 @@
1
+ Metadata-Version: 2.4
2
+ Name: odoo-dev
3
+ Version: 0.4.0
4
+ Summary: Odoo Development Environment Helper
5
+ Project-URL: Homepage, https://git.bemade.org/bemade/odoo-dev
6
+ Project-URL: Repository, https://git.bemade.org/bemade/odoo-dev
7
+ Project-URL: Issues, https://git.bemade.org/bemade/odoo-dev/-/issues
8
+ License-Expression: LGPL-3.0
9
+ Requires-Python: >=3.12
10
+ Requires-Dist: pyyaml>=6.0
11
+ Requires-Dist: rich>=13.0.0
12
+ Requires-Dist: typer>=0.9.0
13
+ Description-Content-Type: text/markdown
14
+
15
+ # odoo-dev
16
+
17
+ A CLI tool for managing Odoo development environments. Handles local Python setup, Docker containers, database operations, and more.
18
+
19
+ It is the successor to the older `odoo-deploy` shell scripts — if you have notes for `odoo-deploy`, the rough mapping is: `odoo-dev docker start/stop/build` replaces the old `odoo-dev.sh start/stop/build`, and `odoo-dev run`/`test`/`shell` give you a local (venv-based) workflow that `odoo-deploy` didn't.
20
+
21
+ ## Installation
22
+
23
+ ```bash
24
+ # Install with uv (recommended) — installs the published package from PyPI
25
+ uv tool install odoo-dev
26
+
27
+ # Or with pip
28
+ pip install odoo-dev
29
+ ```
30
+
31
+ Then make sure the install location is on your `PATH` (uv prints the path; usually `~/.local/bin`):
32
+
33
+ ```bash
34
+ uv tool update-shell # or: export PATH="$HOME/.local/bin:$PATH"
35
+ ```
36
+
37
+ ## Quick Start
38
+
39
+ ```bash
40
+ # In your Odoo project directory
41
+ cd my-odoo-project
42
+
43
+ # Full setup: clone Odoo repos, create venv, install deps, configure VSCode
44
+ odoo-dev setup
45
+
46
+ # Or for community edition only
47
+ odoo-dev setup --community
48
+ ```
49
+
50
+ `setup` reads `ODOO_VERSION` / `PYTHON_VERSION` from a `.env` in the project root (or
51
+ prompts for them and offers to save). It then clones the Odoo repos, builds a `.venv`,
52
+ installs system dependencies, and generates `conf/odoo.conf`. It will offer to set up
53
+ Docker at the end — answer "no" if you only want the local venv workflow.
54
+
55
+ ## Database setup (read this before your first `run`/`test`)
56
+
57
+ The generated `conf/odoo.conf` connects as PostgreSQL user **`odoo`** over the local
58
+ socket. You need a running PostgreSQL server and a matching role. `setup` never creates
59
+ the role, and what it installs differs by OS — on **macOS** it installs the server (but
60
+ does **not** start it); on **Linux** it installs only the PostgreSQL *client* (so you
61
+ supply the server yourself). On a fresh machine do this once:
62
+
63
+ **macOS (Homebrew):**
64
+
65
+ ```bash
66
+ brew services start postgresql@18 # start the server (use your installed version)
67
+ createuser -s odoo # create the role odoo.conf expects
68
+ # Homebrew's versioned postgres is keg-only; add its bin to PATH if psql/createuser aren't found:
69
+ # export PATH="$(brew --prefix postgresql@18)/bin:$PATH"
70
+ ```
71
+
72
+ **Debian/Ubuntu:** install a server if you don't already have one (or point
73
+ `conf/odoo.conf` at an existing / remote / Docker PostgreSQL):
74
+
75
+ ```bash
76
+ sudo apt-get install postgresql # if you don't already have a server
77
+ sudo systemctl start postgresql
78
+ sudo -u postgres createuser -s odoo
79
+ ```
80
+
81
+ **Using a different / remote / Docker PostgreSQL:** set `DB_HOST`, `DB_PORT`,
82
+ `DB_USER`, `DB_PASSWORD` in `.env` before running `setup` (it writes them into
83
+ `conf/odoo.conf`), or edit `conf/odoo.conf` directly. With no `DB_HOST`, odoo-dev
84
+ connects over the local socket as the `odoo` role.
85
+
86
+ Before launching, `run`/`test`/`shell`/`update` run a quick connection preflight: if
87
+ the server is unreachable, the role is missing, or authentication fails, you get a
88
+ specific one-line fix instead of a stack trace.
89
+
90
+ ## Commands
91
+
92
+ ### Local Development (default)
93
+
94
+ ```bash
95
+ odoo-dev run # Start Odoo locally (default port 8069)
96
+ odoo-dev run -d mydb -p 8070 # Pick a database and HTTP port
97
+ odoo-dev run -d mydb -i base # Initialize module(s) on start
98
+ odoo-dev run -d mydb --dev reload # With hot reload
99
+ odoo-dev run --debug # With debugpy (VSCode attach on 5678)
100
+ odoo-dev shell mydb # Open an Odoo shell
101
+ odoo-dev update base -d mydb # Update modules
102
+ odoo-dev test my_module # Run a module's tests (coverage on by default)
103
+ odoo-dev test my_module --test-tags my_module --no-coverage
104
+ odoo-dev test # Auto-discover & test all addons in addons/
105
+ odoo-dev scaffold my_module # Create a new module
106
+ ```
107
+
108
+ > Note: the HTTP port flag is `-p` / `--port` (not `--http-port`).
109
+
110
+ ### Database Operations
111
+
112
+ ```bash
113
+ odoo-dev db list # List databases
114
+ odoo-dev db restore backup.zip # Restore from backup (neutralized by default)
115
+ odoo-dev db restore backup.zip mydb --no-neutralize
116
+ odoo-dev db drop mydb # Drop database
117
+ odoo-dev db neutralize mydb # Disable emails/crons
118
+ ```
119
+
120
+ ### Docker (optional)
121
+
122
+ ```bash
123
+ odoo-dev docker start # Start containers
124
+ odoo-dev docker stop # Stop containers
125
+ odoo-dev docker restart # Restart containers
126
+ odoo-dev docker logs # View logs
127
+ odoo-dev docker build # Rebuild image
128
+ odoo-dev docker shell mydb # Shell in container
129
+ odoo-dev docker psql # PostgreSQL shell
130
+ ```
131
+
132
+ ### Setup Commands
133
+
134
+ ```bash
135
+ odoo-dev setup # Full setup
136
+ odoo-dev setup --community # Community edition only
137
+ odoo-dev setup-venv # Just create the venv (no repo clone)
138
+ odoo-dev vscode # Configure VSCode debugging
139
+ ```
140
+
141
+ ## Project Structure
142
+
143
+ odoo-dev expects this project structure:
144
+
145
+ ```
146
+ my-odoo-project/
147
+ ├── .env # Optional: ODOO_VERSION, PYTHON_VERSION
148
+ ├── addons/ # Your custom addons
149
+ ├── requirements.txt # Project-specific Python deps
150
+ ├── odoo/ # Cloned by setup
151
+ ├── enterprise/ # Cloned by setup (unless --community)
152
+ ├── design-themes/ # Cloned by setup
153
+ ├── .venv/ # Created by setup
154
+ └── conf/
155
+ └── odoo.conf # Created by setup
156
+ ```
157
+
158
+ ## Configuration
159
+
160
+ Create a `.env` file in your project root:
161
+
162
+ ```bash
163
+ ODOO_VERSION=19.0
164
+ PYTHON_VERSION=3.12
165
+
166
+ # Optional — DB connection, written into conf/odoo.conf by `setup`.
167
+ # Omit DB_HOST/DB_PORT to use the local socket (the default). Set these to
168
+ # point at a remote / Docker / non-default PostgreSQL:
169
+ # DB_HOST=localhost
170
+ # DB_PORT=5432
171
+ # DB_USER=odoo
172
+ # DB_PASSWORD=odoo
173
+ ```
174
+
175
+ ## Requirements
176
+
177
+ - Python 3.12+
178
+ - uv (recommended) or pip
179
+ - Git
180
+ - PostgreSQL (for local development — server + an `odoo` role; see "Database setup")
181
+ - Docker (optional, for containerized development)
182
+
183
+ ## Development
184
+
185
+ ```bash
186
+ # Clone and install for development
187
+ git clone git@github.com:bemade/odoo-dev.git
188
+ cd odoo-dev
189
+ uv sync
190
+
191
+ # Run tests
192
+ uv run pytest # All tests
193
+ uv run pytest -m "not slow" # Fast tests only
194
+
195
+ # Build
196
+ uv build
197
+ ```
198
+
199
+ ## License
200
+
201
+ LGPL-3. For complete license terms, visit https://www.gnu.org/licenses/lgpl-3.0.en.html
@@ -0,0 +1,187 @@
1
+ # odoo-dev
2
+
3
+ A CLI tool for managing Odoo development environments. Handles local Python setup, Docker containers, database operations, and more.
4
+
5
+ It is the successor to the older `odoo-deploy` shell scripts — if you have notes for `odoo-deploy`, the rough mapping is: `odoo-dev docker start/stop/build` replaces the old `odoo-dev.sh start/stop/build`, and `odoo-dev run`/`test`/`shell` give you a local (venv-based) workflow that `odoo-deploy` didn't.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ # Install with uv (recommended) — installs the published package from PyPI
11
+ uv tool install odoo-dev
12
+
13
+ # Or with pip
14
+ pip install odoo-dev
15
+ ```
16
+
17
+ Then make sure the install location is on your `PATH` (uv prints the path; usually `~/.local/bin`):
18
+
19
+ ```bash
20
+ uv tool update-shell # or: export PATH="$HOME/.local/bin:$PATH"
21
+ ```
22
+
23
+ ## Quick Start
24
+
25
+ ```bash
26
+ # In your Odoo project directory
27
+ cd my-odoo-project
28
+
29
+ # Full setup: clone Odoo repos, create venv, install deps, configure VSCode
30
+ odoo-dev setup
31
+
32
+ # Or for community edition only
33
+ odoo-dev setup --community
34
+ ```
35
+
36
+ `setup` reads `ODOO_VERSION` / `PYTHON_VERSION` from a `.env` in the project root (or
37
+ prompts for them and offers to save). It then clones the Odoo repos, builds a `.venv`,
38
+ installs system dependencies, and generates `conf/odoo.conf`. It will offer to set up
39
+ Docker at the end — answer "no" if you only want the local venv workflow.
40
+
41
+ ## Database setup (read this before your first `run`/`test`)
42
+
43
+ The generated `conf/odoo.conf` connects as PostgreSQL user **`odoo`** over the local
44
+ socket. You need a running PostgreSQL server and a matching role. `setup` never creates
45
+ the role, and what it installs differs by OS — on **macOS** it installs the server (but
46
+ does **not** start it); on **Linux** it installs only the PostgreSQL *client* (so you
47
+ supply the server yourself). On a fresh machine do this once:
48
+
49
+ **macOS (Homebrew):**
50
+
51
+ ```bash
52
+ brew services start postgresql@18 # start the server (use your installed version)
53
+ createuser -s odoo # create the role odoo.conf expects
54
+ # Homebrew's versioned postgres is keg-only; add its bin to PATH if psql/createuser aren't found:
55
+ # export PATH="$(brew --prefix postgresql@18)/bin:$PATH"
56
+ ```
57
+
58
+ **Debian/Ubuntu:** install a server if you don't already have one (or point
59
+ `conf/odoo.conf` at an existing / remote / Docker PostgreSQL):
60
+
61
+ ```bash
62
+ sudo apt-get install postgresql # if you don't already have a server
63
+ sudo systemctl start postgresql
64
+ sudo -u postgres createuser -s odoo
65
+ ```
66
+
67
+ **Using a different / remote / Docker PostgreSQL:** set `DB_HOST`, `DB_PORT`,
68
+ `DB_USER`, `DB_PASSWORD` in `.env` before running `setup` (it writes them into
69
+ `conf/odoo.conf`), or edit `conf/odoo.conf` directly. With no `DB_HOST`, odoo-dev
70
+ connects over the local socket as the `odoo` role.
71
+
72
+ Before launching, `run`/`test`/`shell`/`update` run a quick connection preflight: if
73
+ the server is unreachable, the role is missing, or authentication fails, you get a
74
+ specific one-line fix instead of a stack trace.
75
+
76
+ ## Commands
77
+
78
+ ### Local Development (default)
79
+
80
+ ```bash
81
+ odoo-dev run # Start Odoo locally (default port 8069)
82
+ odoo-dev run -d mydb -p 8070 # Pick a database and HTTP port
83
+ odoo-dev run -d mydb -i base # Initialize module(s) on start
84
+ odoo-dev run -d mydb --dev reload # With hot reload
85
+ odoo-dev run --debug # With debugpy (VSCode attach on 5678)
86
+ odoo-dev shell mydb # Open an Odoo shell
87
+ odoo-dev update base -d mydb # Update modules
88
+ odoo-dev test my_module # Run a module's tests (coverage on by default)
89
+ odoo-dev test my_module --test-tags my_module --no-coverage
90
+ odoo-dev test # Auto-discover & test all addons in addons/
91
+ odoo-dev scaffold my_module # Create a new module
92
+ ```
93
+
94
+ > Note: the HTTP port flag is `-p` / `--port` (not `--http-port`).
95
+
96
+ ### Database Operations
97
+
98
+ ```bash
99
+ odoo-dev db list # List databases
100
+ odoo-dev db restore backup.zip # Restore from backup (neutralized by default)
101
+ odoo-dev db restore backup.zip mydb --no-neutralize
102
+ odoo-dev db drop mydb # Drop database
103
+ odoo-dev db neutralize mydb # Disable emails/crons
104
+ ```
105
+
106
+ ### Docker (optional)
107
+
108
+ ```bash
109
+ odoo-dev docker start # Start containers
110
+ odoo-dev docker stop # Stop containers
111
+ odoo-dev docker restart # Restart containers
112
+ odoo-dev docker logs # View logs
113
+ odoo-dev docker build # Rebuild image
114
+ odoo-dev docker shell mydb # Shell in container
115
+ odoo-dev docker psql # PostgreSQL shell
116
+ ```
117
+
118
+ ### Setup Commands
119
+
120
+ ```bash
121
+ odoo-dev setup # Full setup
122
+ odoo-dev setup --community # Community edition only
123
+ odoo-dev setup-venv # Just create the venv (no repo clone)
124
+ odoo-dev vscode # Configure VSCode debugging
125
+ ```
126
+
127
+ ## Project Structure
128
+
129
+ odoo-dev expects this project structure:
130
+
131
+ ```
132
+ my-odoo-project/
133
+ ├── .env # Optional: ODOO_VERSION, PYTHON_VERSION
134
+ ├── addons/ # Your custom addons
135
+ ├── requirements.txt # Project-specific Python deps
136
+ ├── odoo/ # Cloned by setup
137
+ ├── enterprise/ # Cloned by setup (unless --community)
138
+ ├── design-themes/ # Cloned by setup
139
+ ├── .venv/ # Created by setup
140
+ └── conf/
141
+ └── odoo.conf # Created by setup
142
+ ```
143
+
144
+ ## Configuration
145
+
146
+ Create a `.env` file in your project root:
147
+
148
+ ```bash
149
+ ODOO_VERSION=19.0
150
+ PYTHON_VERSION=3.12
151
+
152
+ # Optional — DB connection, written into conf/odoo.conf by `setup`.
153
+ # Omit DB_HOST/DB_PORT to use the local socket (the default). Set these to
154
+ # point at a remote / Docker / non-default PostgreSQL:
155
+ # DB_HOST=localhost
156
+ # DB_PORT=5432
157
+ # DB_USER=odoo
158
+ # DB_PASSWORD=odoo
159
+ ```
160
+
161
+ ## Requirements
162
+
163
+ - Python 3.12+
164
+ - uv (recommended) or pip
165
+ - Git
166
+ - PostgreSQL (for local development — server + an `odoo` role; see "Database setup")
167
+ - Docker (optional, for containerized development)
168
+
169
+ ## Development
170
+
171
+ ```bash
172
+ # Clone and install for development
173
+ git clone git@github.com:bemade/odoo-dev.git
174
+ cd odoo-dev
175
+ uv sync
176
+
177
+ # Run tests
178
+ uv run pytest # All tests
179
+ uv run pytest -m "not slow" # Fast tests only
180
+
181
+ # Build
182
+ uv build
183
+ ```
184
+
185
+ ## License
186
+
187
+ LGPL-3. For complete license terms, visit https://www.gnu.org/licenses/lgpl-3.0.en.html
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "odoo-dev"
3
- version = "0.3.2"
3
+ version = "0.4.0"
4
4
  description = "Odoo Development Environment Helper"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -0,0 +1,12 @@
1
+ {
2
+ "$schema": "https://raw.githubusercontent.com/googleapis/release-please/main/schemas/config.json",
3
+ "packages": {
4
+ ".": {
5
+ "release-type": "python",
6
+ "package-name": "odoo-dev",
7
+ "changelog-path": "CHANGELOG.md",
8
+ "include-component-in-tag": false,
9
+ "extra-files": ["src/odoo_dev/__init__.py"]
10
+ }
11
+ }
12
+ }
@@ -0,0 +1,3 @@
1
+ """Odoo Development Environment Helper."""
2
+
3
+ __version__ = "0.4.0" # x-release-please-version
@@ -10,6 +10,7 @@ from typing import Annotated
10
10
  import typer
11
11
 
12
12
  from odoo_dev.config import load_config
13
+ from odoo_dev.preflight import require_db
13
14
  from odoo_dev.utils.console import error, info, success, warning
14
15
 
15
16
 
@@ -53,6 +54,8 @@ def run(
53
54
  error("Run 'odoo-dev setup' first to clone Odoo repositories.")
54
55
  raise typer.Exit(1)
55
56
 
57
+ require_db(cfg)
58
+
56
59
  venv_python = cfg.venv_path / "bin" / "python"
57
60
 
58
61
  # Build command
@@ -114,6 +117,8 @@ def shell(
114
117
  error("Run 'odoo-dev setup' first.")
115
118
  raise typer.Exit(1)
116
119
 
120
+ require_db(cfg)
121
+
117
122
  venv_python = cfg.venv_path / "bin" / "python"
118
123
 
119
124
  success(f"Opening Odoo shell with database {db_name}...")
@@ -148,6 +153,8 @@ def update(
148
153
  error("Run 'odoo-dev setup' first.")
149
154
  raise typer.Exit(1)
150
155
 
156
+ require_db(cfg)
157
+
151
158
  venv_python = cfg.venv_path / "bin" / "python"
152
159
 
153
160
  success(f"Updating modules: {modules} on database {db_name}...")
@@ -192,7 +199,8 @@ def test(
192
199
  bool, typer.Option("--coverage/--no-coverage", help="Enable coverage reporting")
193
200
  ] = True,
194
201
  keep_db: Annotated[
195
- bool, typer.Option("--keep-db/--no-keep-db", help="Keep test database after tests")
202
+ bool,
203
+ typer.Option("--keep-db/--no-keep-db", help="Keep test database after tests"),
196
204
  ] = False,
197
205
  exclude: Annotated[
198
206
  str | None,
@@ -254,6 +262,8 @@ def test(
254
262
  if db_name is None:
255
263
  db_name = f"test_{int(time.time())}"
256
264
 
265
+ require_db(cfg)
266
+
257
267
  venv_python = cfg.venv_path / "bin" / "python"
258
268
 
259
269
  # Determine modules to test
@@ -291,7 +301,15 @@ def test(
291
301
  if not clone_dir.exists():
292
302
  branch = os.environ.get("ODOO_VERSION", cfg.odoo_version)
293
303
  result = subprocess.run(
294
- ["git", "clone", "--depth=1", "-b", branch, repo_url, str(clone_dir)],
304
+ [
305
+ "git",
306
+ "clone",
307
+ "--depth=1",
308
+ "-b",
309
+ branch,
310
+ repo_url,
311
+ str(clone_dir),
312
+ ],
295
313
  capture_output=True,
296
314
  )
297
315
  if result.returncode != 0:
@@ -370,7 +388,9 @@ def test(
370
388
 
371
389
  if coverage:
372
390
  # Build coverage source paths
373
- coverage_source = ",".join(str(cfg.addons_dir / m) for m in modules.split(","))
391
+ coverage_source = ",".join(
392
+ str(cfg.addons_dir / m) for m in modules.split(",")
393
+ )
374
394
 
375
395
  test_cmd = [
376
396
  str(venv_python),
@@ -512,9 +532,12 @@ def _drop_database(cfg, db_name: str) -> None:
512
532
  result = subprocess.run(
513
533
  [
514
534
  "dropdb",
515
- "-h", db_config["host"],
516
- "-p", db_config["port"],
517
- "-U", db_config["user"],
535
+ "-h",
536
+ db_config["host"],
537
+ "-p",
538
+ db_config["port"],
539
+ "-U",
540
+ db_config["user"],
518
541
  "--if-exists",
519
542
  db_name,
520
543
  ],
@@ -534,10 +557,14 @@ def _terminate_connections(db_name: str, db_config: dict[str, str]) -> None:
534
557
  subprocess.run(
535
558
  [
536
559
  "psql",
537
- "-h", db_config["host"],
538
- "-p", db_config["port"],
539
- "-U", db_config["user"],
540
- "-d", "postgres",
560
+ "-h",
561
+ db_config["host"],
562
+ "-p",
563
+ db_config["port"],
564
+ "-U",
565
+ db_config["user"],
566
+ "-d",
567
+ "postgres",
541
568
  "-c",
542
569
  f"SELECT pg_terminate_backend(pid) FROM pg_stat_activity "
543
570
  f"WHERE datname = '{db_name}' AND pid <> pg_backend_pid()",
@@ -547,6 +574,7 @@ def _terminate_connections(db_name: str, db_config: dict[str, str]) -> None:
547
574
  env=env,
548
575
  )
549
576
 
577
+
550
578
  def _get_addons_path(config_file) -> str:
551
579
  """Extract addons_path from odoo.conf."""
552
580
  for line in config_file.read_text().splitlines():
@@ -309,12 +309,28 @@ def _setup_odoo_config(cfg, community_only: bool = False) -> None:
309
309
  # Filter to only existing paths
310
310
  addons_paths = [p for p in addons_paths if Path(p).exists()]
311
311
 
312
- config_content = f"""[options]
313
- addons_path = {",".join(addons_paths)}
314
- admin_passwd = admin
315
- db_user = odoo
316
- db_password = odoo
317
- """
312
+ # DB connection is configurable via .env (loaded into the environment by
313
+ # load_config). Host/port are written only when set, so the default is the
314
+ # local socket — matching odoo-bin's behavior when db_host is absent.
315
+ db_user = os.getenv("DB_USER", "odoo")
316
+ db_password = os.getenv("DB_PASSWORD", "odoo")
317
+ db_host = os.getenv("DB_HOST", "")
318
+ db_port = os.getenv("DB_PORT", "")
319
+
320
+ db_lines = []
321
+ if db_host:
322
+ db_lines.append(f"db_host = {db_host}")
323
+ if db_port:
324
+ db_lines.append(f"db_port = {db_port}")
325
+ db_lines.append(f"db_user = {db_user}")
326
+ db_lines.append(f"db_password = {db_password}")
327
+
328
+ config_content = (
329
+ "[options]\n"
330
+ f"addons_path = {','.join(addons_paths)}\n"
331
+ "admin_passwd = admin\n"
332
+ f"{chr(10).join(db_lines)}\n"
333
+ )
318
334
 
319
335
  conf_file.write_text(config_content)
320
336
  conf_file.chmod(0o600)
@@ -9,6 +9,56 @@ DEFAULT_ODOO_VERSION = "19.0"
9
9
  DEFAULT_PYTHON_VERSION = "3.12"
10
10
 
11
11
 
12
+ @dataclass
13
+ class DbConfig:
14
+ """PostgreSQL connection settings, as odoo-bin will use them.
15
+
16
+ An empty ``host``/``port`` means "use the libpq defaults" (i.e. the local
17
+ Unix socket), which is exactly what odoo-bin does when ``db_host`` is absent
18
+ from odoo.conf. The preflight check must mirror that, so we keep them empty
19
+ rather than substituting ``localhost``/``5432`` (which would force TCP and
20
+ can spuriously fail on socket/peer-auth setups).
21
+ """
22
+
23
+ host: str = ""
24
+ port: str = ""
25
+ user: str = "odoo"
26
+ password: str = ""
27
+ name: str | None = None
28
+
29
+
30
+ def read_db_config(config_file: Path) -> "DbConfig":
31
+ """Read DB connection settings from an odoo.conf file.
32
+
33
+ Args:
34
+ config_file: Path to odoo.conf. A missing file yields defaults.
35
+
36
+ Returns:
37
+ DbConfig reflecting the connection odoo-bin would make.
38
+ """
39
+ db = DbConfig()
40
+ if not config_file.exists():
41
+ return db
42
+
43
+ for line in config_file.read_text().splitlines():
44
+ line = line.strip()
45
+ if "=" not in line or line.startswith("#"):
46
+ continue
47
+ key, _, value = line.partition("=")
48
+ key, value = key.strip(), value.strip()
49
+ if key == "db_host":
50
+ db.host = value
51
+ elif key == "db_port":
52
+ db.port = value
53
+ elif key == "db_user":
54
+ db.user = value
55
+ elif key == "db_password":
56
+ db.password = value
57
+ elif key == "db_name":
58
+ db.name = value
59
+ return db
60
+
61
+
12
62
  @dataclass
13
63
  class ProjectConfig:
14
64
  """Configuration for an Odoo development project."""