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.
- odoo_dev-0.4.0/.github/workflows/release-please.yml +43 -0
- odoo_dev-0.4.0/.release-please-manifest.json +3 -0
- odoo_dev-0.4.0/CHANGELOG.md +8 -0
- odoo_dev-0.4.0/PKG-INFO +201 -0
- odoo_dev-0.4.0/README.md +187 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/pyproject.toml +1 -1
- odoo_dev-0.4.0/release-please-config.json +12 -0
- odoo_dev-0.4.0/src/odoo_dev/__init__.py +3 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/commands/run.py +38 -10
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/commands/setup.py +22 -6
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/config.py +50 -0
- odoo_dev-0.4.0/src/odoo_dev/preflight.py +158 -0
- odoo_dev-0.4.0/tests/test_db_config.py +49 -0
- odoo_dev-0.4.0/tests/test_preflight.py +132 -0
- odoo_dev-0.4.0/tests/test_setup_db.py +41 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/uv.lock +49 -1
- odoo_dev-0.3.2/.claude/settings.json +0 -8
- odoo_dev-0.3.2/.claude/settings.local.json +0 -13
- odoo_dev-0.3.2/PKG-INFO +0 -19
- odoo_dev-0.3.2/README.md +0 -5
- odoo_dev-0.3.2/src/odoo_dev/__init__.py +0 -3
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/.git +0 -1
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/.gitignore +0 -78
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/.gitlab-ci.yml +0 -8
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/.gitmodules +0 -0
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/.repos/.gitkeep +0 -0
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/Notes/Warning Upgrade all +0 -45
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/README.md +0 -0
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/addons/.gitkeep +0 -0
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/note.txt +0 -331
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/requirements.txt +0 -0
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/abstorelsymlink.sh +0 -12
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/adaptation.md +0 -99
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/after_migration.sh +0 -13
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/checkout2 +0 -17
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/cleanup.sql +0 -60
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/deploy +0 -108
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/fix_mail_templates.sql +0 -18
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/gitpull +0 -17
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/main.py +0 -569
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/modules_cleanup.sql +0 -58
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/post-upgrade steps.md +0 -78
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/pre_commit_hook.py +0 -81
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/requirements.txt +0 -3
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/test +0 -62
- odoo_dev-0.3.2/tests/fixtures/odoo-empty/tools/update_addon_versions.py +0 -24
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/.gitignore +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/.gitmodules +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/.python-version +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/cli.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/commands/__init__.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/commands/db.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/commands/docker.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/__init__.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/docker/Dockerfile +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/docker/__init__.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/docker/docker-entrypoint.sh +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/vscode/__init__.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/vscode/launch.json +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/vscode/settings.json +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/templates/vscode/tasks.json +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/utils/__init__.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/src/odoo_dev/utils/console.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/__init__.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/fixtures/__init__.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/test_cli.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/test_config.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/test_db.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/test_drop_database.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/test_integration.py +0 -0
- {odoo_dev-0.3.2 → odoo_dev-0.4.0}/tests/test_run.py +0 -0
- {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,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))
|
odoo_dev-0.4.0/PKG-INFO
ADDED
|
@@ -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
|
odoo_dev-0.4.0/README.md
ADDED
|
@@ -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
|
|
@@ -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
|
+
}
|
|
@@ -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,
|
|
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
|
-
[
|
|
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(
|
|
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",
|
|
516
|
-
|
|
517
|
-
"-
|
|
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",
|
|
538
|
-
|
|
539
|
-
"-
|
|
540
|
-
"
|
|
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
|
-
|
|
313
|
-
|
|
314
|
-
|
|
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."""
|